v-model 双向数据绑定实现原理

我们来手动实现一个 v-model 的功能。

v-model 双向数据绑定实现原理

准备工作

首先定义了一个component组件,里面有一个template。

  const CompOne = {
  props: ['value'],
  template: `
    <div>
      <input type="text"></input>
    </div>
  `,
}

然后再定义一个vue对象,里面引用了该组件。

new Vue({
  components: {
    CompOne,
  },
  template: `
    <div>
      <comp-one></comp-one>
    </div> 
  `,
}).$mount(root)

好了,准备工作完成。

实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EVhPoogo-1622480616354)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0cc2c223924940259fa124c63a96c3e4~tplv-k3u1fbpfcp-watermark.image)]

const CompOne = {
  props: ['value'], // 接收父组件传递的数据
  template: `
    <div>
      <input type="text" @input="handleInput" :value="value"></input> 
      // 添加一个input事件
      // 接收父组件传递的value
    </div>
  `,
  methods: {
    handleInput (e) {
      this.$emit('input', e.target.value) // 通过$emit,当 value 变化时通知父组件
    }
  }
}

2.gif

new Vue({
  components: {
    CompOne,
  },
  data () {
    return {
      value: 'vue' 
    }
  },
  template: `
    <div>
    // value 为传递给子组件的数据
    // @input 接收子组件通过 $emit 传递的参数
      <comp-one :value="value" @input="value = arguments[0]"></comp-one> 
    </div> 
  `,
}).$mount(root)

效果

3.gif

大功告成,我们实现了 v-model 的功能!

拓展

默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event。

但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用
来避免这样的冲突。

new Vue({
 components: {
   CompOne,
 },
 data () {
   return {
     value: 'vue'
   }
 },
 template: `
   <div>
     <comp-one v-model="value"></comp-one> // 使用v-model 满足语法糖规则:属性必须为value,方法名必须为:input
   </div> 
 `,
}).$mount(root)
// 修改子组件 
const CompOne = {
  props: ['value1'],
  model: {
      prop: "value1", // 接收的数据 value => value1
      event: "change" // $emit 需要绑定的事件 input => change
  },
  template: `
    <div>
      <input type="text" @input="handleInput" :value="value1"></input>
    </div>
  `,
  methods: {
    handleInput (e) {
      this.$emit('change', e.target.value)
    }
  }
}

这样就可以让 v-model 变得更灵活,属性和方法名可以自定义。

总结

v-model 时一个语法糖,它做了:

  1. 绑定数据value

  2. 触发输入事件input

  3. data 更新触发重新渲染

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值