- 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属性名: 值}"