vue2_列表渲染、数据监视原理


1列表渲染

1.1、基本列表

v-for指令

  • 用于展示列表数据

  • 语法:

  • ,这里 key 可以是 index ,更好是遍历的对象的唯一标识。

  • 可遍历:数组、对象、字符串(用的少)、指定次数(用的少)




    
    
    
    初始vue
    
    



    

人员列表

  • {{p.name}} _ {{p.age}}

车配置列表

  • {{k}} : {{val}}

结果:
image


1.2、v-for的key的原理

index作为key




    
    
    
    初始vue
    
    



    

人员列表

  • {{p.name}} _ {{p.age}}

点击添加前:
image

点击添加后:
image

为啥会这样:
因为用index作为key:
如果对数据的顺序进行了破坏的操作。就会有下面的问题,而且出现这样问题效率会很低,因为复用的东西变少了。

原因步骤①、如下图:点击添加后,在进行diff比较时候,发现第一个input文本框没有变化,在虚拟dom里面的key为0的节点里还是一个input元素没有变成其它元素,就可以复用,所以就不会重新生成新的元素进行替换。

image

②如下:后面的key的input都复用了真实dom上的,没有重新在虚拟dom上生成新的。
image

③王五重新生成是因为旧的虚拟dom里没有key=3的元素
image

p.id作为键:

如图,修改key
image

原理:
image

总结key的内部原理

面试题:react vue中的key有什么作用? ( key的内部原理)

1 .虚拟DOMkey的作用: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}}

结果:
image



1.4、列表排序




    
    
    
    初始vue
    
    



    

人员列表

  • {{p.name}} - {{p.age}} - {{p.sex}}

image



1.5、Vue数据监视

更新时的问题




    
    
    
    初始vue
    
    



    

人员列表

  • {{p.name}} - {{p.age}} - {{p.sex}}

如下图:更新时候页面上并没有更新:
image

解决方法:
更改如下代码即可,因为vue对能修改数组本身的方法才进行数据监视,
image


简单模拟vue中的监测对象变化的原理

    

Vue.set();和vm.$set()

非响应式添加属性

image

Vue.set():响应式添加属性

添加的属性就和vue生成虚拟dom时候加工data里的数据一样,都有get和set监听。
image

vm.$set()方法和Vue.set()方法一致,只不过一个是构造函数身上的,一个是实例身上的。
vm.$set(vm.student,"sex","女");


Vue监视数据的原理:

  1. vue会监视data中所有层次的数据。

  2. 如何监测对象中的数据?
    通过setter实现监视,且要在new Vue时就传入要监测的数据。
    (1).对象中后追加的属性,Vue默认不做响应式处理
    (2).如需给后添加的属性做响应式,请使用如下API:
    Vue.set(target,propertyName/index,value)
    vm.$set(target,propertyName/index,value)

  3. 如何监测数组中的数据?
    通过包裹数组更新元素的方法实现,本质就是做了两件事:
    (1).调用原生对应的方法对数组进行更新。
    (2).重新解析模板,进而更新页面。

  4. 在Vue修改数组中的某个元素一定要用如下方法:
    1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
    2.Vue.set() 或 vm.$set()

特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象(data)添加属性!!!

image

image




    
    
    
    Document
    



    









学生信息

姓名:{{student.name}}

年龄:{{student.age}}

性别:{{student.sex}}

爱好:

  • {{val}}

朋友们:

  • {{v.name +":"+v.age}}

数据劫持

就是将data里的数据转为vm里_data的格式,为每个属性添加getter和setter的操作就叫数据劫持。劫持就是修改属性被set发现,让后set执行操作。
image