条件渲染跟列表
# 条件渲染跟数据检测
# 条件渲染
条件渲染是一种基于条件来决定是否渲染某个组件或元素的技术。它允许你在Vue组件中根据条件动态地展示或隐藏特定的内容。
在Vue中,你可以使用v-if
指令或v-show
指令来实现条件渲染。
# v-if
<template v-if="showMessage">
<div>
<p >Hello, Vue!</p>
</div>
</template>
2
3
4
5
template:渲染后 dom中没有 template 这个元素,只有div以及p元素,且 template只能跟v-if使用
<script>
export default {
data() {
return {
showMessage: true
};
}
};
</script>
2
3
4
5
6
7
8
9
if常跟else连用,v-if
也可以跟v-else-if
或者v-else
连用
<template>
<div>
<p v-if="n===1">Hello11</p>
<!-- <span>test</span> -->
<p v-else-if="n===2">Hello22</p>
<p v-else="n===3">Hello33</p>
<!-- <p v-else>Hello33</p> 这才是正确的写法 -->
</div>
</template>
2
3
4
5
6
7
8
9
这样的效果就是
- 如果n为1,则显示Hello11
- 如果n为2,则显示Hello22
- 如果n不是1,2,不论是3还是其他的都会显示Hello33。else是除开之前(v-if 跟若干个v-else-if)情况的所有,所以写与不写条件都没差别。
# v-show
<template>
<div>
<p v-show="showMessage">Hello, Vue!</p>
</div>
</template>
2
3
4
5
当showMessage
的值为真时,<p>
元素会被渲染出来;当showMessage
的值为假时,<p>
元素不会被渲染。
总结:
v-if
根据渲染条件决定是否把元素渲染到DOM页面,条件为false,则dom中无该元素,反之则有而
v-show
不管渲染条件是什么,都会把元素渲染到DOM页面,只是简单的切换CSS的显示隐藏,即调整display属性为true或者false。**提示:**如果需要非常频繁地切换,则使用
v-show
较好;如果在运行时条件很少改变,则使用v-if
较好。
# 列表渲染
列表渲染是指通过使用v-for
指令,将一个数组或对象的内容循环渲染到页面上的每个元素中。v-for
指令可以遍历数组或对象的每个元素,并为每个元素创建一个新的Vue实例,从而实现列表的渲染。
# v-for中使用数组
用法:(item, index) in xxx
各个参数:
xxx: 源数据数组
item:数组元素别名
index:可选,索引 可以访问所有父作用域的属性
语法: v-for="(item,index) in xx" :key="yy"
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }} - {{ item.price }}
</li>
</ul>
<!-- <span>test</span> -->
2
3
4
5
6
提示:可以利用of
替代in
作为分隔符,因为它更接近迭代器的语法:
<li v-for="item of items" :key="item.id">
{{ item.name }} - {{ item.price }}
</li>
2
3
new Vue({
el: '#app',
data: {
items: [
{ id: 1, name: 'Apple', price: 10 },
{ id: 2, name: 'Banana', price: 5 },
{ id: 3, name: 'Orange', price: 3 }
]
}
})
2
3
4
5
6
7
8
9
10
在Vue中,:key
是可选的,但是推荐使用。它是用来给每个元素提供一个唯一的标识符,帮助Vue跟踪每个节点的身份,从而优化DOM操作和渲染性能。所以在上述例子中即使不写:key=“item.id”也不会报错
但是需要注意的是,如果在Vue中使用了:key
绑定,但出现了重复的值,Vue会发出警告并抛出错误。这是因为:key
的作用是唯一标识每个元素,以确保Vue能够正确跟踪和渲染列表。
为了避免这种情况的发生,应该确保在v-for
遍历元素时使用唯一的:key
值。原因会在下文更详细的说明。
# v-for中使用对象
v-for还可以使用对象、数字或者字符串,后两者用到的场景很少,这里只简单的演示下对象的使用
<div v-for="(item, name) in xxx" :key="name">
{{ name }} - {{ item }}
</div>
// 以下为实际展示效果
apple - 甜
banana - 酸
orange - 甜酸
2
3
4
5
6
7
xxx:{
'apple': '甜',
'banana': '酸',
'orange': '甜酸'
}
2
3
4
5
v-for中使用对象的语法:
v-for="(value,key,index) in object" 其中 index可选,为索引
# key的探究
前文中说:key是非必填的,但是又强调它的值要确保唯一性,为什么呢?
在Vue中,当使用v-for
指令遍历元素时,Vue会生成一个虚拟节点(VNode)来表示每个元素。这个虚拟节点包含了元素的所有属性和状态,但是并不直接操作实际的DOM元素。
当Vue渲染列表时,它会比较(使用diff算法)新旧虚拟节点(VNode)之间的差异,并计算出最小的DOM操作,然后执行这些操作来更新实际的DOM。
:key
绑定的作用在于帮助Vue唯一标识每个虚拟节点(VNode)。通过使用唯一的:key
值,Vue可以跟踪每个虚拟节点的身份和状态,从而正确地识别需要更新的元素。
如果使用重复的:key
值,Vue将无法正确地跟踪每个虚拟节点的身份和状态,从而导致渲染错误和不可预测的行为。因此,在使用v-for
遍历元素时,推荐使用唯一的:key
绑定来提供唯一的标识符,以确保虚拟DOM的正确操作和渲染性能。
不设置:key,会自动使用index作为key
但是index作为key可能会引发这些问题:
- 对数据进行,逆序添加、逆序删除等破坏顺序操作时,会产生没必要的DOM更新,界面不影响,但是效率低
- 如果结构中包含输入类的dom,则会产生错误的DOM更新
推荐使用唯一标识的的数据作为key
# 数据检测原理
渲染到页面上的数据之所以能够实现数据的双向绑定,数据同步(响应式),其根本是因为Vue实现了数据检测。一旦检测到数据发生变化则会驱动视图更新数据。
# 检测对象中的数据
通过setter实现检测,且要在new Vue时就传入要检测的数据。
- 对象中后追加的属性,Vue默认不做响应式处理
- 如要给后添加的属性做响应式,请使用如下API:
- Vue.set(target,propertyName/index,value)
- Vm.$set(target,propertyName/index,value)
# 检测数组中的数据
通过包裹数据更新元素的方法实现:
- 调用原生对应的方法对数据进行更新
- 重新解析模板,进而更新页面
在vue修改数组某个元素一定要用如下方法:
push()
末尾添加pop()
末尾删除shift()
首位删除unshift()
首位添加splice()
拼合sort()
排序reverse()
反转
或者使用重新设置属性,而不是通过索引值来进行修改,这是由于 JavaScript 的限制,以下情况Vue都不能检测:
- 当你利用索引直接设置一个数组项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:
vm.items.length = newLength
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue
相同的效果,同时也将在响应式系统内触发状态更新:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
2
3
4
你也可以使用 vm.$set
(opens new window) (opens new window)实例方法,该方法是全局方法 Vue.set
的一个别名:
vm.$set(vm.items, indexOfItem, newValue)
为了解决第二类问题,你可以使用 splice
:
vm.items.splice(newLength)
原理的探究会让我们更容易理解跟学习,上述只是简单的大致的描述,这里附上官网链接:
https://v2.cn.vuejs.org/v2/guide/list.html
https://cn.vuejs.org/guide/essentials/list.html#array-change-detection