Vue基础(下):条件渲染列表渲染(key)过滤器内置和自定义指令

Posted 永远没有404

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue基础(下):条件渲染列表渲染(key)过滤器内置和自定义指令相关的知识,希望对你有一定的参考价值。

欢迎学习交流!!!
持续更新中…

有关Vue基础请查看:


1. 条件渲染

1、v-ifv-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-ifv-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-iftemplate配合使用可以不改变页面元素

<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的比较

  1. 如果需要频繁切换,则使用v-show更好
  2. 当条件不成立时,v-if的所有子节点不会解析(项目中使用)

2. 列表渲染

基本列表

v-for指令:

  1. 用于展示列表数据
  2. 语法:v-for="(item, index) in xxx" :key="yyy"
  3. 可遍历:数组(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 | 过滤器名"

注意

  1. 过滤器也可以接收额外参数、多个过滤器也可以串联
  2. 并没有改变原本的数据, 是产生新的对应的数据
<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)过滤器内置和自定义指令的主要内容,如果未能解决你的问题,请参考以下文章

vue06 基础-列表渲染

Vue条件列表渲染

Vue -- 列表渲染(基本列表 & key的原理 & 列表过滤 & 列表排序 )

Vue条件渲染及列表渲染

Vue条件渲染及列表渲染

Vue学习计划(基础三)-class与style绑定,条件渲染和列表渲染