前言
上一篇幅我们一起学习了Vue的基本指令操作、插值语法和双向数据绑定,命令较为多,需要大家勤加练习,相信在不久的将来,你一定会灵活运用这些基本指令,勤学苦练,熟能生巧,多思考,多实践!
这一篇幅我们会继续带大家学习一下关于Vue中的更新检测、API、虚拟DOM以及DIFF算法,让大家对Vue的理解更进一步!
1.v-for更新检测
在这里我们先来思考两个问题:
- v-for数组变化,会更新页面嘛?
- 哪些数组方法会造成v-for更新,哪些不能?
针对上面两个问题,大家记住一下口诀:
- 数组变更方法, 就会导致v-for更新, 页面更新
push() pop() shift() unshift() splice() sort() reverse()
- 数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set()
filter() concat() slice()
2.虚拟DOM
2.1 真实DOM
DOM就是文档对象模型【就是一个节点树】,HTML的文档document页面是一切的基础,没有它dom就无从谈起。当我们创建好一个页面并加载到浏览器的时候,DOM就悄然而生,它会把网页文档转换为一个文档对象,主要功能就是处理网页内容。在这个文档给对象里,所有元素呈现出一种层次,就是除了顶级元素html外,其他元素都被包含在另外的元素中。
2.2 虚拟DOM和DIFF算法
虚拟DOM(virtual DOM)只是js模拟的DOM结构,是对真实DOM的一个抽象,虚拟DOM是由js实现的避免DOM树频繁更新,通过js对象模拟DOM中的节点,然后通过特定的render方法将它渲染成真实的节点,数据更新时,渲染得到新的虚拟DOM,然后与上一次得到的虚拟DOM进行比较(diff算法),得到需要变更的DOM,更新在真实的DOM上,实现UI的同步更新。
真实DOM和虚拟DOM区别
- 虚拟dom不会进行排版与重绘操作,虚拟dom是把js代码转为真实dom
- 真实dom频繁回流与重绘效率非常低
- 虚拟dom可以跨平台操作而真实dom是与浏览器绑定的
- 虚拟dom进行频繁修改,之后一次性比较再修改真实dom中需要修改的部分,最后真实dom进行排版重绘,从而减少dom节点的排版与重绘的损耗
2.3 diff算法
同级比较-根元素变化-整个dom树删除重建
同级比较-根元素不变-属性改变更新属性
2.4 v-for的key
无key
当我们需要在索引1的位置,也就是老二的位置插入新来的时候,那么v-for没有key的时候,会是这种操作来插入:
新来的替换原来老二—>老二替换原来老三—>然后再把老三加进来
这时我们可以看到,从老二开始往后逐步更新操作,性能不高。
有key-值为索引或者唯一不重复的字符串或数字
怎么才能最大限度的修改/服用相同类型的元素呢,那就是添加key属性。
有key属性,基于key来比较新旧虚拟DOM,复用/更新存在的元素,移除key不存在的元素
key属性使用:
一般在用到v-for指令的标签中,添加key属性,值为v-for遍历的对象的索引或者对象唯一的不重复的字符串或数字,例如id等,语法如下:
:key=“索引或唯一值”
注意key前面的:不要省略
示例1:key值为索引
<div id="app">
<ul>
<!-- 此处key的值为索引 -->
<li v-for="item in arr" :key="index">
{{item}}
</li>
</ul>
<button @click="add">春天后面添加一个夏天</button>
</div>
<script src="../vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
arr: ["春天", "秋天", "冬天"]
},
methods: {
add() {
this.arr.splice(1, 0, "夏天")
}
}
});
</script>
示例2:key值为唯一值
<div id="app">
<ul>
<!-- 此处key的值为唯一值 -->
<li v-for="item in stus" :key="stu_no">
{{item.stu_no}}---{{item.stu_name}}
</li>
</ul>
<button @click="add">张三后面添加一个李四,学号1002</button>
</div>
<script src="../vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
stus: [
{
stu_no: 1001,
stu_name: '张三'
},
{
stu_no: 1003,
stu_name: '王五'
}
]
},
methods: {
add() {
this.stus.splice(1, 0, { stu_no: 1002, stu_name: '李四' })
}
}
});
</script>
3、过滤器
过滤器故名思意,就是过滤出来我们想要的数据,就比如我们用筛子筛细沙,能够漏下来的就是我们想要的沙子,要想沙子越细(目标数据),我们的筛子的网格就要越小(过滤条件)
过滤器作用
传入一个值,处理后返回另外一个值
过滤器实现
通过管道符 | 实现过滤
过滤器写在哪儿
只能写在插值表达式、v-bind动态属性里
定义语法
- 全局:
Vue.filter(“过滤器名”,function(val){
过滤语句
})
- 局部:需要在vue实例的filters参数中去写
filters:{
过滤器名:function(val){
过滤语句
}
}
使用
- 在插值表达式中使用
{{ vue变量 | 过滤器名字 }}
-
在v-bind中使用
:属性名=“vue变量 | 过滤器名字”
-
过滤器传参
vue变量 | 过滤器名字(参数)
-
多个过滤器
vue变量 | 过滤器1 | 过滤器2
示例:以插值表达式使用为例
<div id="app">
¥{{price | gsh}}元
</div>
<script src="../vue.js"></script>
<script>
//创建vue实例
var vue = new Vue({
el: "#app",//vue挂载到id为app的元素上
data: {
price: 123.456
},
// 局部过滤器
filters: {
// 通过过滤器将价格保留2位小数
gsh: function (val) {
val = val.toFixed(2);
return val;
}
}
})
</script>
4、总结