绑定样式
<!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>绑定css样式</title>
<script src="../js/vue.js"></script>
<style>
#root {
margin: 0 auto;
}
.box {
width: 400px;
height: 400px;
margin: 20px 0;
background-color: darkcyan;
}
.bor {
border: 1px solid darkorange;
border-radius: 20px;
}
.font {
line-height: 400px;
font-size: 28px;
color: white;
text-align: center;
}
.back {
background-color: darksalmon;
border-radius: 40px;
}
</style>
</head>
<body>
<div id="root">
<!-- 绑定class样式——字符串写法,适用于:样式的类名不确定,需要动态指定 -->
<div class="box" :class="theme">
方式一
</div>
<button @click="changed">切换样式</button>
<!-- 绑定class样式——数组写法,适用于:要绑定的样式个数不确定,名字也不确定 -->
<div class="box" :class="arr[1]">
方式二
</div>
<!-- <button @click="changedArr">切换css</button> -->
<!-- 绑定class样式——对象写法,适用于:要绑定的样式个数确定,名字也确定,但是要动态决定用不用 -->
<div class="box" :class="classObj">
方式三
</div>
<!-- 绑定style样式——对象 -->
<div class="box" :style="styleObj1">
方式四
</div>
<!-- 绑定style样式——数组 -->
<!-- <div class="box" :style="[styleObj1,styleObj2]">
方式五
</div> -->
<div class="box" :style="styleArr">
方式五
</div>
</div>
<script>
new Vue({
el: "#root",
data: {
theme: "bor",
arr: ["bor", "back", "font"],
classObj: {
bor: false,
back: false,
font: true
},
styleObj1: {
fontSize: '40px',
color: 'red'
},
styleObj2: {
fontWeight: "bolder"
},
styleArr: [{
fontSize: '40px',
color: 'red'
}, {
fontWeight: "bolder"
}]
},
methods: {
changed() {
const arr = ["bor", "font", "back"];
// Math.floor(Math.random()*3):先随机获取[0,3)的数,然后再向下取整:0,1,2
const num = Math.floor(Math.random() * 3)
this.theme = arr[num];
}
}
})
</script>
</body>
</html>
条件渲染
1.v-if
写法:
1.1 v-if=“表达式”
1.2 v-else-if=“表达式”
1.3 v-else=“表达式”
适用于切换频率较低的场景。
特点:不展示DOM元素会直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”
2.v-show
写法: v-show=“表达式”
适用于:切换频率较高的场景
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用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>条件渲染</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<!-- 如果切换频繁的,建议使用v-show,切换次数少的用v-if -->
<h2>当前num的值为:<span v-show="flag">{{num}}</span></h2>
<!-- v-show通过display属性来控制dom元素节点的显示和隐藏,v-show的值为true,就显示(display:block),否则就隐藏 (display:none)-->
<h1 v-show="num==3">
{{name}}
</h1>
<!-- v-if直接控制dom元素节点的存在与不存在,若v-if的值为true,dom元素存在,否则dom元素不存在 -->
<h3 v-if="num==5">
{{name}}
</h3>
<button @click="add">num++</button>
<button @click="sub">num--</button>
<!-- 如果使用v-if——v-else条件渲染的,在其之间不可以断开 -->
<div v-if="num==1">{{num}}</div>
<div v-else-if="num==3">{{num}}</div>
<!-- <div>v-if和v-else之间不可以断开,否则无效</div> -->
<div v-else-if="num==5">{{num}}</div>
<div v-else>num上天了</div>
<!-- template不影响页面结构,不渲染成元素,template与v-if配合使用有效,v-show无效 -->
<template v-if="num==1">
<p>num==1时出现</p>
<p>num==1时出现</p>
<p>num==1时出现</p>
</template>
</div>
<script>
new Vue({
el: '#root',
data: {
name: "张三",
flag: true,
num: 1
},
methods: {
add() {
this.num++;
if (this.num > 0) {
this.flag = true
}
},
sub() {
this.num--;
if (this.num == 0) {
this.num = 0
this.flag = false
}
}
},
})
</script>
</body>
</html>
列表渲染
v-for指令:
1.用于展示列表数据
2.语法:v-for =“item,index in(of) 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>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>人员列表</h2>
<ul>
<!-- 用in和of都可以 -->
<li v-for="person in persons" :key="person.id">{{person.name}}——{{person.age}}</li>
<!-- <li></li>
<li></li>
<li></li>
<li></li> -->
</ul>
<!-- 确定的遍历次数 -->
<ul>
<!-- v是1-5的数值,i从0开始的索引值 -->
<li v-for="(v,i) of 5" :key="i">
{{v}}-{{i}}
</li>
</ul>
<!-- 遍历字符串 -->
<ul>
<li v-for="(v,i) in str" :key="i">{{v}}</li>
</ul>
</div>
<script>
new Vue({
el: "#root",
data: {
str: "hello",
persons: [{
id: 001,
name: "张三",
age: 24
}, {
id: 002,
name: "李四",
age: 28
}, {
id: 003,
name: "王五",
age: 20
}, {
id: 004,
name: "周六",
age: 26
}, {
id: 005,
name: "田七",
age: 22
}, ]
}
})
</script>
</body>
</html>
面试题:react、vue中的key有什么作用?(key的内部原理)
1.虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据[新数据]生成[新的虚拟DOM],随后vue进行[新虚拟DOM]与[旧虚拟DOM]的差异比较。
2.对比规则:
2.1 在旧虚拟DOM中找到了与新虚拟DOM相同的key:
2.1.1 若旧虚拟DOM中的内容与新虚拟DOM中的内容一致,直接使用之前的真实DOM
2.1.2 若旧虚拟DOM中的内容与新虚拟DOM中的内容不一致,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
2.2 旧虚拟DOM中未找到与新虚拟DOM相同的key“
创建新的真实DOM,随后渲染到页面
3.用index作为key可能会引发的问题
3.1 若对数据进行逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新==>界面效果没问题,但效率低
3.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>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<h2>人员列表</h2>
<button @click="add">添加新成员</button>
<ul>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}}
<input type="text">
</li>
</ul>
</div>
<script>
new Vue({
el: "#root",
data: {
persons: [{
id: 001,
name: "张三",
age: 24
}, {
id: 002,
name: "李四",
age: 28
}, {
id: 003,
name: "王五",
age: 20
}, {
id: 004,
name: "周六",
age: 26
}, {
id: 005,
name: "田七",
age: 22
}, ]
},
methods: {
add() {
const p = {
id: '006',
name: '老刘',
age: 40
}
this.persons.unshift(p)
}
},
})
</script>
</body>
</html>