Vue——08生命周期、绑定加冒号与不加的区别、总线机制、$bus事件总线、以及$emit与$on之间的关系

简介: 生命周期、绑定加冒号与不加的区别、总线机制、$bus事件总线、以及$emit与$on之间的关系

51fb15b333dc4891ae9fe3cea162485a.png

一、Vue的生命周期

这里可以比作人的一生需要经历:出生=>小孩=>成人=>结婚=>衰老=>病死  

而Vue生命周期亦是如此。

一个组件从创建一直到销毁。这整个过程就叫做生命周期 ,在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。

下面是一张官网的图:

231c43608dcf643c6044fcd6eab2472b.png

这里做了解释:

14938c6dcb08497fba5e2a407e39cb5c.jpg

这个图看着有点绕,让我们直接看代码了解一下生命周期

<!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、初始化页面调用的方法

效果如下图:

4a5dbbff9d014fefbb6df7697df449d7.png

2、更新过后数据调用生命周期的方法

打印效果如下图:

f73c386df5bf48fda23632eba17b5e77.png

3、销毁过后生命周期出现的方法:

打开控制台直接输入 vm.$destroy()就会销毁这个组件并且执行beforeDestroy和destroyed销毁前和销毁后的方法并返回undefined,这时再去修改其值已经不起作用了

bcb3c6bceb1c47bdae2f2cace76615dd.png

d4689c1d34234c4899805038b5a2989a.png

二、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>

7cbda7eb3b7b48969b97953bfeab52af.png

没有el时:

// el: '#app'

效果如下:

16b71ca7f69c469d92d10980dc27f5c1.png

由此证明了没有el选项,则停止编译,也意味着暂时停止了生命周期。生命周期到created钩子函数就结束了。

能够使暂停的生命周期进行下去可以使用vm.$mount(el)方法

Vue 的$mount()为手动挂载,在项目中可用于延时挂载(例如在挂载之前要进行一些其他操作、判断等),之后要手动挂载上。new Vue时,el和$mount并没有本质上的不同。

在代码末尾添加vm.$mount('#app')效果如下:

4fb656c68e4f4386814bcb183a297cf2.png

直接在控制台输入vm.$mount('#app')效果如下:

17c08428b8cd4da69d7292b908b9fbe5.png

三、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>

效果如下:

1c0fd98134ec4994b1dbce92713adf2f.png

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>

实现效果:

5e76b21a0b0a4258ad4b9b3a19a065e3.gif

这样就实现了简单的兄弟之间的通讯 下面来说一下$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>

效果如下:

5e76b21a0b0a4258ad4b9b3a19a065e3.gif

相关文章
|
2月前
|
JavaScript
vue实例的data属性,可以在哪些生命周期中获取到
Vue实例的`data`属性在`beforeCreate`、`created`和`beforeMount`阶段已可访问。此时,虽能使用数据,但事件监听和DOM操作不可行。`beforeCreate`时数据可访问,但未初始化观测和事件;`created`时数据完全可用,但未挂载到DOM;`beforeMount`时仍可访问数据,DOM挂载未开始。
31 3
|
2月前
|
JavaScript
在vue中,在哪个生命周期内调用异步请求?
在vue中,在哪个生命周期内调用异步请求?
25 0
|
2月前
|
JavaScript
在vue中,Vue 的父组件和子组件生命周期钩子函数执行顺序?
在vue中,Vue 的父组件和子组件生命周期钩子函数执行顺序?
17 0
|
2月前
|
JavaScript
在vue中,谈谈你对 Vue 生命周期的理解?
在vue中,谈谈你对 Vue 生命周期的理解?
17 0
|
6天前
|
存储 JavaScript 前端开发
【Vue】绝了!这生命周期流程真...
【Vue】绝了!这生命周期流程真...
|
12天前
|
JavaScript 前端开发 API
vue与jqyery的区别
vue与jqyery的区别
|
13天前
|
JavaScript 算法 前端开发
vue3和vue2的区别都有哪些
【4月更文挑战第15天】Vue3与Vue2在响应式系统(Proxy vs. Object.defineProperty)、组件模块化(Composition API vs. Options API)、数据变化检测(Reactive API vs. $watch)、虚拟DOM算法(基于迭代 vs. 基于递归)及Tree-Shaking支持上存在显著差异。Vue3的改进带来了更好的性能和灵活性,适合追求新技术的项目。Vue2则因其成熟稳定,适合维护大型项目。选择版本需根据项目需求、团队情况和技术追求来决定。
14 0
|
19天前
|
JavaScript 前端开发
vue绑定数组
vue绑定数组
|
22天前
|
JavaScript 前端开发
「Vue3系列」Vue3 样式绑定
在 Vue 3 中,样式绑定通常是通过绑定到元素的 `style` 属性来实现的。你可以使用对象语法或数组语法来动态地绑定样式。
26 0
|
23天前
|
缓存 JavaScript
vue中的计算属性和侦听属性的区别
vue中的计算属性和侦听属性的区别