Vue——v-model双向绑定数据原理及用法

vue中双向绑定是一个指令v-model,所谓的双绑就是可以绑定一个响应式数据到视图,同时视图中变化能改变该值。

v-model是语法糖,默认情况下相当于:value@input。使用v-model可以减少大量繁琐的事件处理代码,提高开发效率

通常在表单项上使用v-model,还可以在自定义组件上使用,表示某个值的输入和输出控制。

比如说我们在input上使用时,我们将xxx的值绑定到表单元素value上<input v-model = "xxx">;如果这个input的类型是checkbox,可以使用true-valuefalse-value指定特殊的值。对于selest可以通过option元素的value设置元素特殊的值;我们甚至可以结合.lazy,.number,.trim对v-model的行为做进一步限定,这样做出来的东西可以帮我们进行一些业务处理(.number->得到处理后的数字,.trim->处理后去掉空格)。

v-model用在自定义组件上时又会有很大的不同,vue3中它类似于async修饰符,最终展开的结果是modelValue属性的绑定和update:modelValue事件;vue3中我们甚至可以用参数形式指定多个不同的绑定,例如:v-model:foo和v-model:bar,非常强大!

双向绑定的原理其实就是分为两步:模板编译数据劫持

模板编译:分析模板tempalte,元素节点的属性如果存在v-htmlv-model{{ }}等属性,需要找到对应的数据,并进行渲染。

数据劫持:当数据data发生改变的时候,重新编译模板。(利用的是Object.defineProperty监听数据变化,watch方法对每个元素进行监听,发布订阅者模式订阅watch对象,发布watch对象中update方法)

模板编译之内存操作元素

模板编译将所有的dom操作都转移到内存中去执行(先创建一个内存对象,然后将所有的dom节点转移到内存对象中),操作完dom元素后再把dom结点转移到根节点上

这个转移其实是为了节约内存空间,因为每颗dom树就相当于一颗真实的树,每个dom节点就相当于树的一个片段,当某个片段发生改变的时候,它下面的所有片段都需要重排,是非常耗性能的。

模板编译之遍历节点

模板编译我们还需要去遍历它的所有节点,监听每个节点的类型(元素节点/文本节点),如果是元素节点的话,一定会存在子节点,这个时候就需要利用递归去做遍历。

  • 模板编译之处理元素节点
    如果是元素节点的话,我们需要去进行一个元素的赋值、渲染。
    1. 元素节点需要监听所有的属性名,是否存在双向数据绑定的标志
    2. 如果存在双向绑定标志,直接获取属性值进行赋值
  • 模板编译之处理文本节点
    利用正则获取{{ }}里面的内容,获取的文本节点内容直接赋值给文本节点

数据劫持之监听数据变化

监听数据变化,Object.defineProperty只能监听属性的变化,所以这里需要对对象进行遍历,而监听的每一个属性值可能是对象,所以这里还需要进行递归。
监听有两种方法:get和set

当用户获取数据的时候调用get方法,当用户设置数据的时候调用set方法

  • 数据劫持之订阅发布

    定义发布订阅者模式,当获取数据的时候,表明元素正在进行赋值操作,这时需要订阅watch对象,当改变数据的时候,表明赋值完成,这时,需要发布watch对象上的updata方法,对监听到的元素进行赋值操作。
  • 数据劫持之监听元素更新

    定义watch构造函数,构造函数主要是获取老值,获取老值时会触发监听的get方法,把每个元素订阅起来。准备更新方法时。当数据重新赋值,发布消息触发订阅的updata方法。

版权声明:本文为weixin_45771601原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。