1. 条件渲染
-
v-if
- v-if=“表达式”
- v-else-if = “表达式”
- v-else = “表达式”
适用于:切换频率较低的场景
特点:不显示dom元素,直接被删除
注意:v-if和v-else-if、v-else一起使用,但要求结构不能被打断
v-if和template一起使用, v-show不可以 -
v-show v-show = “表达式” 适用于: 切换频率较高的场景 特点: 不展示dom元素,未被移除,仅仅是样式隐藏
-
备注:使用v-if时,元素可能无法取到,v-show一定可以获取到
示例:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./vue.js"></script></head><body><div id="app"><!-- v-show: 控制元素style样式中display属性实现显示与隐藏 --><p v-show="1 !== 3">这是v-show文本</p><p v-show="false">这是v-show文本</p><hr><!-- v-if: 对元素的删除与渲染 --><p v-show="1 !== 3">这是v-if文本</p><p v-if="true">这是v-if文本</p><hr><!-- v-if, v-else 的使用 --><button @click="n++">点击if事件</button><!-- <p v-if="n === 1"> 8:00</p><p v-if="n === 1"> 9:00</p><p v-if="n === 3"> 10:00</p> --><p v-if="n === 1"> 8:00</p><p v-else-if="n === 2"> 9:00</p><p v-else-if="n === 3"> 10:00</p><p v-else>其他时间</p><hr><!--v-if可以和 template使用,v-show不可以 --><!-- <p v-if="n === 1"> 小红</p><p v-if="n === 1"> 小李</p><p v-if="n === 1"> 小王</p> --><!-- template模板,不改变页面结构 --><!-- <template v-show="n === 1"> --><template v-if="n === 1"><p> 小红</p><p> 小李</p><p> 小王</p></template> </div><script>const vm = new Vue({el: '#app',data: {n: 0,},})</script></body></html>
2. 列表渲染
- v-for
- 用于展示列表数据
- 语法:v-for=“(val, index) in arr” :key = yyy
- 可遍历:数组,对象,字符串(用的很少),指定次数(用的很少)
示例:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./vue.js"></script></head><body><div id="app"><!-- 遍历数组 --><h2>人员列表</h2><ul><li v-for="(p, index) in persons" :key="index">{{ p.name }} - {{ p.age }}</li></ul><hr><!-- 遍历对象 --><ul><li v-for="(v, index) in obj" :key="index">{{ index }} - {{ v }}</li></ul><hr><!-- 遍历字符串(比较少用) --><ul><li v-for="(v, index) in 'ahggg'" :key="index">{{ index }} - {{ v }}</li></ul><hr><!-- 遍历数字(比较少用) --><ul><li v-for="(v, index) in 5" :key="index">{{ index }} - {{ v }}</li></ul></div><script>const vm = new Vue({el: '#app',data: {persons: [{ id: '001', name: '小红', age: 19 },{ id: '002', name: '小明', age: 20},{ id: '003', name: '小亮', age: 21}],obj: {name: '小丽',age: 19,sex: '女'}}})</script></body></html>
-
key作用与原理
- 虚拟DOM中key的作用:
- key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
- 随后Vue进行【新虚拟DOM】和【旧虚拟DOM】的差异比较,比较规则如下:
- 对比规则:
- 旧虚拟DOM中找到与新虚拟DOM相同的key:
- 若虚拟DOM中的内容没有变,直接使用之前的真实DOM
- 若虚拟DOM中的内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
- 旧虚拟DOM中未找到与新虚拟DOM相同的key:
- 创建新的真实DOM,随后渲染到页面
- 创建新的真实DOM,随后渲染到页面
- 旧虚拟DOM中找到与新虚拟DOM相同的key:
- 虚拟DOM中key的作用:
-
用index作为key可能会引发的问题:
- 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
- 会产生没有必要的真实DOM更新 ==>界面效果没问题,但效率低
- 如果结构中还包含输入类的DOM:
- 会产生错误的DOM更新,页面有问题
- 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
-
开发中如何选择key:
- 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号等唯一值
- 如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表用于展示,使用index作为key是没有问题的
示例:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./vue.js"></script></head><body><div id="app"><!-- 唯一值作为key值: 逆序添加 --><button @click.once="handleClickUnshiftPerson">unshift添加person</button><ul><!-- <li v-for="(p, index) in persons" :key="p.id"> --><li v-for="(p, index) in persons" :key="index">{{ p.name }} - {{p.age }}<input type="text"></li></ul></div><script>const vm = new Vue({el: '#app',data: {persons: [{ id: 1, name: '小红', age: 19 },{ id: 2, name: '小梁', age: 20 },{ id: 3, name: '小名', age: 21 },]},methods: {handleClickUnshiftPerson(){this.persons.unshift({id: 4, name: '小丽', age:22})}},})</script></body></html>
3. 收集表单数据
- 若:
<input type = "text"/>
, 则v-model收集的是value值,用户输入的就是value值。 - 若:
<input type = "radio"/>
, 则v-model收集的是value值,且要给标签配置value值。 - 若:
<input type = "checkbox"/>
- 没有配置input的value属性,v-model收集的就是checked(勾选 or 未勾选, 是布尔值)
- 配置input的value属性:
- v-model 的初始值是非数组,那么收集的就是checked(勾选 or 未勾选, 是布尔值)
- v-model 的初始值是数组,那么收集的就是value组成的数组
- 备注:v-model的三个修饰符:
- lazy: 失去焦点再收集数据
- number: 输入字符串转为有效的数字
- trim: 输入首尾空格过滤
示例:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="./vue.js"></script></head><body><div id="app"><form @submit.prevent="demo"><!-- 完整写法 --><!-- <label for="demo">账号:</label> --><!-- <input type="text" id="demo"> -->账号:<input type="text" v-model.trim="obj.account">1{{ obj.account }}2<br><br>密码:<input type="password" v-model="obj.password"> {{ obj.password }}<br><br>年龄:<input type="number" v-model.number="obj.age"> {{ typeof(obj.age) }}<br><br>性别:男<input type="radio" name="sex" v-model="obj.sex" value="male">女<input type="radio" name="sex" v-model="obj.sex" value="female">{{ obj.sex }}<br><br>爱好:<!-- 多选框的初始值影响v-model收集回来的值 -->学习<input type="checkbox" v-model="obj.hobby" value="study" id="demo">打游戏<input type="checkbox" v-model="obj.hobby" value="game">读书<input type="checkbox" v-model="obj.hobby" value="read">{{ obj.hobby }}<br><br>家乡:<select v-model="obj.city"><option value="">请选择家乡</option><option value="sjz">石家庄</option><option value="xt">邢台</option><option value="hd">邯郸</option><option value="cd">承德</option></select>{{ obj.city }}<br><br>其他信息:<textarea v-model.lazy="obj.other"></textarea> {{ obj.other }}<br><br><input v-model="obj.argee" type="checkbox"> 阅读并接受<a href="http://www.baidu.com">《用户协议》</a> {{ obj.argee }}<br><br><button>提交</button></form></div><script>const vm = new Vue({el: "#app",data:{obj:{account: '',password: '',age: 18,sex: 'female',hobby: [],city:'',other: '',argee: false}},methods: {demo(){console.log(this.obj);}},})</script></body></html>