[Vue] vue学习笔记(4): 渲染

条件渲染

主要有四个指令

  • v-show:控制元素可视性,即是否增加样式display=none
  • v-if/v-else-if/v-else:类似if/else-if/else的逻辑结构,进行条件判断,控制元素的可视性,注意这种方法会直接决定元素是否出现DOM树上,而非样式改变
< !--- n is a property of vue instance --- >
<div v-if="n===1">Angular</div>
<div v-else-if="n===2">React</div>
<div v-else-if="n===3">Vue</div>
<div v-else>guess</div>
< !--- v-else needs no js expr --- >

template的使用

假设有复数个元素的可视性判断条件相同,可以使用template来统一控制,这种情况下只能使用v-if

< !--- n is a property of vue instance --- >
<template v-if="n === 1">
	<h2>Apple</h2>
	<h2>Banana</h2>
	<h2>Corn</h2>
</template>

列表渲染

使用v-for来遍历数组,对象,字符串或指定次数

<h2>遍历数组</h2>
<ul>
	<li v-for="(p, index) in people" :key="index">
		{{index}}: {{p.name}} - {{p.age}}
	</li>
</ul>
< !---  --- >
<h2>遍历对象 - js对象是由k-v键值对组成的</h2>
<ul>
	<li v-for="(v, k) in student" :key="k">
		{{k}} - {{v}}
	</li>
</ul>

key的作用

⬇️一图流说明key的作用⬇️

  • 以索引作为key❌
    解释:对于数组中的对象中来说,索引值并不是与其绑定的唯一标准。如图所示,由于数组更新后的第一条记录(即存储的对象)与先前的发生了变化,但是key值不变,而vue依据key值来判断是更新还是复用旧虚拟DOM上的元素
    ⚠️以第一条数据key='0'为例,其中的文本元素发生了变化,因此vue更新了其值;而输入框元素无变化,vue将选择复用旧DOM的元素,无论输入框内是否已经有输入的内容。以此类推,会得到一个错位的人员列表

  • 以id为key(更好的效率,在此场景下推荐)✅
    解释:对象的id是作为识别对象的唯一标识的最好选择,依照vue根据key值排查元素的机制,这样做很好地保证了顺序性,避免了错位,也节省了资源--因为vue实际上只更新了最后也是最新的那一行数据

  • 结论:由此可知,在没有逆序增加/删除元素的情况下,使用index是没问题的

列表过滤

创建一个输入框用于筛选列表内的记录,该操作不改变原有的列表,可通过计算属性或监视属性实现->推荐计算属性

基本架构

<!--- 用v-for写列表 --->
<!--- input box --->
<input type="input" placeholder="Enter a name" v-model="keyword"/>

<script type="text/javascript">
new Vue({
	el: '#root',
	data: {
		keyword: '', 
		students: [
			{id: '001', name: 'xyz', age: 19, gender: 'F'}, 
			{id: '002', name: 'xvv', age: 18, gender: 'M'}, 
			{id: '003', name: 'hyt', age: 21, gender: 'F'}, 
			{id: '004', name: 'fvo', age: 13, gender: 'M'}
		],
		students_fil: []
	},
	// 方法1:用watch监控keyword的变化,生成过滤后的新数组students_fil
	watch: {
		// 不能简写,初始时由于关键字和过滤数组皆为空,导致页面内容空白
		// 使用indexOf判断是否存在含有val值的记录,-1 = 不存在,否则返回对应索引值
		// val: keyword的新值
		// 将watch配置成初始化时立即执行 --> immediate
		immediate: true,
		handler(val) {
			this.students_fil = this.students.filter((p)=>{
				return p.name.indexOf(val) !== -1
			})
		}
	},
	
	// 方法2:用computed计算过滤后的新数组,该方法无需在data中配置students_fil
	// 第一个return,将filter方法给的数组返回给students_fil
	computed: {
		students_fil() {
			return this.students.filter((p)=>{
				return p.name.indexOf(this.keyword) !== -1
			})
		}
	}
})
</script>

当然也可以针对这个案例里的列表进行排序⬇️

列表排序

3个选项:升序 -- 2,降序 -- 1,归零 -- 0。排序必须是针对当前的列表进行的

<button>Ascending</button>
<button>Descending</button>
<button>Original</button>

<script type="text/javascript">
// 在上一个案例的vue实例中增加一个data属性
sortType = 0,

// 在过滤的逻辑上排序, 先过滤再排序
/* 利用sort方法,Array.sort((a, b) => {
	return a-b --> order from lowest to highest
	return b-a --> order from highest to lowest
})
*/
computed: {
	students_fil() {
		const arr = this.students.filter((p)=>{
			return p.name.indexOf(this.keyword) !== -1
		})
		if (this.sortType) {
			arr.sort((p1, p2)=>{
				return if (sortType === 1) p2.age - p1.age : p1.age - p2.age
			})
		}
		return arr
	}
}
</script>
posted @ 2023-11-29 21:47  Akira300000  阅读(5)  评论(0编辑  收藏  举报