vue2_列表渲染、数据监视原理
1列表渲染
1.1、基本列表
v-for指令
-
用于展示列表数据
-
语法:
,这里 key 可以是 index ,更好是遍历的对象的唯一标识。
-
可遍历:数组、对象、字符串(用的少)、指定次数(用的少)
初始vue
人员列表
-
{{p.name}} _ {{p.age}}
车配置列表
-
{{k}} : {{val}}
结果:
1.2、v-for的key的原理
index作为key
初始vue
人员列表
-
{{p.name}} _ {{p.age}}
点击添加前:
点击添加后:
为啥会这样:
因为用index作为key:
如果对数据的顺序进行了破坏的操作。就会有下面的问题,而且出现这样问题效率会很低,因为复用的东西变少了。
原因步骤①、如下图:点击添加后,在进行diff比较时候,发现第一个input文本框没有变化,在虚拟dom里面的key为0的节点里还是一个input元素没有变成其它元素,就可以复用,所以就不会重新生成新的元素进行替换。
②如下:后面的key的input都复用了真实dom上的,没有重新在虚拟dom上生成新的。
③王五重新生成是因为旧的虚拟dom里没有key=3的元素
p.id作为键:
如图,修改key
原理:
总结key的内部原理
面试题:react vue中的key有什么作用? ( key的内部原理)
1 .虚拟DOM
中key
的作用:key
是虚拟DOM
中对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM ,随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较,对比规则如下
2 .对比规则
a.旧虚拟DOM中找到了与新虚拟DOM相同的key
- ①.若虚拟DOM中内容没变,直接使用之前的真实DOM节点。
- ②若虚拟DOM中内容变了,则生成新的真实DOM节点 ,随后替换掉页面中之前的真实DOM中对应的有变化的节点元素。(不是替换掉整个dom文档,而是替换掉里面修改的节点元素)
b. 旧虚拟DOM中未找到与新虚拟DOM相同的key
- 创建新的真实DOM ,随后渲染到到页面
3 .用index作为key可能会引发的问题
a.若对数据进行逆序添加、逆序删除等破坏顺序操作,会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低。
b.若结构中还包含输入类的DOM(如:输入框) :会产生错误DOM更新 ==> 界面有问题。
4 .开发中如何选择key ?
a.最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
b,如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表,使用index作为key是没有问题的。
1.3、列表过滤
初始vue
人员列表
-
{{p.name}} - {{p.age}} - {{p.sex}}
结果:
1.4、列表排序
初始vue
人员列表
-
{{p.name}} - {{p.age}} - {{p.sex}}
1.5、Vue数据监视
更新时的问题
初始vue
人员列表
-
{{p.name}} - {{p.age}} - {{p.sex}}
如下图:更新时候页面上并没有更新:
解决方法:
更改如下代码即可,因为vue对能修改数组本身的方法才进行数据监视,
简单模拟vue中的监测对象变化的原理
Vue.set();和vm.$set()
非响应式添加属性
Vue.set():响应式添加属性
添加的属性就和vue生成虚拟dom时候加工data里的数据一样,都有get和set监听。
vm.$set()
方法和Vue.set()
方法一致,只不过一个是构造函数身上的,一个是实例身上的。
vm.$set(vm.student,"sex","女");
Vue监视数据的原理:
-
vue会监视data中所有层次的数据。
-
如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1).对象中后追加的属性,Vue默认不做响应式处理
(2).如需给后添加的属性做响应式,请使用如下API:
Vue.set(target,propertyName/index,value)
或
vm.$set(target,propertyName/index,value)
-
如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1).调用原生对应的方法对数组进行更新。
(2).重新解析模板,进而更新页面。 -
在Vue修改数组中的某个元素一定要用如下方法:
1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
2.Vue.set() 或 vm.$set()
特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象(data)添加属性!!!
Document
学生信息
姓名:{{student.name}}
年龄:{{student.age}}
性别:{{student.sex}}
爱好:
-
{{val}}
朋友们:
-
{{v.name +":"+v.age}}
数据劫持
就是将data里的数据转为vm里_data的格式,为每个属性添加getter和setter的操作就叫数据劫持。劫持就是修改属性被set发现,让后set执行操作。