Vue -- 列表渲染(基本列表 & key的原理 & 列表过滤 & 列表排序 )

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue -- 列表渲染(基本列表 & key的原理 & 列表过滤 & 列表排序 )相关的知识,希望对你有一定的参考价值。

1. 基本列表

示例代码:

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title>基本列表</title>
	<script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
	<!-- 
				v-for指令(可以用in关键字 也可以用of关键字):
						1.用于展示列表数据
						2.语法:v-for="(item, index) in(of) xxx" :key="yyy"
						3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
		-->
	<!-- 准备好一个容器-->
	<div id="root">
		<!-- 遍历数组 -->
		<h2>人员列表(遍历数组)</h2>
		<ul>
			<li v-for="(p,index) of persons" :key="index">
				{{p.name}}-{{p.age}}
			</li>
		</ul>

		<!-- 遍历对象 -->
		<h2>汽车信息(遍历对象)</h2>
		<ul>
			<li v-for="(value,k) of car" :key="k">
				{{k}}-{{value}}
			</li>
		</ul>

		<!-- 遍历字符串 -->
		<h2>测试遍历字符串(用得少)</h2>
		<ul>
			<li v-for="(char,index) of str" :key="index">
				{{char}}-{{index}}
			</li>
		</ul>

		<!-- 遍历指定次数 -->
		<h2>测试遍历指定次数(用得少)</h2>
		<ul>
			<li v-for="(number,index) of 5" :key="index">
				{{index}}-{{number}}
			</li>
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false

		new Vue({
			el: '#root',
			data: {
				persons: [
					{ id: '001', name: '张三', age: 18 },
					{ id: '002', name: '李四', age: 19 },
					{ id: '003', name: '王五', age: 20 }
				],
				car: {
					name: '奥迪A8',
					price: '70万',
					color: '黑色'
				},
				str: 'hello'
			}
		})
	</script>

</html>

运行结果:


2. key的原理

如果没有手动给列表元素绑定key,那么Vue默认会把index作为key。Key只是Vue内部需要用到,不会吧key属性解析到游览器上面

示例代码:

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title>key的原理</title>
	<script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
	<!-- 
				面试题:react、vue中的key有什么作用?(key的内部原理)
						
						1. 虚拟DOM中key的作用:
										key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 
										随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
										
						2.对比规则:
									(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
												①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
												②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。

									(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
												创建新的真实DOM,随后渲染到到页面。
												
						3. 用index作为key可能会引发的问题:
											1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
															会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。

											2. 如果结构中还包含输入类的DOM:
															会产生错误DOM更新 ==> 界面有问题。

						4. 开发中如何选择key?:
											1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
											2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
												使用index作为key是没有问题的。
		-->
	<!-- 准备好一个容器-->
	<div id="root">
		<!-- 遍历数组 -->
		<h2>人员列表(遍历数组)</h2>
		<button @click.once="add">添加一个老刘</button>
		<ul>
			<li v-for="(p,index) of persons" :key="index">
				{{p.name}}-{{p.age}}
				<input type="text">
			</li>
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false

		new Vue({
			el: '#root',
			data: {
				persons: [
					{ id: '001', name: '张三', age: 18 },
					{ id: '002', name: '李四', age: 19 },
					{ id: '003', name: '王五', age: 20 }
				]
			},
			methods: {
				add() {
					const p = { id: '004', name: '老刘', age: 40 }
					this.persons.unshift(p)
				}
			},
		})
	</script>

</html>

运行结果:


3. 列表过滤 计算属性(优先使用)和监视属性分别实现

示例代码:

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title>列表过滤</title>
	<script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
	<!-- 准备好一个容器-->
	<div id="root">
		<h2>人员列表</h2>
		<input type="text" placeholder="请输入名字" v-model="keyWord">
		<ul>
			<li v-for="(p,index) of filPerons" :key="index">
				{{p.name}}-{{p.age}}-{{p.sex}}
			</li>
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false

		//用watch实现
		//#region 
		/* new Vue({
			el:'#root',
			data:{
				keyWord:'',
				persons:[
					{id:'001',name:'马冬梅',age:19,sex:'女'},
					{id:'002',name:'周冬雨',age:20,sex:'女'},
					{id:'003',name:'周杰伦',age:21,sex:'男'},
					{id:'004',name:'温兆伦',age:22,sex:'男'}
				],
				filPerons:[]
			},
			watch:{
				keyWord:{
					immediate:true,
					handler(val){
						this.filPerons = this.persons.filter((p)=>{
							return p.name.indexOf(val) !== -1
						})
					}
				}
			}
		}) */
		//#endregion

		//用computed实现
		new Vue({
			el: '#root',
			data: {
				keyWord: '',
				persons: [
					{ id: '001', name: '马冬梅', age: 19, sex: '女' },
					{ id: '002', name: '周冬雨', age: 20, sex: '女' },
					{ id: '003', name: '周杰伦', age: 21, sex: '男' },
					{ id: '004', name: '温兆伦', age: 22, sex: '男' }
				]
			},
			computed: {
				filPerons() {
					return this.persons.filter((p) => {
						return p.name.indexOf(this.keyWord) !== -1
					})
				}
			}
		})
	</script>

</html>

运行结果:


4. 列表排序

示例代码:

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8" />
	<title>列表排序</title>
	<script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
	<!-- 准备好一个容器-->
	<div id="root">
		<h2>人员列表</h2>
		<input type="text" placeholder="请输入名字" v-model="keyWord">
		<button @click="sortType = 2">年龄升序</button>
		<button @click="sortType = 1">年龄降序</button>
		<button @click="sortType = 0">原顺序</button>
		<ul>
			<li v-for="(p,index) of filPerons" :key="p.id">
				{{p.name}}-{{p.age}}-{{p.sex}}
				<input type="text">
			</li>
		</ul>
	</div>

	<script type="text/javascript">
		Vue.config.productionTip = false

		new Vue({
			el: '#root',
			data: {
				keyWord: '',
				sortType: 0, //0原顺序 1降序 2升序
				persons: [
					{ id: '001', name: '马冬梅', age: 30, sex: '女' },
					{ id: '002', name: '周冬雨', age: 31, sex: '女' },
					{ id: '003', name: '周杰伦', age: 18, sex: '男' },
					{ id: '004', name: '温兆伦', age: 19, sex: '男' }
				]
			},
			computed: {
				filPerons() {
					const arr = this.persons.filter((p) => {
						return p.name.indexOf(this.keyWord) !== -1
					})
					//判断一下是否需要排序
					if (this.sortType) {
						arr.sort((p1, p2) => {
							return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age
						})
					}
					return arr
				}
			}
		})

	</script>

</html>

运行结果:



以上是关于Vue -- 列表渲染(基本列表 & key的原理 & 列表过滤 & 列表排序 )的主要内容,如果未能解决你的问题,请参考以下文章

Vue列表渲染

Vue列表渲染

vue-列表渲染

VUE项目实战22获取用户列表数据并渲染

vue基本使用

Vue 指令数据及事件绑定条件和列表渲染