目录
一、Vue的生命周期
这里可以比作人的一生需要经历:出生=>小孩=>成人=>结婚=>衰老=>病死
而Vue生命周期亦是如此。
一个组件从创建一直到销毁。这整个过程就叫做生命周期 ,在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。
下面是一张官网的图:
这里做了解释:
这个图看着有点绕,让我们直接看代码了解一下生命周期
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue的生命周期</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
<button type="button" @click="handlerUpdate">更新</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data() {
return {
message:'123456789'
}
},
methods: {
handlerUpdate() {
this.message = this.message.split('').reverse().join('-')
}
},
beforeCreate() {
// console.log(this.$el);
console.log('执行了beforeCreate');
console.log('——————');
},
created() {
// console.log(this.$el);
console.log('执行了Create');
console.log('——————');
},
beforeMount() {
// console.log(this.$el);
console.log('执行了beforeMount');
console.log('——————');
},
mounted() {
// console.log(this.$el);
console.log('执行了mounted');
console.log('——————');
},
beforeUpdate() {
console.log('执行了beforeUpdate');
},
updated() {
console.log('执行了updated');
},
beforeDestroy() {
console.log('执行了beforeDestroy');
},
destroyed() {
console.log('执行了destroyed');
},
})
</script>
</body>
</html>
这里记住八个方法:
beforeCreate(创建前)
created(创建后)
beforeMount(载入前)
mounted(载入后)
beforeUpdate(更新前)
updated(更新后)
beforeDestroy(销毁前)
destroyed(销毁后)
1、初始化页面调用的方法
效果如下图:
2、更新过后数据调用生命周期的方法
打印效果如下图:
3、销毁过后生命周期出现的方法:
打开控制台直接输入 vm.$destroy()就会销毁这个组件并且执行beforeDestroy和destroyed销毁前和销毁后的方法并返回undefined,这时再去修改其值已经不起作用了
三、el对生命周期的影响:
加el时:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
<button type="button" @click="handlerUpdate">更新</button>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data() {
return {
message:'123456789'
}
},
methods: {
handlerUpdate() {
this.message = this.message.split('').reverse().join('-')
}
},
beforeCreate() {
console.log(this.$el);
console.log('执行了beforeCreate');
console.log('——————');
},
created() {
console.log(this.$el);
console.log('执行了Create');
console.log('——————');
},
beforeMount() {
console.log(this.$el);
console.log('执行了beforeMount');
console.log('——————');
},
mounted() {
console.log(this.$el);
console.log('执行了mounted');
console.log('——————');
},
beforeUpdate() {
console.log('执行了beforeUpdate');
},
updated() {
console.log('执行了updated');
},
beforeDestroy() {
console.log('执行了beforeDestroy');
},
destroyed() {
console.log('执行了destroyed');
},
})
</script>
</body>
</html>
没有el时:
// el: '#app'
效果如下:
由此证明了没有el选项,则停止编译,也意味着暂时停止了生命周期。生命周期到created钩子函数就结束了。
能够使暂停的生命周期进行下去可以使用vm.$mount(el)方法
Vue 的$mount()为手动挂载,在项目中可用于延时挂载(例如在挂载之前要进行一些其他操作、判断等),之后要手动挂载上。new Vue时,el和$mount并没有本质上的不同。
在代码末尾添加vm.$mount('#app')效果如下:
直接在控制台输入vm.$mount('#app')效果如下:
四、template与html之间的优先级
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试html与template的优先级</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<h3>测试html与template的优先级</h3>
<div id="app">
<p>是html优先?</p>
</div>
<script type="text/javascript">
const vm = new Vue({
el:'#app',
data(){
return{
message:'是template优先?'
}
},
template:
`<p>{{message}}<p>`
,
})
</script>
</body>
</html>
效果如下:
template参数选项的优先级要比外部的HTML高
绑定不加冒号与加冒号的区别:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>绑定加不加冒号</title>
</head>
<body>
<div id="app">
<cpn message="content"></cpn>
<!-- 不加冒号会被Vue识别为字符串 -->
<cpn :message="content"></cpn>
<!-- 加冒号会进行数据绑定 -->
</div>
<template id="cpn">
<div>
<h2>{{msg}}</h2>
<h2>{{message}}</h2>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
data() {
return {
msg: '我是子组件数据'
}
},
props: {
message: {
type: String
}
}
}
const app = new Vue({
el: "#app",
data() {
return {
content: '我是父组件数据'
}
},
components: {
cpn
}
})
</script>
</body>
</html>
不加冒号的效果:
加冒号的效果如下:
五、总线机制(bus):
非父子组件之间通信可以用bus和vuex
bus比较适合小项目,而vuex适合中、大型项目
这里实现一个兄弟之间的通信,看例子:
第一种写法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>bus</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="app">
<child content='Nan'></child>
<child content="Chen"></child>
</div>
<script type="text/javascript">
// 这里需要使用Vue的原型
// 添加一个变量到 Vue.prototype
// 变量前面最好以$开头,避免数据、方法、计算属性等发生冲突
Vue.prototype.$bus =new Vue();
Vue.component('child',{
template:
`<div @click="handelClick">{{message}}</div>`,
data(){
return{
message:this.content
}
},
props:{
content:[String]
},
methods:{
handelClick(){
// 很像父子之间传值的方法
this.$bus.$emit('change',this.message)
}
},
// 挂载后执行
mounted(){
var that = this
// $on 用来监听$emit所派发的事件
this.$bus.$on('change',function(msg){
// 将获取到的msg值传给message
console.log(msg);
console.log(that);
that.message = msg
})
}
})
const vm = new Vue({
el:'#app',
})
</script>
</body>
</html>
实现效果:
这样就实现了简单的兄弟之间的通讯 下面来说一下$emit与$on之间的关系
$emit与$on之间的关系:
详细解析可以参考vue中的$on,$emit,v-on 三者关系_oiery的博客-CSDN博客
使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件
如果把Vue看成一个家庭(相当于一个单独的components),女主人一直在家里指派($emit)男人做事,而男人则一直监听($on)着女士的指派($emit)里eventName所触发的事件消息,一旦 $emit 事件一触发,$on 则监听到 $emit 所派发的事件,派发出的命令和执行派执命令所要做的事都是一一对应的。
第二种写法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第二种写法</title>
</head>
<body>
<div id="app">
<cpn content="Nan"></cpn>
<cpn content="Chen"></cpn>
</div>
<template id="cpn">
<div @click="handelClick">{{message}}</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
<script>
Vue.prototype.$bus = new Vue()
const cpn = {
template:'#cpn',
data(){
return {
message:this.content
}
},
props:{
content:{
type:String
}
},
methods:{
handelClick(){
this.$bus.$emit('change',this.message)
}
},
mounted(){
var that = this
this.$bus.$on('change',function(msg){
console.log(msg);
that.message = msg
})
}
}
const app = new Vue({
el: "#app",
components:{
cpn
}
})
</script>
</body>
</html>
效果如下: