vue梳理
v-if和v-show的区别
- v-if指令用于条件性地渲染一块内容。这只会在指令的表达式返回 true 值的时候被渲染, 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
- v-show根据条件展示元素的选项, 控制方式只是简单地切换元素的 CSS 属性 display。(注意: v-show 不支持 template 和 v-else元素)
v-if主要用于切换不频繁的组件中, 在很大程度上节省了初次渲染的性能, 但在后续切换时会进行组件渲染, 开销大; v-show反之, 在初次渲染时就会进行所有组件的加载, 消耗性能, 但在后续切换时只修改属性, 节省了后续开销,
key值的作用
- 用key管理可复用的元素
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快外. 但不总是符合实际需求, 因此使用key可以使相同的模板元素两个元素是完全独立的,不复用它们
例如:
- 默认
loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素, 不会被替换掉——仅仅是替换了它的 placeholder。<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template>
- 添加key值后:
每次切换时,输入框都将被重新渲染。<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username" key="username-input"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address" key="email-input"> </template>
- 用key维护状态
当Vue正在更新v-for 渲染的元素列表时,它默认使用“就地更新”的策略, 如果数据项的顺序被改变, Vue不会移动DOM元素匹配顺序, 而是更新每一个元素且确保每个索引正确渲染, 这种只适用于不依赖子组件状态或临时 DOM 状态. 因此为了使Vue方便跟踪每一个节点, 从而重用和重新排序现有的元素, 节省开销提高性能, 可提供一个唯一的key属性.
尽可能在使用 v-for 时提供 key属性(2.2+版本组件中使用必须制定key),除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
例如:
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
更新检测
注意: 如果Vue未检测到数据更新将不会对相关数据进行重新渲染, 会导致数据更新成功, 但页面元素内容未更新的异常情况
数组更新检测
- 变异方法
Vue 将被侦听的数组的变异方法进行了包裹,所以它们将会触发视图更新
- 其中包括:
push() // 添加元素到数组末尾
pop() // 移除数组中末尾元素
shift() // 移除数组中首元素
unshift() // 添加元素到数组末尾
splice() // 从数组中添加/删除项目,然后返回被删除的项目。
sort() // 数组排序
reverse() // 数组反转
- 非变异方法
它们不会改变原始数组,而总是返回一个新数组。当使用非变异方法时,不会触发视图更新, 可以用新数组替换旧数组解决更新问题
- 其中包括:
filter() // 过滤返回值为true的元素, 生成新数组
concat() // 数组连接
slice() // 从已有的数组中返回选定的元素
const vm = new Vue({
data: {
items: ['a', 'b', 'c', ''],
items2: ['d', 'f']
}
})
vm.items.filter(item => item) //不会触发视图更新
vm.items = vm.items.filter(item => item) //会触发视图更新
vm.items.concat(vm.items2) //不会触发视图更新
vm.items = vm.items.concat(vm.items2) //会触发视图更新
vm.items.slice(0,3) //不会触发视图更新
vm.items = vm.items.slice(0,3) //会触发视图更新
vm.items[1] = 'x' // 不会触发视图更新
vm.$set(vm.items, 1, 'x') //会触发视图更新
vm.items.length = 2 // 不会触发视图更新
vm.items.splice(newLength) // 会触发视图更新
对象更新检测
由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除.对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。
例如:
const vm = new Vue({
data: {
a: 1,
user: {
name: '张三'
}
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的
vm.user.age = 15 //不是响应式
vm.$set(vm.user, 'age', 15) //是响应式
// 常用
Object.assign(vm.user, {age: 15}) //不是响应式
vm.user = Object.assign({}, vm.user, {age: 15}) //是响应式