♻️ Vue 实例生命周期
生命周期函数就是Vue实例在某一个时间点会自动执行的函数。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue实例生命周期函数</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
var vm = new Vue({
el: '#app',
template: "<div>{{test}}</div>",
data: {
test: "hello world"
},
beforeCreate() {
console.log("beforeCreate");
},
created() {
console.log("created");
},
beforeMount() {
console.log(this.$el); // 此时页面还没有被渲染,里面没有内容:<div id="app"></div>
console.log("beforeMount");
},
mounted() {
console.log(this.$el); // 页面被渲染完毕,内容:<div>hello world</div>
console.log("mounted");
},
// 通过在控制台输入 vm.$destroy(); 进行测试
beforeDestroy() {
console.log("beforeDestroy");
},
destroyed() {
console.log("destroyed");
},
// 通过在控制台输入 vm.test="update"; 进行测试
beforeUpdate() {
console.log("beforeUpdate");
},
updated() {
console.log("updated");
},
})
</script>
</body>
</html>
是否指定“template”选项?
是:<div id="app"></div> <script> var vm = new Vue({ el: '#app', template: "<div>hello world</div>" }) </script>
否:
<div id="app">hello world</div> <script> var vm = new Vue({ el: '#app' }) </script>
两种情况是相同的。
✏️ Vue 的模版语法
v-text
和 差值表达式 {{}}
的功能相同。
vue 指令(v-text)后面跟着一个值(=“name”)的时候,这个值就不再是字符串了,而是一个 js 表达式。
v-html
不对内容进行转义,直接显示 html 样式。
<div id="app">
<div>{{name}}</div>
<div v-text="name"></div>
<div v-html="name"></div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
name: "<h1>bule_daze</h1>"
}
})
</script>
<div id="app">
<div>{{name + ' Hi'}}</div>
<div v-text="name + ' Hi'"></div>
<div v-html="name + ' Hi'"></div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
name: "bule_daze"
}
})
</script>
🐟 计算属性,方法与侦听器
我们不希望在模版中写一些带有逻辑的表达式:
<div>{{firstName + " " + lastName}}</div>
而是:
<div>{{fullName}}</div>
🌊 此时就要利用计算属性。✯
<div id="app">
<div>{{fullName}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstName: "daze",
lastName: "bule"
},
// 计算属性
computed: {
fullName() {
return this.firstName + " " + this.lastName;
}
}
})
</script>
计算属性有一个缓存,如果其依赖的值没有发生改变,就不会重新计算。
🌊 也可以利用方法实现。
<div id="app">
<div>{{fullName()}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstName: "daze",
lastName: "bule"
},
// 方法
methods: {
fullName() {
return this.firstName + " " + this.lastName;
}
}
})
</script>
但是不推荐,因为其内部没有缓存机制,只要页面重新渲染方法就会被重新执行。
🌊 还可以利用侦听器。
<div id="app">
<div>{{fullName}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstName: "daze",
lastName: "bule",
fullName: "daze bule"
},
watch: {
firstName() {
this.fullName = this.firstName + " " + this.lastName;
},
lastName() {
this.fullName = this.firstName + " " + this.lastName;
}
}
})
</script>
🐳 计算属性的 getter 和 setter
<div id="app">
<div>{{fullName}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstName: "daze",
lastName: "bule",
},
computed: {
fullName: {
get() {
return this.fullName = this.firstName + " " + this.lastName;
},
set(value) {
var arr = value.split(" ");
this.firstName = arr[0];
this.lastName = arr[1];
}
}
}
})
</script>
computed
计算属性上,不仅可以写一个 get
的方法,通过其它的值算出一个新值;同时还可以写一个 set
的方法,通过设置一个值来改变它相关联的值,而改变相关联的值之后,又回引起重新计算,页面变化为新的内容。
⚓️ Vue 中的样式绑定
我们希望当 div 被点击一次的时候,字体变成红色;当再次点击时,恢复默认颜色;循环往复。
1⃣️ class 的对象绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 中的样式绑定</title>
<script src="./vue.js"></script>
<style>
.activated {
color: red;
}
</style>
</head>
<body>
<div id="app">
<div @click="handleDivClick" :class="{activated: isActivated}">hello world</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
isActivated: false
},
methods: {
handleDivClick() {
this.isActivated = !this.isActivated;
}
}
})
</script>
</body>
</html>
:class="{activated: isActivated}"
:div 元素上面有一个 class,这个 class 的名字是 activated,activated 取决于 isActived 变量。
2⃣️ class 的数组绑定
class 可以和一个数组相绑定,数组里的内容代表一个变量。数组里可以写多个变量。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 中的样式绑定</title>
<script src="./vue.js"></script>
<style>
.activated {
color: red;
}
</style>
</head>
<body>
<div id="app">
<div @click="handleDivClick" :class="[activated]">hello world</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
activated: ""
},
methods: {
handleDivClick() {
this.activated = this.activated === "activated" ? "" : "activated"
}
}
})
</script>
</body>
</html>
:class="[activated]"
:div 元素上面有一个class,这个 class 显示的是 activated 变量的内容。
3⃣️ style 的对象绑定
<div id="app">
<div :style="styleObj" @click="handleDivClick">hello world</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj: {
color: "black"
}
},
methods: {
handleDivClick() {
this.styleObj.color = this.styleObj.color === "black" ? "red" : "black";
}
}
})
</script>
4⃣️ style 的数组绑定
<div id="app">
<div :style="[styleObj]" @click="handleDivClick">hello world</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
styleObj: {
color: "black"
}
},
methods: {
handleDivClick() {
this.styleObj.color = this.styleObj.color === "black" ? "red" : "black";
}
}
})
</script>
数组,可以挂载多个对象。
<div :style="[styleObj,{fontSize: '20px'}]" @click="handleDivClick">hello world</div>
在 js 对象中
font-size
需要写成fontSize
。
🌲 Vue 中的条件渲染
🍃 v-if
v-if
指令,决定这个标签是否在页面中存在。当其值为 true
时存在(显示),false
不存在(不显示)。
<div id="app">
<div v-if="show">{{message}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: false,
message: "hello world"
}
})
</script>
在控制台中输入
vm.show = true;
使 div 显示出来。
🍃 v-show
v-show
指令,决定这个标签是否在页面中显示。当其值为 true
时显示,false
不显示。
<div v-if="show">{{message}}</div>
🍃 v-else
v-if
和 v-else
要紧贴在一起使用。
<div v-if="show">{{message}}</div>
<div v-else>bye</div>
🍃 v-else-if
v-if
,v-else-if
,v-else
也要连在一起写,中间不能被其它标签分隔。
<div id="app">
<div v-if="show === 'a'">This is A.</div>
<div v-else-if="show === 'b'">This is B.</div>
<div v-else>This is others.</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: "a"
}
})
</script>
当你给某一个元素标签加一个 key
值时,Vue 会知道它是唯一的一个元素。如果两个 key 不一样,Vue 就不会复用该内容。
<div id="app">
<div v-if="show">
用户名:<input key="username" />
</div>
<div v-else>
邮箱:<input key="email" />
</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
show: false
}
})
</script>
不加 key 的时候,你尝试一下在 input 中输入内容后更改 show 的值,看 input 的显示。
🌳 Vue 中的列表渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue 中的列表渲染</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<div v-for="(item,index) in list">{{item}}----{{index}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
list: [
"hello",
"censek",
"haha"
]
}
})
</script>
</body>
</html>
key 值通常用 id 表示。
v-for="(item,index) in list" :key="item.id"
当我们去尝试修改数组里的内容时,不能直接通过下标的形式来改变数组。数据变了但是页面中没有变化。
想要改变页面内容的 解决办法: 1⃣️ 通过 Vue 提供的几个数组变异方法修改数组。2⃣️ 改变数据的引用地址。
🌱 操作数组的方法
push
pop
shift
unshift
splice
sort
reverse
🌱 template
如果我想根据 list 循环 div 和 span 标签,让循环写两遍不好。
<!-- bad -->
<div id="app">
<div v-for="(item,index) in list">{{item}}----{{index}}</div>
<span v-for="(item,index) in list">{{item}}</span>
</div>
所以,考虑在最外层加一个 div,把循环写在最外层的 div 里面。
<div id="app">
<div v-for="(item,index) in list">
<div>{{item}}----{{index}}</div>
<span>{{item}}</span>
</div>
</div>
但是我只想显示一个 div 和 span,怎么办呢?利用 template
模版占位符。
<div id="app">
<template v-for="(item,index) in list">
<div>{{item}}----{{index}}</div>
<span>{{item}}</span>
</template>
</div>
🌱 对象的循环
<div id="app">
<div v-for="(item,key,index) of userInfo">{{item}}---{{key}}---{{index}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
userInfo: {
name: "blue_daze",
age: 18
}
}
})
</script>
v-for="(item,key,index) of userInfo"
- item:对象的值
- key:对象的键名
- index:位置
如果我想修改 name 的值,直接在控制台输入 vm.userInfo.name = "censek"
进行测试即可。
但是如果我想加一个字段,同操作数组,需要改变数据的引用。
vm.userInfo = {
name: "blue_daze",
age: 18,
address: "Xian"
}
🌿 set 方法
通过 set 方法改变对象中数据内容。
-
Vue 全局方法:
Vue.set()
Vue.set(vm.userInfo, "address", "Xian");
-
Vue 实例方法:
$set()
vm.$set(vm.userInfo, "address", "Xian");
set 也可以对数组进行修改。
<div id="app">
<div v-for="(item,index) of userInfo">{{item}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
userInfo: [1, 2, 3, 4]
}
})
</script>
- Vue 全局方法:
Vue.set()
Vue.set(vm.userInfo, 1, 5);
- Vue 实例方法:
$set()
vm.$set(vm.userInfo, 2, 10);