这是我参与「第四届青训营 」笔记创作活动的第4天
十一、绑定样式
1、绑定class样式
:class="xxx" xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
数组写法适用于:要绑定多个样式,个数不确定,名字也不确定。
对象写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
2、绑定style样式
对象写法 :style="{fontSize: xxx}" 或 :style="styleObj" 其中xxx是动态值。
数组写法 :style="[a,b]" 其中a、b是样式对象。
十二、条件渲染
条件渲染:
1、v-if
(1)v-if="表达式"
(2)v-else-if="表达式"
(3)v-else="表达式"
适用于:切换频率较低的场景
特点:不展示的DOM元素直接被移除
注意:v-if可以和v-else-if、v-else一起使用,但要求结构不能被打断
2、v-show v-show="表达式"
适用于:切换频率较高的场景
特点:不展示的DOM元素未被移除,仅仅是隐藏使用样式
3、备注 使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到元素。
十三、列表渲染
1、基本列表
v-for指令
1、用于展示列表数据
2、语法 v-for="(item,index) in xxx" :key="yyy"
3、可遍历:数组(常用)、对象(常用)、字符串、指定次数
<!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>
<!-- 引入vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="root">
<!-- 遍历数组 -->
<h2>人员列表</h2>
<ul>
<li v-for="p in personArr" :key="p.id">
<!-- <li v-for="(p,index) in personArr" :key="index"> -->
{{p.name}}-{{p.age}}
</li>
</ul>
<!-- 遍历对象 -->
<h2>汽车信息</h2>
<ul>
<li v-for="(value,key) in car" :key="key">
{{key}}-{{value}}
</li>
</ul>
<!-- 遍历字符串 -->
<h2>测试遍历字符串</h2>
<ul>
<li v-for="(char,index) in str" :key="index">
{{index}}-{{char}}
</li>
</ul>
<!-- 遍历指定次数 -->
<h2>测试遍历指定次数</h2>
<ul>
<li v-for="(number,index) in 5" :key="index">
{{index}}-{{number}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false // 阻止vue在启动时生成生产提示
new Vue({
el:'#root',
data:{
personArr:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:20},
{id:'003',name:'王五',age:19},
],
car:{
name:'兰博基尼',
pirce:'20元',
coler:'白色',
},
str:'hello'
}
})
</script>
</html>
2、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,随后渲染到到页面
3、用index作为key可能会引发的问题:
(1)若对数据进行:逆序添加、逆序删除等破坏顺序操作: 会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低
(2)如果结构中还包含输入类的DOM: 会产生错误DOM更新 ==> 界面有问题
4、开发中如何选择key?
(1)最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值
(2)如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用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>
<!-- 引入vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="root">
<!-- 遍历数组 -->
<h2>人员列表</h2>
<button @click.once="add">添加一个老刘</button>
<ul>
<li v-for="p in personArr" :key="p.id">
<!-- <li v-for="(p,index) in personArr" :key="index"> -->
{{p.name}}-{{p.age}}
<input>
</li>
</ul>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false // 阻止vue在启动时生成生产提示
new Vue({
el:'#root',
data:{
personArr:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:20},
{id:'003',name:'王五',age:19},
]
},
methods: {
add(){
const p = {id:'004',name:'老刘',age:'200'}
this.personArr.unshift(p) // 添加到原数组最上方
}
},
})
</script>
</html>
3、列表过滤
以下为使用监视和计算属性实现的两种方法:
<!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>
<!-- 引入vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="root">
<h2>人员列表</h2>
<input type="text" placeholder="请输入名字" v-model="keyWord">
<ul>
<li v-for="p in filPersonArr" :key="p.id">
<!-- <li v-for="(p,index) in personArr" :key="index"> -->
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false // 阻止vue在启动时生成生产提示
new Vue({
el:'#root',
data:{
keyWord:'',
personArr:[
{id:'001',name:'马冬梅',age:18,sex:'女'},
{id:'002',name:'周冬雨',age:20,sex:'女'},
{id:'003',name:'周杰伦',age:19,sex:'男'},
{id:'004',name:'温兆伦',age:13,sex:'男'},
],
// filPersonArr:[]
},
// watch:{
// keyWord:{
// immediate:true,
// handler(value){
// this.filPersonArr = this.personArr.filter((p)=>{ // filter()方法创建一个新的数组,新数组中元素是通过检查指定数组中符合条件的元素,原数组不受影响
// return p.name.indexOf(value) !== -1 // .indexOf('')返回值是0
// })
// }
// }
// }
computed:{
filPersonArr(){
return this.personArr.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1
})
}
}
})
</script>
</html>
4、列表排序
<!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>
<!-- 引入vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<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 in filPersonArr" :key="p.id">
<!-- <li v-for="(p,index) in personArr" :key="index"> -->
{{p.name}}-{{p.age}}-{{p.sex}}
</li>
</ul>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false // 阻止vue在启动时生成生产提示
new Vue({
el:'#root',
data:{
keyWord:'',
sortType:0, // 0是原顺序,1是降序,2是升序
personArr:[
{id:'001',name:'马冬梅',age:18,sex:'女'},
{id:'002',name:'周冬雨',age:20,sex:'女'},
{id:'003',name:'周杰伦',age:19,sex:'男'},
{id:'004',name:'温兆伦',age:13,sex:'男'},
],
},
computed:{
filPersonArr(){
const arr = this.personArr.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1
})
// 判断是否需要排序
if(this.sortType){
arr.sort((p1,p2)=>{ // .sort((a,b)=>{}) a-b是升序排列,b-a是降序排列
return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
})
}
return arr
}
}
})
</script>
</html>
十四、收集表单数据
收集表单数据:
若:,则v-model收集的是value值,用户输入的就是value值。
若:,则v-model收集的是value值,且要给标签配置value值。
若:
1、没有配置input的value属性,那么收集的就是checked(勾选or未勾选,是布尔值)
2、配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or未勾选,是布尔值)
(2)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>
<!-- 引入vue -->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="root">
<form @submit.prevent="demo">
账号:<input type="text" v-model="userInfo.account"> <br/><br/>
密码:<input type="password" v-model="userInfo.password"> <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="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>
</body>
<script type="text/javascript">
Vue.config.productionTip = false // 阻止vue在启动时生成生产提示
new Vue({
el:'#root',
data:{
userInfo:{
account:'',
password:'',
sex:'male',
hobby:[],
city:'beijing',
other:'',
agree:'',
}
},
methods: {
demo(){
console.log(JSON,stringify(this.userInfo))
}
},
})
</script>
</html>
本篇总结:
这篇笔记的主要内容是介绍Vue内,绑定样式、条件渲染、列表渲染、收集表单数据这四方面内容的概括和实践。
- 绑定样式分为绑定class样式和绑定style样式,注意区分两者的作用
- 条件渲染中主要掌握v-if和v-show的区别与使用方法,使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到元素
- 列表渲染中掌握v-for指令,尤其要理解key的原理,作为补充掌握列表排序和列表过滤的两种方法
- 收集表单数据作为一个简单的小例子,在实践中理解知识
今天也是有收获的一天~