3.4 条件渲染:
1.v-if :
写法:
v-if;
v-else-if;
v-else;
适用于切换频率较低的场景。
特点:不展示的dom元素直接删除。
注意:v-if与v-else-if,v-else可以一起使用,但是要求结构不能被打断,即必须连续的使用。
2.v-show:
写法:
v-show;
适用于:切换频率较高的场景;
特点:不展示的dom元素不删除,而是使用display:none来隐藏;
3.备注:
使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到,因为v-show只是隐藏,元素还是存在的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="../js/vue.js" type="text/javascript"></script>
<title>条件渲染</title>
</head>
<body>
<div class="root">
<!-- show or hide 3 choose-->
<h1 v-show="a">welcome study {{name}} 1</h1>
<h1 v-show="true">welcome study {{name}} 2</h1>
<h1 v-show="1 === 1">welcome study {{name}} 3</h1>
<h1 v-if="false">welcome study {{name}} 4</h1>
<h2>n = {{n}}</h2>
<button @click="addn">click to add n</button>
<div v-show="n === 1">Jsp</div>
<div v-show="n === 2">Angular</div>
<div v-show="n === 3">Vue</div>
<!-- v-if v-else v-else-if -->
<div v-if="n === 1">Jsp</div>
<div v-else-if="n === 2">Angular</div>
<div v-else-if="n === 3">Vue</div>
<div v-else>default</div>
<!-- v-if与template的配合使用 -->
<template v-if=" n === 1">
<h2>aa</h2>
<h2>bb</h2>
<h2>cc</h2>
</template>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
//Vue instance
const x = new Vue({
// el:document.getElementById('root') the same
el:".root",
data:{
name:'Vue2',
a:true,
n:0,
},
methods:{
addn(){
this.n++;
}
}
})
</script>
</body>
</html>
3.5 列表渲染:
v-for:
1.可以使用v-for指令展示列表数据
2.语法:v-for="(item,index) in xxx" :key=“yyy”
3.可遍历:数组,对象,字符串,指定次数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="../js/vue.js" type="text/javascript"></script>
<title>列表渲染</title>
</head>
<body>
<div class="root">
<ul>
<!-- <li v-for="person in persons" :key="person.id">-->
<!-- <li v-for="(p,index) in persons" :key="p.id">-->
<!-- Array-->
<li v-for="(p,index) of persons" :key="p.id">
Name:{{p.name}}, Age:{{p.age}}, index:{{index}}
</li>
<!-- object-->
<li v-for="(key,value) of car">
{{key}}---{{value}}
</li>
<!-- string-->
<li v-for="(char,index) in str">
{{char}}---{{index}}
</li>
<!-- 指定次数-->
<li v-for="(num,index) in 5">
{{num}}---{{index}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
//Vue instance
const vm = new Vue({
// el:document.getElementById('root') the same
el:".root",
data:{
persons:[
{id:'001',name:'Aqorid',age:18},
{id:'002',name:'Sam',age:19},
{id:'003',name:'Joy',age:20},
],
car:{
name:'otto',
price:'70w',
},
str:'hello'
}
})
</script>
</body>
</html>
key的相关问题:
Vue中key的作用:
1.key在虚拟dom中的作用:
key是虚拟dom对象的标识,当状态中的数据发生变化时,Vue会根据「新数据」生成「新的虚拟DOM」;
随后Vue进行「新虚拟DOM」与「旧虚拟DOM」的差异比较。
2.比较规则:
(1)旧虚拟DOM中找到了和新虚拟DOM相同的KEY:
a:若虚拟DOM内容没变,则直接使用之前的虚拟DOM;
b:若虚拟DOM内容改变,则生成新的真实DOM,随后替换掉页面之前的真实DOM;
(2)旧虚拟DOM中为找到与新虚拟DOM相同的KEY:
创建新的真实DOM,并渲染到页面;
3.用index作为key可能会出现的问题:
1.若对数据进行「逆序添加」,「逆序删除」等操作:
会产生没有必要的真实DOM更新,效率极低;
2.若结构中还包含输入类的DOM:
会产生错误DOM更新,界面出现问题。
4.如何选择key:
(1)最好是使用每条数据的唯一标识作为key,如:id,telephone等;
(2)如果不存在「逆序添加」,「逆序删除」等操作,仅用于渲染列表用于展示,使用index作为key是没有问题的;
列表过滤:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="../js/vue.js" type="text/javascript"></script>
<title>列表过滤</title>
</head>
<body>
<div class="root">
<input type="text" v-model:value="keyWord">
<ul>
<li v-for="(p,index) of filPersons" :key="p.id">
{{p.name}}--{{p.age}}--{{p.sex}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
/**
* watch filter
*/
// const vm = new Vue({
// // el:document.getElementById('root') the same
// el:".root",
// data:{
// 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:'男'},
// ],
// keyWord:'',
// filPersons:[],
// },
// watch:{
// keyWord: {
// immediate:true,
// handler(newValue){
// this.filPersons = this.persons.filter((p)=>{
/**
*如果indexof的返回值不为-1,则说明name包含newValue
*/
// return p.name.indexOf(newValue) !== -1;
// })
// }
// }
// }
// })
/**
* computed filter
*/
new Vue({
el:'.root',
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:'男'},
],
},
computed:{
filPersons(){
return this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1
})
}
}
})
</script>
</body>
</html>
列表排序:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="../js/vue.js" type="text/javascript"></script>
<title>列表过滤</title>
</head>
<body>
<div class="root">
<input type="text" v-model:value="keyWord" placeholder="input the name">
<button @click="sortType = 2">年龄升序</button>
<button @click="sortType = 1">年龄降序</button>
<button @click="sortType = 0">原顺序</button>
<ul>
<li v-for="(p,index) of filPersons" :key="p.id">
{{p.name}}--{{p.age}}--{{p.sex}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false
/**
* watch filter
*/
// const vm = new Vue({
// // el:document.getElementById('root') the same
// el:".root",
// data:{
// 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:'男'},
// ],
// keyWord:'',
// filPersons:[],
// },
// watch:{
// keyWord: {
// immediate:true,
// handler(newValue){
// this.filPersons = this.persons.filter((p)=>{
/**
*如果indexof的返回值不为-1,则说明name包含newValue
*/
// return p.name.indexOf(newValue) !== -1;
// })
// }
// }
// }
// })
/**
* computed filter
*/
new Vue({
el:'.root',
data:{
keyWord:[],
persons:[
{id:'001',name:'马东美',age:22,sex:'女'},
{id:'002',name:'周东雨',age:19,sex:'女'},
{id:'003',name:'周结伦',age:18,sex:'男'},
{id:'004',name:'纹子伦',age:21,sex:'男'},
],
sortType:0, //0 原顺序 1 年龄降序 2 年龄升序
},
computed:{
filPersons(){
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>
</body>
</html>