条件渲染
-
v-if
- 写法:
- v-if="表达式"
- v-else-if="表达式"
- v-else="表达式"
- 适用于:切换频率较低的场景
- 特点:不展示的DOM元素直接被移除
- 注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被"打断"
- 写法:
-
v-show
- 写法:v-show="表达式"
- 适用于:切换频率较高的场景
- 特点:不展示DOM元素未被移除,仅仅是使用样式隐藏掉
- 备注:使用v-if的时候,元素可能无法获取到,而使用v-show一定要获取到
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>条件渲染</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="app">
<h2>当前的n值是:{{n}}</h2>
<button @click="n++">点我n+1</button>
<!-- 使用v-show做条件渲染 -->
<h2 v-show:"false">欢迎来到{{name}}</h2>
<h2 v-show:"1 === 1">欢迎来到{{name}}</h2>
<!-- 使用v-if做条件渲染 -->
<h2 v-if:"false">欢迎来到{{name}}</h2>
<h2 v-if:"1 === 1">欢迎来到{{name}}</h2>
<!-- v-else和v-else-if -->
<div v-if="n===1">大理</div>
<div v-else-if="n===2">厦门</div>
<!-- <div>@</div> 不允许被打断 -->
<div v-else-if="n===3">台湾</div>
<div v-else>台湾</div>
<!-- v-if与template的配合使用 template只是一个模板结构不会解析到画面中-->
<!-- v-show不可以和template的配合使用 -->
<template v-if="n===1">
<h2>你好</h2>
<h2>同福客栈</h2>
<h2>武林外传</h2>
</template>
</div>
</body>
<script type = "text/javascript">
Vue.config.productionTip = false
// 创建Vue实例
const vm = new Vue({
el: '#app',
data:{
name:'武林外传'
},
</script>
</html>
列表渲染
-
v-for指令
- 用于展示列表数据
- 语法:v-for="(item, index) in xxx" :key="yyy"
- 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>条件渲染</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="app">
<!-- 遍历数组 -->
<ul>
<li>xxx-xxx</li>
<li>xxx-xxx</li>
<li>xxx-xxx</li>
<h2>人员列表</h2>
<li>姓名-年龄</li>
<!-- :key="表达式"使每一个li节点都动态绑定一个唯一标识 -->
<!-- key="1"生成的li标识都是1 -->
<li v-for="p in persons" :key="p.id">
<!-- 插值语法 p还可以来自属性 -->
{{p.name}}-{{p.age}}
</li>
<li v-for="(a,b,c) in persons" :key="p.id">
<!-- 输出的分辨是item(遍历的每一项)---索引值(数组里的第几个0开始)---undefined -->
{{a}---{{b}}---{{c}}
<!-- {id:'001',name:'张三',age:18}---0--- -->
</li>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}}
</li>
<li v-for="(p,index) of persons" :key="index">
{{p.name}}-{{p.age}}
</li>
</ul>
<!-- 遍历对象 -->
<h2>汽车信息</h2>
<ul>
<li v-for="(value, k) in car" :key="k">
{{value}}-{{k}}
</li>
<!--
奥迪A8-name
70万-price
黑色-color
-->
</ul>
<!-- 遍历字符串 -->
<h2>测试遍历字符串</h2>
<ul>
<li v-for="(char, index) in str" :key="index">
{{char}}-{{index}}
</li>
<!--
h-0
e-1
y-2
-->
</ul>
<!-- 遍历指定次数 -->
<h2>测试遍历指定次数(用得少)</h2>
<ul>
<li v-for="(number, index) in 3" :key="index">
{{number}}-{{index}}
</li>
<!--
1-0
2-1
3-2
-->
</ul>
</div>
</body>
<script type = "text/javascript">
Vue.config.productionTip = false
// 创建Vue实例
const vm = new Vue({
el: '#app',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:20}
],
car:{
name:'奥迪A8',
price:'70万',
color:'黑'
},
str:'hey'
},
</script>
</html>
key作用与原理
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>条件渲染</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="app">
<!-- 遍历数组 -->
<h2>人员列表(遍历数组)</h2>
<button @click.once='add'>添加一个人</button>
<ul>
<li v-for="(p,index) of persons" :key="index">
{{p.name}}-{{p.age}}
</li>
</ul>
</div>
</body>
<script type = "text/javascript">
Vue.config.productionTip = false
// 创建Vue实例
const vm = new Vue({
el: '#app',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:20}
]
},
method:{
add(){
const p = {id:'004',name:'赵六',age:40}
// 数组的最前面加一个数组p
this.persons.unshift(p)
}
}
</script>
</html>
遍历列表时key的作用(index作为key)
遍历列表时key的作用(数据唯一标识id作为key)
总结
面试题: 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,随后渲染到到页面。
- (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
- 3.用index作 为key可能会引发的问题:
- 1.若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
- 2.如果结构中还包含输入类的DOM:
- 会产生错误DOM更新==>界面有问题。
- 4.开发中如何选择key?:
- 1.最好使用每条数据的唯一标识作为key,比如id、 手机号、身份证号、学号等唯一值。
- 2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
列表过滤
用监视属性watch实现
ps:#region #endregion可以折叠代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>条件渲染</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="app">
<h2>人员列表</h2>
<!-- 收集用户输入 -->
<input type="text" placeholder="请输入名字" v-model="keyWord"/>
<ul>
<li v-for="(p,index) of filPerons" :key="index">
{{p.name}}-{{p.age}}
</li>
</ul>
</div>
</body>
<script type = "text/javascript">
Vue.config.productionTip = false
// 创建Vue实例
const 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:'男'}
],
filPerons:[]
},
watch:{
// 输入框value值改变时触发
keyWord:{
immediate:true,//初始化时让handler调用一下 即:handler('')
handler(val){
console.log('keyWord被改了', val)
// 过滤数据-不会影响原数据,而是返回一个全新的数组数据
// 只有将新数组重新赋值给persons才可以变化 但是过滤的数据真的不见了
// 赋值给filPerons并遍历filPerons
this.filPerons= this.persons.filter((p)=>{
// indexOf是否包含某字符串 不包含返回-1 包含则返回所在位置(0开始)
// indexOf('')indexOf一个空字符串会返回0而不是-1
retuen p.name.indexOf(val) !== -1
})
}
}
}
})
</script>
</html>
用计算属性computer实现
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>条件渲染</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="app">
<h2>人员列表</h2>
<!-- 收集用户输入 -->
<input type="text" placeholder="请输入名字" v-model="keyWord"/>
<ul>
<li v-for="(p,index) of filPerons" :key="index">
{{p.name}}-{{p.age}}
</li>
</ul>
</div>
</body>
<script type = "text/javascript">
Vue.config.productionTip = false
// 创建Vue实例
const 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:'男'}
]
},
computed:{
filPerons(){
// 计算属性的return即filPerons的结果
return this.persons.filter((p)=>{
// filter的返回值 过滤的结果数组
retuen p.name.indexOf(this.keyWord) !== -1
})
}
}
})
</script>
</html>
列表排序
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>条件渲染</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="app">
<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}}
</li>
</ul>
</div>
</body>
<script type = "text/javascript">
Vue.config.productionTip = false
// 创建Vue实例
const vm = new Vue({
el: '#app',
data:{
keyWord:'',
sortType:0,//0原顺序 1降序 2升序
//原数据
persons:[
{id:'001',name:'马冬梅',age:30,sex:'女'},
{id:'002',name:'周冬雨',age:18,sex:'女'},
{id:'003',name:'周杰伦',age:29,sex:'男'},
{id:'004',name:'温兆伦',age:21,sex:'男'}
]
},
// 只要计算属性中任何一个属性发生变化 计算属性都会重新计算
computed:{
filPerons(){
// 过滤结果数组
const arr = this.persons.filter((p)=>{
// filter的返回值 过滤的结果数组
retuen p.name.indexOf(this.keyWord) !== -1
})
// 判断一下是否需要排序
// 只要不是0转成bool型就是1
if(this.sortType){
// 排序会收到两个数据项sort(前项,后项)会改变原数组
// 升序:前项-后项;降序:后项-前项
arr.sort((p1,p2)=>{
return this.sortType === 1? p2.age-p1.age:p1.age-p2.age
})
}
// filPerons的结果
return arr
}
}
})
</script>
</html>
更多推荐
【VUE】遍历列表
发布评论