4.1 条件渲染
--v-show
特点:display占位,并不是完全隐藏
备注:使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到
v-if 是实打实地改变dom元素,v-show 是隐藏或显示dom元素
适用于:切换频率较高的场景
--v-if
特点:不展示的DOM元素直接被移除
适用于:切换频率较低的场景
<h3 v-if="false">欢迎来到{{name1}}</h3>
<!-- display占位,并不是完全隐藏 -->
<h3 v-show="false">欢迎来到{{name2}}</h3>
script>
// 创建 vm 实例对象
const vm = new Vue({
el: '#root',
data: {
name1: '天津',
name2: '青岛'
}
});
</script>
div id="root">
<h2>当前n的值为:{{n}}</h2>
<button @click="n++">点我n+1</button>
<div v-if="n===1">11</div>
<div v-if="n===2">22</div>
<div v-if="n===3">33</div>
</div>
<script>
// 创建 vm 实例对象
const vm = new Vue({
el: '#root',
data: {
n: 0
}
});
</script>
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”
n===1后面就不执行了
<!-- v-else和v-else-if -->
<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> //最后else就不要写条件了
就不需要写好多个判断,写一个就行
这里的思想就像事件代理的使用
4.2 列表渲染
--v-for
加在谁身上就遍历谁
用于展示列表数据
语法:v-for=“(item, index) in xxx” :key=“yyy”
可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
<div id="root">
<!-- *** 1.遍历数组 -->
<h2>人员列表</h2>
<ul>
<!-- p:形参, -->
<!-- <li v-for="p in persons" :key="p.id">{{p.name}}-{{p.age}}</li> -->
<!-- 形参也可以有2个 -->
<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}}-{{index}}
</li>
</ul>
<!-- 2.遍历对象 -->
<h2>汽车信息</h2>
<ul>
<li v-for="(value,k) of car" :key="k">
{{k}}-{{value}}
</li>
</ul>
<!-- 3.遍历字符串 -->
<h2>字符串信息</h2>
<ul>
<li v-for="(char,index) of str" :key="index">
{{char}}-{{index}}
</li>
</ul>
</div>
<script>
// 创建 vm 实例对象
const vm = 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: '70w',
color: '黑色'
},
str: 'hello'
}
});
</script>
--key作用与原理
(1)index作为key
index作为key
若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==> 界面有问题。
(2)id作为key
id作为key
文本框直接拿来复用
结论:
- 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值
- 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的
--列表过滤
<div id="root">
<!-- 遍历数组 -->
<h2>人员列表</h2>
<input type="text" placeholder="请输入姓名" v-model="keyWord">
<ul>
<li v-for="(p,index) of filPersons" :key="index">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
用watch实现
const vm = new Vue({
el: '#root',
data: {
keyWord: '',
persons: [
{ id: '001', name: '马冬梅', age: 19, sex: '女' },
{ id: '002', name: '周冬雨', age: 20, sex: '女' },
{ id: '003', name: '周杰伦', age: 21, sex: '男' },
{ id: '004', name: '温兆伦', age: 22, sex: '男' }
],
filPersons: [
]
},
watch: {
keyWord: {
immediate: true,
handler(val) {
// console.log('keyWord', val)
this.filPersons = this.persons.filter((p) => {
return p.name.indexOf(val) !== -1
})
}
}
}
});
用computed实现
const vm = new Vue({
el: '#root',
data: {
keyWord: '',
persons: [
{ id: '001', name: '马冬梅', age: 19, sex: '女' },
{ id: '002', name: '周冬雨', age: 20, sex: '女' },
{ id: '003', name: '周杰伦', age: 21, sex: '男' },
{ id: '004', name: '温兆伦', age: 22, sex: '男' }
]
},
computed: {
filPersons() {
return this.persons.filter((p) => {
return p.name.indexOf(this.keyWord) !== -1
})
}
}
});
--列表排序
sort排序
<div id="root">
<!-- 遍历数组 -->
<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 filPersons" :key="index">
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
<script>
// 用computed实现
const vm = new Vue({
el: '#root',
data: {
keyWord: '',
sortType: 0, // 0原顺序 1降序 2升序
persons: [
{ id: '001', name: '马冬梅', age: 39, sex: '女' },
{ id: '002', name: '周冬雨', age: 20, sex: '女' },
{ id: '003', name: '周杰伦', age: 41, sex: '男' },
{ id: '004', name: '温兆伦', age: 22, sex: '男' }
]
},
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>
--更新数据的一个bug
控制台上的数据没有发生改变,说明,这个更改的数据并没有被 vue 监测到。
methods: {
updateMei() {
// this.persons[0].name = '马老师'
// this.persons[0].age = 50
// this.persons[0].sex = '男'
this.persons[0] = { id: '001', name: '马老师', age: 50, sex: '男' }
}
},
--vue监测数据
--收集表单数据
<div id="root">
<form @submit.prevent="demo">
<!-- <label for="demo">账号:</label>
<input type="text" id="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="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="music"><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="https://www.baidu.com">用户协议</a><br /><br />
<button>提交</button>
</form>
</div>
<script>
// 创建 vm 实例对象
const vm = new Vue({
el: '#root',
data: {
userInfo: {
account: '',
password: '',
sex: 'female',
hobby: [],
city: '',
other: '',
agree: ''
}
},
methods: {
demo() {
console.log(JSON.stringify(this.userInfo))
}
}
});
</script>
备注: v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤