vue双向绑定原理以及v-model

vue2双向绑定原理

vue2中的双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图

 var obj = {};  //定义一个空对象
    Object.defineProperty(obj, 'val', {//定义要修改对象的属性
        get: function () {
            console.log('获取对象的值')
        },
        set: function (newVal) { 
            console.log('设置对象的值:最新的值是'+newVal);
        }
    });
    obj.hello = 'hello world'

vue3双向绑定原理

在vue3.0中,使用proxy这个功能更加强大的函数,它可以定义对象的基本操作的自定义行为。对比defineProperty只能拦截对象的某一属性,proxy的功能更方便。所提供的可自定义的操作也更多。

var obj = new Proxy({}, {
 get: function (target, propKey, receiver) {
  return Reflect.get(target, propKey, receiver);
 },
 set: function (target, propKey, value, receiver) {
  return Reflect.set(target, propKey, value, receiver);
 },
delete: function (target, propKey, receiver) {
  return Reflect.deleteProperty(target, prop, receiver);
 },
});

双向绑定原理总结

vue2.x版本使用了Object.defineProperty来实现双向绑定,由于其功能的限制,只能绑定对象的某个属性,vue需要递归遍历对象的所有属性挨个进行绑定,功能上不是很完美。

vue3.0版本使用proxy进行双向绑定,proxy提供了可以定义对象基本操作的自定义行为的功能(如属性查找、赋值、枚举、函数调用),可以直接拦截整个对象,不需要再进行递归。本例中我们只使用到了proxy提供自定义set和get的能力。


v-model

vue2 v-model

//默认v-model  
   Vue.component('base-checkbox', {
model: {
  prop: 'value',
  event: 'input'
},
props: {
    value: {type:String}
},
template: <input  :value="value" @input="$emit('input', $event.target.value)" >
})
 
//自定义v-model
Vue.component('base-checkbox', {
        model: {
          prop: 'checked',
          event: 'change'
        },
        props: {
          checked: {
            type:Boolean
          }
        },
        template: `
          <input
            type="checkbox"
            :checked="checked"
            @change="$emit('change', $event.target.checked)"
          >
        `
      })

.sync 修饰符

在有些情况下,我们可能需要对一个 prop 进行“双向绑定”。不幸的是,真正的双向绑定会带来维护上的问题,因为子组件可以变更父组件,且在父组件和子组件两侧都没有明显的变更来源。

      这也是为什么我们推荐以 update:myPropName 的模式触发事件取而代之。举个例子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值的意图:
      this.$emit('update:title', newTitle)
      然后父组件可以监听那个事件并根据需要更新一个本地的数据 property。例如:
      <text-document
        :title="doc.title"
        @update:title="doc.title = $event"
      ></text-document>
      为了方便起见,我们为这种模式提供一个缩写,即 .sync 修饰符:
      <text-document :title.sync="doc.title"></text-document>

vue3 v-model

变更:在自定义组件上使用v-model时, 属性以及事件的默认名称变了

变更:v-bind的.sync修饰符在 Vue 3 中又被去掉了, 合并到了v-model里

新增:同一组件可以同时设置多个 v-model

新增:开发者可以自定义 v-model修饰符

//如果要绑定属性名, 只需要给v-model传递一个参数就行, 同时可以绑定多个v-model:
//所以Vue 3 中抛弃了.sync写法, 统一使用v-model

<el-dialog v-model:visible="isVisible" v-model:content="content"></el-dialog>
<!-- 相当于 -->
<el-dialog
    :visible="isVisible"
    :content="content"
    @update:visible="isVisible"
    @update:content="content"
></el-dialog>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值