1.v-for更新监测
数组变更方法, 就会导致v-for更新, 页面更新
数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.
s
e
t
(
)
/
/
V
u
e
解
决
−
t
h
i
s
.
set() // Vue解决-this.
set()//Vue解决−this.set(参数1,参数2,参数3)
// 参数1: 更新目标结构
// 参数2: 更新位置
// 参数3: 更新值
<template>
<div>
<ul>
<li v-for="(item, index) in arr" :key="index">{{ item }}</li>
</ul>
<!-- 结果: 会更新页面 -->
<button @click="rev">数组翻转</button>
<!-- 结果: 不会更新页面 -->
<button @click="sli">数组截取</button>
<!-- 结果: 不会更新页面 -->
<button @click="updateVal">更新值</button>
</div>
</template>
<script>
export default {
name: 'VuecliDemoApp',
// Date
// 组件中的 data 都是函数, 函数中返回一个对象
// 为了保证多个组件复用时, 内部的 data 相互独立
data() {
return { // 对象字面量: new Object()
arr: ['a', 'b', 'c']
}
},
methods: {
rev() {
// 1. 数组翻转可以让v-for更新
this.arr.reverse()
},
sli() {
// 2. 数组slice方法不会造成v-for更新
// slice不会改变原始数组
// this.arr.slice(0, 3)
// 解决v-for更新 - 覆盖原始数组
let newArr = this.arr.slice(0, 3)
this.arr = newArr
},
updateVal() {
// Vue 2 响应式的原理是使用 Object.defineProperty 方法实现的数据劫持
// 有一个小缺陷, 无法劫持直接修改数组元素的值
// 它除了数据劫持, 还对数组的大部分方法进行了重写, 手动劫持了方法
// 结论: 在 Vue 2 中不要直接使用 数组[索引] 的方式修改数据, 会导致无法更新的情况
// this.arr[0] = '张三' // 不要这样干
// Vue 也提供了解决方案: $set
this.$set(this.arr, 0, '张三')
}
</script>
<style lang="scss" scoped>
</style>
2.虚拟DOM
.vue文件中的template里写的标签, 都是模板, 都要被vue处理成虚拟DOM对象, 在生成真实DOM片段, 才会渲染显示到真实DOM页面上
● 虚拟DOM是什么? ---- 保存节点信息的一个js虚拟对象
● 虚拟DOM的好处?----- 提高性能 , 不用频繁操作真实DOM , 在内存中比较变化部分,然后给真实DOM更新
1.内存中生成一样的虚拟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'
}
}
2.以后vue数据更新
● 生成新的虚拟DOM结构
● 和旧的虚拟DOM结构对比
● 找不不同, 只更新变化的部分(重绘/回流)到页面 - 也叫打补丁
2.1重绘与回流
频繁操作DOM会触发重绘与回流: 影响性能
回流(重排):元素的几何信息(高度/位置)发生变化时,浏览器需要重新计算位置,并重新绘制
重绘:元素的颜色/透明度等属性变化时,浏览器重新渲染
回流一定会触发重绘,而重绘不一定会触发回流
3.v-for中key值的作用: 提高性能
v-for 无key 就地更新
v-for key 为索引 根据key比较 还是就地更新
v-for key 为id 基于 key 来比较新旧虚拟DOM, 移除key不存在元素
要求: key 值为 唯一不重复 的 字符串或数字
如何使用? 有id用id,无id用索引
v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key 来提供一个排序提示
● 新DOM里数据的key存在, 去旧的虚拟DOM结构里找到key标记的标签, 复用标签
● 新DOM里数据的key存在, 去旧的虚拟DOM结构里没有找到key标签的标签, 创建
● 旧DOM结构的key, 在新的DOM结构里没有了, 则移除key所在的标签
4.watch侦听器(深度监听)(重要):
作用:可以侦听data/computed属性值的改变
//语法1:
watch:{
'被监听的属性名'(newVal,oldVal){//函数写法 只能侦听基本数据类型的变化
//newVal 修改后的值 oldVal 修改前的值
log(newVal,oldVal)
}
}
//语法2: //对象写法 侦听复杂类型
watch:{
'被监听的属性名':{
deep:true, //深度侦听,可以侦听到引用数据类型
handler(newVal,oldVal){
//深度侦听对象的属性时, oldVal将失效,和newVal的值一样 (Vue bug)
// 不影响开发
log(newVal,oldVal)
}
}
}
侦听器实现数据缓存