04生命周期与数据共享

136 阅读4分钟

1.组件的生命周期

1.1 生命周期 & 生命周期函数

生命周期(Life Cycle) 是指一个组件从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段。

生命周期函数:是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行。

注意:生命周期强调的是时间段,生命周期函数强调的是时间点

1.2 组件生命周期函数的分类

在这里插入图片描述

1.3 生命周期图示

在这里插入图片描述

1.4 beforeCreate

beforeCreate:组件的 propsdatamethods 尚未被创建,都处于不可用的状态

App.vue 内容如下:

<template>
  <div id="app">
    <div>{{ num }}</div>
    <button @click="show">按钮</button>
  </div>
</template>

<script>
export default{
  data(){
    return{
      num : 1
    }
  },
  methods:{
    show(){
      console.log('调用了 show 方法')
    }
  },
  beforeCreate(){
    console.log(this.num)
    this.show()
  }
}
</script>

由于组件的 propsdatamethods 尚未被创建,都处于不可用的状态,所以 num 打印出来为 undefinedshow 方法找不到。

在这里插入图片描述

1.5 created

created:组件的 propsdatamethods 已经创建完毕,都处于可用的状态,但模板结构尚未生成

App.vue 内容如下:

<template>
  <div id="app">
    <div>{{ num }}</div>
    <button @click="show">按钮</button>
  </div>
</template>

<script>
export default{
  data(){
    return{
      num : 1
    }
  },
  methods:{
    show(){
      console.log('调用了 show 方法')
    }
  },
  created(){
    console.log(this.num)
    this.show()
    const btn = document.querySelector('button')
    console.log(btn) // 无法获取
  }
}
</script>

由于组件的 propsdatamethods 已经创建完毕,都处于可用的状态,但模板结构尚未生成,所以 num 打印出来为 1show 方法正常使用,但无法获取到 dom 结构,所以为 null

在这里插入图片描述

由于有数据,但模板还未创建。所以该函数常用功能是:请求服务器数据,并将数据转存到 data 中,供 template 模板渲染的时候使用。

1.6 beforeMount

beforeMount:基本和 created 类似,所以将该刚才 created 换成 beforeMount,执行结果是一致的。

他们的不同点在所处的时间段不一样:

  • createHTML 结构未编译
  • beforeMountHTML 结构编译完成

且两者均无法调用 DOM 结构,因为模板还没有被渲染。

1.7 mounted

mounted:已经把内存中的 HTML 成功渲染,即:可以使用 DOM 结构了

App.vue 内容如下:

<template>
  <div id="app">
    <div>{{ num }}</div>
    <button @click="show">按钮</button>
  </div>
</template>

<script>
export default{
  data(){
    return{
      num : 1
    }
  },
  methods:{
    show(){
      console.log('调用了 show 方法')
    }
  },
  mounted(){
    console.log(this.num)
    this.show()
    const btn = document.querySelector('button')
    console.log(btn) 
  }
}
</script>

在这里插入图片描述

所以:mounted 是最早能够操作 DOM 的生命周期函数

1.8 beforeUpdate

beforeUpdate:数据变化时,数据先变化,DOM 结构不变(未被渲染)

App.vue 内容如下:

<template>
  <div id="app">
    <div class="val">{{ num }}</div>
    <button @click="show">按钮</button>
    <button @click="add">+1</button>
  </div>
</template>

<script>
export default{
  data(){
    return{
      num : 1
    }
  },
  methods:{
    show(){
      console.log('调用了 show 方法')
    },
    add(){
      this.num+=1
    }
  },
    
  beforeUpdate(){
    const val = document.querySelector('.val')
    this.show()
    console.log(val.innerHTML)
    console.log(this.num)
  }
}
</script>

按下 +1 按钮后,结果如下:

在这里插入图片描述

按下之后数据肯定会发生变化,所以该函数的 this.num 变成了 2,但由于模板结构没有被重新渲染,所以 DOM 结构的 innerHTML 没有变化。

1.9 updated

updated:已经根据最新的数据,DOM 结构重新渲染

App.vue 内容如下:

<template>
  <div id="app">
    <div class="val">{{ num }}</div>
    <button @click="show">按钮</button>
    <button @click="add">+1</button>
  </div>
</template>

<script>
export default{
  data(){
    return{
      num : 1
    }
  },
  methods:{
    show(){
      console.log('调用了 show 方法')
    },
    add(){
      this.num+=1
    }
  },
    
  beforeUpdate(){
    const val = document.querySelector('.val')
    this.show()
    console.log(val.innerHTML)
    console.log(this.num)
  }
}
</script>

按下 +1 按钮后,结果如下:

在这里插入图片描述

数据和 DOM 结构被重新渲染,所以值都是 2。

1.10 组件销毁(略)

beforeDestroydestroy 都是销毁阶段的生命周期函数,没什么特别好说的,一般也不会用到。

2. 组件之间的数据共享

2.1 组件之间的关系

在项目开发中,组件之间的最常见的关系分为如下两种:

  • 父子关系
  • 兄弟关系

在这里插入图片描述

如上图所示:

  • A 与 B,A 与 C 之间就是父子关系
  • A 与 D,E 与 F,B 与 E 之间就是兄弟关系

即,有直接联系的就是父子关系,否则可认为是兄弟关系

2.2 父子组件之间的数据共享

父子组件之间的数据共享又分为:

  • 父 -> 子 共享数据

  • 子 -> 父 共享数据

2.2.1 父 -> 子

父组件向子组件共享数据需要使用自定义属性

逻辑:

  • 父组件有要传输给子组件的数据
  • 联结方式:用 v-bind 绑定自定义属性,值就是要传输的数据
  • 子组件要定义自定义属性

父组件:

<template>
  <div id="app">
    <Son :msg="message" :user="userinfo"></Son>
  </div>
</template>

<script>
import Son from '@/components/Son.vue'
export default{
  components:{
    Son
  },
  data(){
    return{
      message: 0,
      userinfo:{name:'zs','age':18}
    }
  }
}
</script>

子组件:

<template>
  <div id="Son">
    <h2>子组件</h2>
    <div>父给子的 msg 是{{ msg }}</div>
    <div>父给子的 user 是{{ user }}</div>
  </div>
</template>

<script>
export default {
    props: ['msg','user']
}
</script>

<style>

</style>

2.2.2 子 -> 父

子组件向父组件共享数据使用自定义事件

逻辑:

  • 子组件要有自定义的事件和要发送的数据

    this.$emit('事件名称', 要发送的数据)
    
  • 联结方式:通过触发自定义事件进行联结,这个事件相当于触发条件,类似于: clickkeyup,所以后面可以跟个函数

  • 父组件中可以根据自定义事件的函数来取到子组件的值

子组件:

<template>
  <div id="Son">
    <h2>子组件</h2>
    <button @click="add" >+1</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      num: 0
    }
  },

  methods:{
    add(){
      this.num++
      this.$emit('trans', this.num)
    }
  }
}
</script>

<style>

</style>

父组件:

<template>
  <div id="app">
    <Son @trans="getNum"></Son>
    <div>{{ count }}</div>
  </div>
</template>

<script>
import Son from '@/components/Son.vue'
export default{
  components:{
    Son
  },
  data(){
    return{
      count:0
    }
  },
  methods:{
    getNum(val){
      this.count = val
    }
  }
}
</script>

2.3 兄弟组件之间的数据共享

vue2.x 中,兄弟组件之间数据共享的方案是 EventBus

EventBus 的使用步骤:

  • 创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象

  • 在数据发送方,调用 bus.$emit('事件名称', 要发送的数据) 方法触发自定义事件

  • 在数据接收方,调用 bus.$on('事件名称', 事件处理函数) 方法注册一个自定义事件

eventBus.js 模块:

import Vue from 'vue'
// 向外共享 Vue 的实例对象
export default new Vue()

发送方:

<template>
    <div id="left">
        <h2>左组件</h2>
        <button @click="sendMsg">发送</button>
  </div>
</template>

<script>
import bus from './eventBus.js'
export default {
    data(){
        return{
            msg:'hello, right!'
        }
    },
    methods:{
        sendMsg(){
            bus.$emit('share', this.msg)
        }
    }
}
</script>

<style>

</style>

接收方:

<template>
    <div id="right">
        <h2>右组件</h2>
        <div>{{ leftMsg }}</div>
    </div>
</template>

<script>
import bus from './eventBus.js'
export default {
    data(){
        return{
            leftMsg:'9'
        }
    },
    created(){
        bus.$on('share', val => {
            this.leftMsg = val
        })
    }
}
</script>

<style>

</style>

本文主要学习 黑马程序员Vue全套视频教程,从vue2.0到vue3.0一套全覆盖,前端学习核心框架教程

如有错误,敬请指正,欢迎交流🤝,谢谢♪(・ω・)ノ