组件生命周期

组件生命周期

钩子函数,就是options里面的key, 它的值是函数
钩子函数写在其他配置项的后面
1. 组件的有哪几个阶段?

  • 初始化阶段
  • 运行中阶段
  • 销毁阶段
    2. 初始化阶段
  • 分为两个大阶段, 每一个大阶段包含两个生命周期钩子函数 ---- 生命周期 --》人的一声 钩子函数 --》 (人在某个阶段做得一些事情, 这些事情是自动触发)
  • 有那四个钩子函数呢?每个钩子函数有什么功能嗯?项目中有什么用呢?
  • beforeCreate
    - 表示组件创建前的准备工作, 为事件的发布订阅 和 生命周期的开始做初始化
    - 这个钩子函数中
    - 数据拿不到, 真实DOM也拿不到
    - 这个钩子在项目中我们没有什么实际用途
  • created
    - 表示组件创建结束
    - 这个钩子函数中
    - 数据拿到了, 但是真实DOM没有拿到
    - 这个钩子函数在项目
    - 数据请求, 然后可以进行一次默认数据的修改
  • beforeMount
    - 表示组件装载前的准备工作
    - 判断 el选项有没有, 判断 template选项有没有 , 如果没有, 那么需要手动装载
    - 如果有,那么通过render函数进行模板的渲染(没有做的,正要进行, VDOM)
    - 这个钩子函数中
    - 数据拿到了, 真实DOM没有拿到
    - 这个钩子函数在项目中,
    - 数据请求, 它也可以进行一次数据修改
  • mounted
    - 表示组件装载结束, 就是我们可以在视图中看到了
    - 这个钩子函数中
    - 数据拿到了, 真实DOM也拿到了
    - 这个钩子函数在项目:
    - DOM操作就可以进行了, 第三方库的实例化
<body>
      <div id="app">
          <life-circle></life-circle>
     </div>
    <template id="life-circle">
       <div>
          <h3> 组件生命周期的 初始化阶段 </h3>
          <p> {{ msg }} </p>
       </div>
    </template>
</body>
<script>
      Vue.component('LifeCircle',{
      template: '#life-circle',
               data () {
                       return {
                             msg: 'hello vue.js'
                  }
              },
// 初始化阶段钩子函数
beforeCreate () { //表示组件创建前的准备工作( 初始化事件和生命周期 ) ---- 小孩降生前的准备工作
/*
组件未创建, 所以没有this , 数据拿不到 , DOM也拿不到
*/
console.log('01-beforeCreate');
console.log( 'data',this.msg )
console.log( 'DOM',document.querySelector('p'))
/* axios({
          url: './data.json'
    })
      .then( res => {
      this.msg = res
     })
    .catch( error => console.log(error))
*/
},
      created () { // 组件创建结束
           console.log('02-created')
           console.log( 'data',this.msg )
           console.log( 'DOM',document.querySelector('p'))
/* axios({
         url: './data.json'
     })
       .then( res => {
       this.msg = res
   })
      .catch( error => console.log(error)) */
 },
     beforeMount () {
      console.log( '03-beforeMounte' )
      console.log( 'data',this.msg )
      console.log( 'DOM',document.querySelector('p'))
/* axios({
       url: './data.json'
     })
    .then( res => {
    this.msg = res
   })
   .catch( error => console.log(error)) */
},
   mounted () {
    console.log('04-mounted')
   console.log('data',this.msg)
   console.log('Real DOM',document.querySelector('p'))
axios({
    url: './data.json'
  })
       .then( res => {
        this.msg = res
  })
    .catch( error => console.log(error))
   }
})
new Vue({
}).$mount('#app')
</script>

总结: 由上对比,我们可以知道, 数据请求越提前越好一些, created常用于数据的请求和数据的修改, 第三方库的实例化常在mounted中进行书写

3. 运行中阶段

  • 运行中阶段一共有两个钩子函数
    beforeUpdate
    - 表示数据更新前的准备工作
    - 这个钩子不主动执行,当数据修改了, 才会执行
    - 这个钩子函数中
    - 数据拿到了, 并且拿到的是修改后的数据
    - DOM也输出了
    - 这个钩子函数更多的工作内容为:生成新的 VDOM , 然后通过diff算法进行两次VDOM 对比
    - 这个钩子在项目中
    - 因为他主要做的事情是内部进行的, 所以对我们而言没有太多的操作意义
    **updated **
    表示数据更新结束, 通过render函数渲染真实DOM
    • 这个钩子函数的执行也是, 当数据修改的时候才执行
    • 这个钩子函数中
    • 数据拿到了, DOM也拿到了
      -** 这个钩子在项目中 **
      也是进行第三方库的实例化( DOM是改变的
    • 总结: 数据更新, 也要进行DOM操作那么, 我们使用update这个钩子
<body>
     <div id="app">
         <life-circle></life-circle>
      </div>
      <template id="life-circle">
          <div>
              <h3> 运行中阶段 </h3>
              <p> {{ msg }} </p>
         </div>
      </template>
</body>
<script>
          Vue.component('LifeCircle',{
                   template: '#life-circle',
                  data () {
                  return {
                  msg: 'hello 骏哥约见面'
                 }
           },
                  beforeUpdate () {
                       console.log( 'beforeUpdate' )
                    console.log( 'data', this.msg)
                    console.log( 'DOM', document.querySelector('p') )
               },
                 updated () {
                        console.log( 'updated' )
                        console.log( 'data', this.msg )
                        console.log( 'DOM' , document.querySelector('p') )
// document.querySelector('p').style.background = 'red'
                  }
            })
new Vue({
       el: '#app'
})
</script>
4. 销毁阶段
  • 用过开关销毁
    - 这个组件真实DOM也会被删除掉
  • 通过调用vm.$destroy()
    • 这个组件的被删除了, 但是它的真实DOM的html结构还在
  • 包含两个钩子函数
    • beforeDestroy
    • destroyed
    • 这两个钩子无差别
    • 这两个钩子在项目中
      - 做善后工作 , 手动清除一些计时器, 和一些方法, 还有第三方实例化出来的对象
    • 我们建议大家使用开关的形式来操作组件的销毁和创建
5. 用案例来写一个生命周期 第三方库的实例化来做 swiper

真实DOM存在了, 才能实例化

  1. 直接写死了
    • DOM就没有渲染
    • 数据直接有了
  2. 数据请求
    • 我们常规是往 updated 钩子里面写, 但是遇到问题了?
    • 问题是: 当我们有其他数据更新时,updated钩子就会重复触发, 也就是说第三方库要重复实例化
  • 解决:
    1. 在updated钩子中添加判断条件, if(!this.swiper){}
    2. 在数据请求里面写, 但是发现无法获得真实DOM
    3. 将实例化代码发到异步队列
    • setTimeout(function(){},0) 将实例化代码发到这里面 [不推荐]
    • Vue.nextTick() /this.$nextTick 优先使用
    • 概念: nextTick表示DOM渲染之后执行的业务
<body>
          <div id="app">
               <button @click = 'flag = !flag'> 销毁 </button>
               <life-circle v-if = "flag"></life-circle>
        </div>
          <template id="life-circle">
        <div>
                <h3> 销毁阶段 </h3>
                <button @click = 'destroy'> 销毁 </button>
         </div>
         </template>
</body>
<script>
Vue.component('LifeCircle',{
            template: '#life-circle',
            methods: {
            destroy(){
                      this.$destroy()
                 }
       },
           created () {
                this.timer = setInterval( () => {
                 console.log('1')
               },1000)
            },
          beforeDestroy () {
               console.log('beforeDestory')
           },
         destroyed () {
               console.log('destroyed')
                 clearInterval( this.timer )
// 如果是用$destroy这个方法来清除组件, 那么我们必须手动清除这个组件的外壳
                 document.querySelector('#app div').remove()
                 }
         })
new Vue({
        el: '#app',
data: {
flag: true
}
})
</script>

猜你喜欢

转载自blog.csdn.net/weixin_44889992/article/details/89514994