一、基本列表
v-for指令
(1)用于展示列表
(2)语法:<li v-for = "(item , index) in items" , :key="index" > {{ item }} </li>
(3)可遍历:数组、对象、字符串、指定次数
示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<!-- 引入Vue -->
<script src="../vuejs//vue.js"></script>
</head>
<body>
<!-- 准备容器 -->
<div id="root">
<h>v-for遍历数组(常用)</h>
<ul>
<li v-for="(p,index) in persons" :key="index">{{p.name}}---{{p.age}}</li>
</ul>
<h>v-for遍历对象</h>
<ul>
<li v-for="(value, key) in obj" :key="key">{{key}}---{{value}}</li>
</ul>
<h>v-for遍历字符串(用的少)</h>
<ul>
<li v-for="(char, index) in str" :key="index">{{index}}---{{char}}</li>
</ul>
<h>遍历指定次数</h>
<ul>
<li v-for="(n, index) in 5">{{index}}---{{n}}</li>
</ul>
</div>
<script>
new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'温开水a',age:21},
{id:'002',name:'温开水b',age:22},
{id:'003',name:'温开水c',age:23}
],
obj:{
name1:'温开水a',
name2:'温开水b',
name3:'温开水c',
},
str:"wenkaishui",
}
})
</script>
</body>
</html>
二、key的原理
面试题:react、vue中的key有什么作用?(key的内部原理)
(一)虚拟DOM中key的作用
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM, 随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较,比较规则如下
(二)对比规则
(1)旧虚拟DOM中找到了与新虚拟DOM相同的key
①若虚拟DOM中内容没变, 直接使用之前的真实DOM!
②若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。(2)旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面。
(三)问题及解决
用index作为key可能会引发的问题
(1)若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。(2)如果结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题。
开发中如何选择key?
(1)最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
(2)如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
(五)图示
(六)示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>key的原理</title>
<script type="text/javascript" src="../vuejs/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<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>
三、列表过滤
(一)watch实现
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>列表过滤</title>
<script type="text/javascript" src="../vuejs/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>人员列表</h2>
<input type="text" placeholder="请输入姓名" v-model="keyWord"></input>
<ul>
<li v-for="(p, index) in fileFersons" :key="index">{{p.name}}-{{p.sge}}-{{p.sex}}</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
//用watch实现
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:'男'}
],
filPersons:[]
},
watch:{
keyWord:{
handler:function(newVal){ // 回调函数:将过滤的数组部分赋给filePersons
this.fileFersons = this.persons.filter((p)=>{
return p.name.indexOf(newVal)!==-1;
})
},
immediate:true
}
}
})
</script>
</html>
图解
(二)computed实现
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>列表过滤</title>
<script type="text/javascript" src="../vuejs/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器-->
<div id="root">
<h2>人员列表</h2>
<input type="text" placeholder="请输入姓名" v-model="keyWord"></input>
<ul>
<li v-for="(p, index) in filPersons" :key="index">{{p.name}}-{{p.sge}}-{{p.sex}}</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
//用watch实现
// 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:'男'}
// ],
// filPersons:[]
// },
// watch:{
// keyWord:{
// handler:function(newVal){ // 回调函数:将过滤的数组部分赋给filePersons
// this.filFersons = this.persons.filter((p)=>{
// return p.name.indexOf(newVal)!==-1;
// })
// },
// immediate:true
// }
// }
// })
//用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:{
filPersons:{
get(){
return this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord)!==-1;
})
},
set(){
}
}
}
})
</script>
</html>