v-for指令
- 用于展示列表数据
- 语法:v-for="(item,index) in xxx" :key="yyy"
- 可遍历数组、对象、字符串(使用较少)、指定次数(使用极少)
<div id="app">
<h3>人员列表(遍历数组)</h3>
<ul>
<li v-for="(p,i) in persons" :key="i">{{p.name}}-{{p.age}}</li>
</ul>
<h3>人员张三(遍历对象)</h3>
<ul>
<li v-for="(item,index) in per" :key="index">{{index}}:{{item}}</li>
</ul>
<h3>测试(遍历字符串,使用较少)</h3>
<ul>
<li v-for="(char,index) in str" :key="index">{{index}}-{{char}}</li>
</ul>
<h3>测试(遍历指定次数,使用较少)</h3>
<ul>
<li v-for="(i,index) of 5" :key="index">{{index}}-{{i}}</li>
</ul>
</div>
<script>
Vue.config.productionTip = false;
var vm = new Vue({
el: "#app",
data: {
persons: [
{ id: "001", name: "张三", age: 18 },
{ id: "002", name: "李四", age: 19 },
{ id: "003", name: "王五", age: 20 },
],
per: { name: "张三", add: "上海", friend: "李四" },
str: "hello",
}
});
</script>
key的作用与原理
- 虚拟DOM中key的作用
- key是虚拟DOM对象的标识,当状态中的数据发生变化时,vue会根据“新数据”生成“新虚拟DOM”,随后vue会将“新虚拟DOM”与“初始虚拟DOM”进行差异比较,其规则如下
- 对比规则
- 初始虚拟DOM中找到与新虚拟DOM相同的key
- 若虚拟DOM中内容没变,直接使用之前的真实DOM
- 若虚拟DOM中内容发生变化,则生成新的真实DOM,随后替换掉页面中原有的真实DOM
- 初始虚拟DOM中未找到与新虚拟DOM相同的key
- 使用index作为key可能会引发的问题
- 若对数据进行逆序添加、逆序删除等破坏操作,会产生没有必要的真实DOM操作==>界面效果没问题,但降低效率
- 若其中还包含输入类型DOM,则会禅城错误DOM==>界面出现问题
- 开发中如何选择key
- 最好使用每条数据的唯一标识符作为key,如:id、手机号、身份证号、学号等
- 若不存在对数据的逆序破坏性操作,仅用于渲染列表用于展示,使用index作为key是没有问题的
列表过滤(模糊搜索)
计算属性实现
<div id="app">
<h3>人员列表</h3>
<input type="text" placeholder="请输入名字" v-model="keyWord" />
<ul>
<li v-for="(p,i) in filPersons" :key="p.id">
{{p.name}}-{{p.age}}--{{p.sex}}
</li>
</ul>
</div>
<script>
Vue.config.productionTip = false;
var vm = new Vue({
el: "#app",
data: {
keyWord: "",
persons: [
{ id: "001", name: "张三", age: 18, sex: "女" },
{ id: "002", name: "张四", age: 19, sex: "女" },
{ id: "003", name: "李二", age: 20, sex: "男" },
{ id: "004", name: "李三", age: 21, sex: "女" },
{ id: "005", name: "王二", age: 20, sex: "男" },
{ id: "006", name: "王四", age: 22, sex: "男" },
],
},
computed:{
filPersons(){
return this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord)!==-1
})
}
}
});
侦听属性实现
<div id="app">
<h3>人员列表</h3>
<input type="text" placeholder="请输入名字" v-model="keyWord" />
<ul>
<li v-for="(p,i) in filPersons" :key="p.id">
{{p.name}}-{{p.age}}--{{p.sex}}
</li>
</ul>
</div>
<script>
Vue.config.productionTip = false;
var vm = new Vue({
el: "#app",
data: {
keyWord: "",
persons: [
{ id: "001", name: "张三", age: 18, sex: "女" },
{ id: "002", name: "张四", age: 19, sex: "女" },
{ id: "003", name: "李二", age: 20, sex: "男" },
{ id: "004", name: "李三", age: 21, sex: "女" },
{ id: "005", name: "王二", age: 20, sex: "男" },
{ id: "006", name: "王四", age: 22, sex: "男" },
],
filPersons: [],
},
// 用侦听属性实现
watch: {
keyWord: {
immediate: true,
handler(val) {
this.filPersons = this.persons.filter((p) => {
return p.name.indexOf(val) != -1;
});
},
},
},
});
</script>