- 1. 能够了解更新监测, key作用, 虚拟DOM, diff算法
- 2. 能够掌握设置动态样式
- 3. 能够掌握过滤器, 计算属性, 侦听器
- 4. 能够完成品牌管理案例
一.Vue基础_更新监测和key
1.v-for更新监测
目标:目标结构变化, 触发v-for的更新
- 情况1: 数组翻转
- 情况2: 数组截取
- 情况3: 更新值
口诀:
数组变更方法, 就会导致v-for更新, 页面更新
push
方法是 JavaScript 数组对象的一个方法,用于向数组的末尾添加一个或多个新元素,并返回添加新元素后数组的新长度pop
方法是 JavaScript 数组对象的一个方法,用于移除数组的最后一个元素,并返回被移除的元素。shift
方法是 JavaScript 数组对象的一个方法,用于移除数组的第一个元素,并返回被移除的元素。unshift
方法是 JavaScript 数组对象的一个方法,用于向数组的开头添加一个或多个新元素,并返回添加新元素后数组的新长度。splice
方法是 JavaScript 数组对象的一个方法,用于在指定位置插入或删除元素,并返回被删除的元素组成的数组。sort
方法是 JavaScript 数组对象的一个方法,用于对数组的元素进行排序。默认情况下,sort
方法会将数组的元素转换为字符串,然后按照 Unicode 码点顺序进行排序。reverse
方法是 JavaScript 数组对象的一个方法,用于颠倒数组中元素的顺序,即将数组中的元素从后向前排列。
数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set()
filter
方法可以帮助程序员方便地对数组进行筛选,从而得到符合特定条件的元素集合。
新建一个文件夹,用vscode打开文件,在用命令vue create demo创建项目
<template><div><ul><li v-for="(val,index) in arr" :key="index">{{ val }}</li></ul><button @click="revBtn">数组翻转</button><button @click="sliceBtn">截取前三个</button><button @click="updateBtn">点击改掉第一个元素的值</button></div>
</template><script>export default {data(){return {arr: [5,3,9,2,1]}},methods: {revBtn(){// 1.数据翻转可以让v-for更新this.arr.reverse()},sliceBtn(){// 2.数组slice方法不会造成v-for更新// slice不会改变原始数组this.arr.slice(0,3)// console.log(re)// 解决v-for更新 ---覆盖原始数组let newArr = this.arr.slice(0,3)this.arr = newArr},updateBtn(){// 3.更新某个值的时候,v-for是监测不到的// this.arr[0] = 1000;// 解决-This.$set()// 参数1:更新目标结构// 参数2:更新位置// 参数3:更新值this.$set(this.arr,0,1000)}}}
</script><style></style>
在截取前三个问题中,如何解决v-for更新,如下图:
在点击改掉第一个元素的值中,如何解决v-for更新问题,如下:
1. 哪些数组方法会导致v-for更新页面?
可以改变原数组的方法
2. 有的数组方法不导致v-for更新页面, 如何处理?
拿返回的新数组, 直接替换旧数组 this.$set()方法更新某个值
2.v-for就地更新
目标:当数组改变后是如何更新的
旧-虚拟DOM结构: 新-虚拟DOM结构:
新旧DOM产生后对比, 然后决定是否复用真实DOM/更新内容
<template><div><ul><li v-for="(val, ind) in arr" :key="ind">{{ val }}</li></ul><button @click="btn">下标1位置插入新来的</button></div>
</template><script>export default {data(){return {arr: ["老大","老二","老三"]}},methods: {btn(){this.arr.splice(1,0,'新来的')}}}
</script><style></style>
v-for更新时, 是如何操作DOM的?
循环出新的虚拟DOM结构, 和旧的虚拟DOM
结构对比, 尝试复用标签就地更新内容
3.真实DOM
目标:在document对象上, 渲染到浏览器上显示的标签
虚拟DOM
目标:本质是保存节点信息, 属性和内容的一个JS对象 ,真实DOM属性过多, 遍历耗时
目标:在内存中比较变化部分, 然后给真实DOM打补丁(更新)
-
内存中生成一样的虚拟DOM结构(==本质是个JS对象==)
因为真实的DOM属性好几百个, 没办法快速的知道哪个属性改变了
比如template里标签结构
<template><div id="box"><p class="my_p">123</p></div> </template>
对应的虚拟DOM结构
const dom = {type: 'div',attributes: [{id: 'box'}],children: {type: 'p',attributes: [{class: 'my_p'}],text: '123'} }
-
以后vue数据更新
-
生成新的虚拟DOM结构
-
和旧的虚拟DOM结构对比
-
利用diff算法, 找不不同, 只更新变化的部分(重绘/回流)到页面 - 也叫打补丁
-
==好处1: 提高了更新DOM的性能(不用把页面全删除重新渲染)==
==好处2: 虚拟DOM只包含必要的属性(没有真实DOM上百个属性)==
1. 虚拟DOM是什么?
本质就是一个JS对象, 保存DOM关键信息
2. 虚拟DOM好处?
提高DOM更新的性能, 不频繁操作真实DOM,
在内存中找到变化部分, 再更新真实DOM(打补丁)
3.diff算法
目标:同级比较-根元素变化-整个dom树删除重建
旧虚拟DOM
<div id="box"><p class="my_p">123</p>
</div>
新虚拟DOM
<ul id="box"><li class="my_p">123</li>
</ul>
情况2: 根元素没变, 属性改变, ==元素复用==, 更新属性
旧虚拟DOM
<div id="box"><p class="my_p">123</p>
</div>
新虚拟DOM
<div id="myBox" title="标题"><p class="my_p">123</p>
</div>
01、第一章webpack+vue基础/1-20 虚拟DOM+Diff算法
1. diff算法如何比较新旧虚拟DOM? 同级比较
2. 根元素变化? 删除重新建立整个DOM树
3. 根元素未变, 属性改变? DOM复用, 只更新属性
4.无key
目标:从第二个往后更新内容 – 性能不高
情况3: 根元素没变, 子元素没变, 元素内容改变
无key - 就地更新
v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key
来提供一个排序提示
<ul id="myUL"><li v-for="str in arr">{{ str }} <input type="text"></li>
</ul>
<button @click="addFn">下标为1的位置新增一个</button>
export default {data(){return {arr: ["老大", "新来的", "老二", "老三"]}},methods: {addFn(){this.arr.splice(1, 0, '新来的')}}
};
目标:最大限度尝试就地修改/复用相同类型元素
有key, 值为索引
目标:有key属性, 基于key的来比较新旧虚拟DOM, 移除key不存在元素
目标:先产生新旧虚拟DOM, 根据key比较, 还是就地更新
有key, 值唯一不重复的字符串或数字
目标:有key属性, 基于key的来比较新旧虚拟DOM, 移除key不存在元素
- 给每个数据换成对象, 准备id, 把id的值作为key
有key, 值为id
目标:先产生新旧虚拟DOM, 根据key比较
1. 子元素或者内容改变会分diff哪2种情况比较?
无key, 就地更新
有key, 按照key比较
2. key值要求是?
唯一不重复的字符串或者数值
3. key应该怎么用?
有id用id, 无id用索引
4. key的好处? 可以配合虚拟DOM提高更新的性能
v-for什么时候会更新页面呢?
数组采用更新方法, 才导致v-for更新页面
vue是如何提高更新性能的?
采用虚拟DOM+diff算法提高更新性能
虚拟DOM是什么?
本质是保存dom关键信息的JS对象
diff算法如何比较新旧虚拟DOM?根元素改变 – 删除当前DOM树重新建
根元素未变, 属性改变 – 更新属性
根元素未变, 子元素/内容改变
无key – 就地更新 / 有key – 按key比较
5.动态class
目标: 用v-bind给标签class设置动态的值
- 语法 :class="{类名: 布尔值}"
如何给标签class属性动态赋值?
:class=“{类名: 布尔值}”, true使用, false不用
6.动态style
目标: 给标签动态设置style的值
语法 :style="{css属性名: 值}"
给style赋值和class区别是?
:class="{类名: 布尔值}”, true使用, false不用
:style="{css属性名: 值}"