手把手教你造一个自己的v-model:原来双向绑定这么简单!

大家好,我是小杨,一个写了6年前端的老码农。今天想带大家揭开Vue里v-model的神秘面纱,我们自己动手实现一个简易版!

记得刚学Vue时,我觉得v-model简直是黑魔法------输入框的值怎么就自动同步到数据了呢?直到有一天我看了源码,才发现...

1. v-model的本质是什么?

一句话:语法糖!

它其实就是value属性 + @input事件的快捷写法。比如:

html 复制代码
<input v-model="message">

等价于:

html 复制代码
<input 
  :value="message"
  @input="message = $event.target.value"
>

2. 自己实现一个简易v-model

让我们造个轮子叫my-model

html 复制代码
<template>
  <input 
    :value="value"
    @input="$emit('input', $event.target.value)"
  >
</template>

<script>
export default {
  props: ['value']
}
</script>

使用时:

html 复制代码
<my-model v-model="message"></my-model>

效果: 和官方v-model一模一样!不信你试试。

3. 我踩过的坑

有次我自作聪明加了额外功能:

javascript 复制代码
@input="handleInput($event.target.value)"

然后在methods里:

javascript 复制代码
handleInput(val) {
  this.$emit('input', val + '后缀') // 自动加后缀
}

结果用户每输入一个字符就追加后缀,直接炸了😂。所以直接emit原始值最安全!

4. 进阶玩法:自定义组件的v-model

Vue 2.x默认使用value属性和input事件,但我们可以改!

javascript 复制代码
model: {
  prop: '我喜欢的名字',  // 改用其他属性名
  event: 'change'      // 改用其他事件名
}

这样就能:

html 复制代码
<custom-input 
  v-model="message"
  我喜欢的名字="初始值"
  @change="处理函数"
></custom-input>

5. Vue 3的小变化

Vue 3中更灵活了:

  • 默认属性名改为modelValue
  • 默认事件名改为update:modelValue
  • 支持多个v-model绑定
html 复制代码
<MyComponent v-model:title="title" v-model:content="content" />

6. 活学活用案例

我做过一个颜色选择器组件:

html 复制代码
<color-picker v-model="themeColor" />

内部实现:

javascript 复制代码
// 当用户选颜色时
this.$emit('input', newColor)

这样父组件完全不用写监听逻辑,干净又卫生!

7. 为什么理解这个很重要?

  1. 面试常考题(我当面试官必问)
  2. 自定义表单组件必备技能
  3. 避免滥用v-model(有些场景应该用.sync)

最后送大家一句话:

"理解v-model,就是理解Vue双向绑定的第一课" ------ 这是当年我的导师说的,现在送给你们。

⭐ 写在最后

请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.

✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅ 认为我部分代码过于老旧,可以提供新的API或最新语法

✅ 对于文章中部分内容不理解

✅ 解答我文章中一些疑问

✅ 认为某些交互,功能需要优化,发现BUG

✅ 想要添加新功能,对于整体的设计,外观有更好的建议

✅ 一起探讨技术加qq交流群:906392632

最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!

相关推荐
莫的感情10 小时前
下载按钮点击一次却下载两个文件问题
前端
一个很帅的帅哥10 小时前
JavaScript事件循环
开发语言·前端·javascript
小宁爱Python10 小时前
Django Web 开发系列(二):视图进阶、快捷函数与请求响应处理
前端·django·sqlite
fox_10 小时前
深入理解React中的不可变性:原理、价值与实践
前端·react.js
武天10 小时前
Vue项目中有封装过axios吗?怎么封装的?
vue.js
Github项目推荐10 小时前
你的错误处理一团糟-是时候修复它了-🛠️
前端·后端
Code小翊10 小时前
C语言bsearch的使用
java·c语言·前端
云枫晖11 小时前
Webapck系列-初识Webpack
前端·javascript
慧一居士11 小时前
HTML5 功能介绍,使用场景,对应功能点完整使用示例
前端
海在掘金6112711 小时前
告别“undefined is not a function”:TS如何让你的函数调用更安心
前端