Vue基础(下):条件渲染列表渲染(key)过滤器内置和自定义指令
Posted 永远没有404
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue基础(下):条件渲染列表渲染(key)过滤器内置和自定义指令相关的知识,希望对你有一定的参考价值。
欢迎学习交流!!!
持续更新中…
有关Vue基础请查看:
1. 条件渲染
1、
v-if
和v-else
写法:
v-if="表达式"
v-else-if="表达式"
v-else="表达式"
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除,即DOM结构改变。
<h2 v-if="false">欢迎来到name</h2>
<h2 v-if="1 === 1">欢迎来到name</h2>
注意:
v-if
可以和v-else-if
、v-else
一起使用,但要求结构不能被“打断”。(即这几个使用的时候必须连在一起,中间不能插入其余 div 等结构)
<div v-if="n === 1">Angular</div>
<div v-else-if="n === 2">React</div>
<div v-else-if="n === 3">Vue</div>
<div v-else>哈哈</div>
2、
v-show
写法:v-show="表达式"
适用于:切换频率较高的场景
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉,但是结构未改变,即display: none
<h2 v-show="false">欢迎来到name</h2>
<h2 v-show="1 === 1">欢迎来到name</h2>
浏览器解析后:
3、备注:使用v-if
的时,元素可能无法获取到,而使用v-show
一定可以获取到。
4、v-if
与template
配合使用可以不改变页面元素
<div v-if="n === 1">
<h2>你好</h2>
<h2>中国</h2>
<h2>北京</h2>
</div>
<!-- 使用template后结构未改变: -->
<template v-if="n === 1">
<h2>你好</h2>
<h2>中国</h2>
<h2>北京</h2>
</template>
v-if与v-show的比较
- 如果需要频繁切换,则使用v-show更好
- 当条件不成立时,v-if的所有子节点不会解析(项目中使用)
2. 列表渲染
基本列表
v-for
指令:
- 用于展示列表数据
- 语法:
v-for="(item, index) in xxx" :key="yyy"
- 可遍历:数组(v-for/index)、对象(v-for/key)、字符串(用的很少)、指定次数(用的很少)
<div>
<!-- 遍历数组 -->
<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>
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'
)
key的作用与原理
1、虚拟DOM中key的作用:
- key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
- 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2、对比规则:
-
旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变, 直接使用之前的真实DOM ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
-
旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。
3、用index作为key可能会引发的问题:
-
若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。 -
如果结构中还包含输入类的DOM(如input框中包含有数据):
会产生错误DOM更新 ==> 界面有问题。
4、开发中如何选择key?
- 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
- 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
数据监测
Vue监视数据的原理:
1、vue会监视data中所有层次的数据。
2、 如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
- 对象中后追加的属性,Vue默认不做响应式处理
- 如需给后添加的属性做响应式,请使用如下API:
Vue.set(target,propertyName/index,value)
或
vm.$set(target,propertyName/index,value)
3、 如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
- 调用原生对应的方法对数组进行更新。
- 重新解析模板,进而更新页面。
4、在Vue修改数组中的某个元素一定要用如下方法:
- 使用这些API:
push()
、pop()
、shift()
、unshift()
、splice()
、sort()
、reverse()
Vue.set()
或vm.$set()
5、特别注意:Vue.set()
和 vm.$set()
不能给vm 或 vm的根数据对象添加属性(即直接给data中添加属性)
<div id="root">
<h1>学生信息</h1>
<button @click="student.age++">年龄+1岁</button> <br/>
<button @click="addSex">添加性别属性,默认值:男</button> <br/>
<button @click="student.sex = '未知' ">修改性别</button> <br/>
<button @click="addFriend">在列表首位添加一个朋友</button> <br/>
<button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br/>
<button @click="addHobby">添加一个爱好</button> <br/>
<button @click="updateHobby">修改第一个爱好为:开车</button> <br/>
<button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br/>
<h3>姓名:student.name</h3>
<h3>年龄:student.age</h3>
<h3 v-if="student.sex">性别:student.sex</h3>
<h3>爱好:</h3>
<ul>
<li v-for="(h,index) in student.hobby" :key="index">
h
</li>
</ul>
<h3>朋友们:</h3>
<ul>
<li v-for="(f,index) in student.friends" :key="index">
f.name--f.age
</li>
</ul>
</div>
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
const vm = new Vue(
el:'#root',
data:
student:
name:'tom',
age:18,
hobby:['抽烟','喝酒','烫头'],
friends:[
name:'jerry',age:35,
name:'tony',age:36
]
,
methods:
addSex()
// Vue.set(this.student,'sex','男')
this.$set(this.student,'sex','男')
,
addFriend()
this.student.friends.unshift(name:'jack',age:70)
,
updateFirstFriendName()
this.student.friends[0].name = '张三'
,
addHobby()
this.student.hobby.push('学习')
,
updateHobby()
// this.student.hobby.splice(0,1,'开车')
// Vue.set(this.student.hobby,0,'开车')
this.$set(this.student.hobby,0,'开车')
,
removeSmoke()
this.student.hobby = this.student.hobby.filter((h)=>
return h !== '抽烟'
)
)
收集表单数据
1、若:<input type="text"/>
,则v-model收集的是value值,用户输入的就是value值。
2、若:<input type="radio"/>
,则v-model收集的是value值,且要给标签配置value值。
3、若:<input type="checkbox"/>
- 没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
- 配置input的value属性:
v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
v-model的初始值是数组,那么收集的的就是value组成的数组
4、备注:v-model的三个修饰符:
修饰符 | 说明 |
---|---|
lazy | 失去焦点再收集数据 |
number | 输入字符串转为有效的数字 |
trim | 输入首尾空格过滤 |
<div id="root">
<form @submit.prevent="demo">
账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
密码:<input type="password" v-model="userInfo.password"> <br/><br/>
年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
性别:
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
爱好:
学习<input type="checkbox" v-model="userInfo.hobby" value="study">
打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
<br/><br/>
所属城市
<select v-model="userInfo.city">
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武汉</option>
</select>
<br/><br/>
其他信息:
<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
<input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》</a>
<button>提交</button>
</form>
</div>
Vue.config.productionTip = false
new Vue(
el:'#root',
data:
userInfo:
account:'',
password:'',
age:18,
sex:'female',
hobby:[],
city:'beijing',
other:'',
agree:''
,
methods:
demo()
console.log(JSON.stringify(this.userInfo))
)
3. 过滤器
功能:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
注意:并没有改变原本的数据,是产生新的对应的数据
语法:
过滤器 | 语法 |
---|---|
注册过滤器 | Vue.filter(name,callback) 或 new Vuefilters: |
使用过滤器 | xxx | 过滤器名 或 v-bind:属性 = "xxx | 过滤器名" |
注意:
- 过滤器也可以接收额外参数、多个过滤器也可以串联
- 并没有改变原本的数据, 是产生新的对应的数据
<div id="root">
<h2>显示格式化后的时间</h2>
<!-- 计算属性实现 -->
<h3>现在是:fmtTime</h3>
<!-- methods实现 -->
<h3>现在是:getFmtTime()</h3>
<!-- 过滤器实现 -->
<h3>现在是:time | timeFormater</h3>
<!-- 过滤器实现(传参) -->
<h3>现在是:time | timeFormater('YYYY_MM_DD') | mySlice</h3>
以上是关于Vue基础(下):条件渲染列表渲染(key)过滤器内置和自定义指令的主要内容,如果未能解决你的问题,请参考以下文章