目标: 当v-for遍历的目标结构改变, Vue触发v-for的更新
情况1: 数组翻转
情况2: 数组截取
情况3: 更新值
口诀:
数组变更方法, 就会导致v-for更新, 页面更新
数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set()
-
{{ val }}
这些方法会触发数组改变, v-for会监测到并更新页面
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
这些方法不会触发v-for更新
slice()
filter()
concat()
注意: vue不能监测到数组里赋值的动作而更新, 如果需要请使用Vue.set() 或者this.$set(), 或者覆盖整个数组
总结: 改变原数组的方法才能让v-for更新
v-for
的默认行为会尝试原地修改元素而不是移动它们。
详解v-for就地更新流程(可以看ppt动画)
这种 虚拟DOM对比方式, 可以提高性能 - 但是还不够高
目标: 了解虚拟DOM的概念
.vue文件中的template里写的标签, 都是模板, 都要被vue处理成虚拟DOM对象, 才会渲染显示到真实DOM页面上
内存中生成一样的虚拟DOM结构(本质是个JS对象)
因为真实的DOM属性好几百个, 没办法快速的知道哪个属性改变了
比如template里标签结构
123
对应的虚拟DOM结构
const dom = {
type: 'div',
attributes: [{id: 'box'}],
children: {
type: 'p',
attributes: [{class: 'my_p'}],
text: '123'
}
}
以后vue数据更新
好处1: 提高了更新DOM的性能(不用把页面全删除重新渲染)
好处2: 虚拟DOM只包含必要的属性(没有真实DOM上百个属性)
总结: 虚拟DOM保存在内存中, 只记录dom关键信息, 配合diff算法提高DOM更新的性能
vue用diff算法, 新虚拟dom, 和旧的虚拟dom比较
旧虚拟DOM
123
新虚拟DOM
- 123
旧虚拟DOM
123
新虚拟DOM
123
v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key
来提供一个排序提示
-
{{ str }}
export default {
data(){
return {
arr: ["老大", "新来的", "老二", "老三"]
}
},
methods: {
addFn(){
this.arr.splice(1, 0, '新来的')
}
}
};
旧 - 虚拟DOM结构 和 新 - 虚拟DOM结构 对比过程
性能不高, 从第二个li往后都更新了
因为新旧虚拟DOM对比, key存在就复用此标签更新内容, 如果不存在就直接建立一个新的
-
{{ str }}
export default {
data(){
return {
arr: ["老大", "新来的", "老二", "老三"]
}
},
methods: {
addFn(){
this.arr.splice(1, 0, '新来的')
}
}
};
key为索引-图解过程 (又就地往后更新了)
v-for先循环产生新的DOM结构, key是连续的, 和数据对应
然后比较新旧DOM结构, 找到区别, 打补丁到页面上
最后补一个li, 然后从第二个往后, 都要更新内容
口诀: key的值有id用id, 没id用索引
key的值只能是唯一不重复的, 字符串或数值
v-for不会移动DOM, 而是尝试复用, 就地更新,如果需要v-for移动DOM, 你需要用特殊 attribute key
来提供一个排序提示
新DOM里数据的key存在, 去旧的虚拟DOM结构里找到key标记的标签, 复用标签
新DOM里数据的key存在, 去旧的虚拟DOM结构里没有找到key标签的标签, 创建
旧DOM结构的key, 在新的DOM结构里没有了, 则移除key所在的标签
-
{{ obj.name }}
图解效果:
总结: 不用key也不影响功能(就地更新), 添加key可以提高更新的性能
v-for什么时候会更新页面呢?
vue是如何提高更新性能的?
虚拟DOM是什么?
diff算法如何比较新旧虚拟DOM?
目标: 用v-bind给标签class设置动态的值
动态class
总结: 就是把类名保存在vue变量中赋予给标签
目标: 给标签动态设置style的值
动态style
总结: 动态style的key都是css属性名
目的: 转换格式, 过滤器就是一个函数, 传入值返回处理后的值
过滤器只能用在, 插值表达式和v-bind表达式
Vue中的过滤器场景
语法:
Vue.filter(“过滤器名”, (值) => {return “返回处理后的值”})
filters: {过滤器名字: (值) => {return “返回处理后的值”}
例子:
原来的样子: {{ msg }}
使用翻转过滤器: {{ msg | reverse }}
鼠标长停
总结: 把值转成另一种形式, 使用过滤器, Vue3用函数替代了过滤器.
全局注册最好在main.js中注册, 一处注册到处使用
目标: 可同时使用多个过滤器, 或者给过滤器传参
原来的样子: {{ msg }}
使用翻转过滤器: {{ msg | reverse('|') }}
鼠标长停
总结: 过滤器可以传参, 还可以对某个过滤器结果, 后面在使用一个过滤器
目标: 复制上个案例, 在此基础上, 把表格里的时间用过滤器+moment模块, 格式化成YYYY-MM-DD 格式
图示:
下载moment处理日期的第三方工具模块
moment官网文档: http://momentjs.cn/docs/#/displaying/
yarn add moment
定义过滤器, 把时间用moment模块格式化, 返回我们想要的格式
// 目标: 处理时间
// 1. 下载moment模块
import moment from 'moment'
// 2. 定义过滤器, 编写内部代码
filters: {
formatDate (val){
return moment(val).format('YYYY-MM-DD')
}
}
<!-- 3. 使用过滤器 -->
<td>{{ obj.time | formatDate }}</td>
目标: 一个数据, 依赖另外一些数据计算而来的结果
语法:
computed: {
"计算属性名" () {
return "值"
}
}
需求:
{{ num }}
注意: 计算属性也是vue数据变量, 所以不要和data里重名, 用法和data相同
总结: 一个数据, 依赖另外一些数据计算而来的结果
{{ reverseMessage }}
{{ reverseMessage }}
{{ reverseMessage }}
{{ getMessage() }}
{{ getMessage() }}
{{ getMessage() }}
总结: 计算属性根据依赖变量结果缓存, 依赖变化重新计算结果存入缓存, 比普通方法性能更高
此处只修改了变化的代码
统计:
总价钱为: {{ allPrice }}
平均价: {{ svgPrice }}
总结: 总价来源于所有数据计算而来的结果, 故采用计算属性
目标: 计算属性也是变量, 如果想要直接赋值, 需要使用完整写法
语法:
computed: {
"属性名": {
set(值){
},
get() {
return "值"
}
}
}
需求:
页面准备输入框
姓名:
总结: 想要给计算属性赋值, 需要使用set方法
目标: 小选框都选中(手选), 全选自动选中
分析:
① 先静态后动态, 从.md拿到静态标签和数据
② 循环生成复选框和文字, 对象的c属性和小选框的选中状态, 用v-model双向绑定
③ 定义isAll计算属性, 值通过小选框们统计c属性状态得来
模板标签和数据(直接复制在这基础上写vue代码)
全选:
-
任务名
正确代码,不可复制
全选:
-
{{ obj.name }}
目标: 全选影响小选
分析:
①: isAll改成完整写法, set里获取到全选框, 勾选的状态值
②: 遍历数据数组, 赋给所有小选框v-model关联的属性
图示:
正确代码,不可以复制
目标: 反选功能
分析:
①: 小选框的勾选状态, 在对象的c属性
②: 遍历所有对象, 把对象的c属性取相反值赋予回去即可
正确代码,不可以复制
目标: 可以侦听data/computed属性值改变
语法:
watch: {
"被侦听的属性名" (newVal, oldVal){
}
}
完整例子代码:
总结: 想要侦听一个属性变化, 可使用侦听属性watch
目标: 侦听复杂类型, 或者立即执行侦听函数
语法:
watch: {
"要侦听的属性名": {
immediate: true, // 立即执行
deep: true, // 深度侦听复杂类型内变化
handler (newVal, oldVal) {
}
}
}
完整例子代码:
总结: immediate立即侦听, deep深度侦听, handler固定方法触发
目标: 侦听list变化, 同步到浏览器本地
分析:
① 在watch侦听list变化的时候, 把最新的数组list转成JSON字符串存入到localStorage本地
② data里默认把list变量从本地取值, 如果取不到给个默认的空数组
效果:
新增/删除 – 刷新页面 – 数据还在
在之前的案例代码基础上接着写
正确代码,不可复制
Vue.js允许自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和v-bind表达式
全局的用Vue.filter()
局部的用filters属性
:key是给v-for循环生成标签颁发唯一标识的, 用于性能的优化
因为v-for数据项的顺序改变,Vue 也不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素
:key如果是索引, 因为索引是连续的, 如果删除其中某一个, 会导致最后一个被删除
当我们再删除的时候, :key再根据数据来把新旧的dom对比时, 删除:key不存在的对应的标签(添加也是一样的插入到指定位置, 别的都不会动)
因为vue内部只能监测到数组顺序/位置的改变/数量的改变, 但是值被重新赋予监测不到变更, 可以用 Vue.set() / vm.$set()
✨ 原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下
点 赞 , 你 的 认 可 是 我 创 作 的 动 力 ! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!
⭐️ 收 藏 , 你 的 青 睐 是 我 努 力 的 方 向 ! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!
✏️ 评 论 , 你 的 意 见 是 我 进 步 的 财 富 ! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!