组件的生命周期

组件生命周期

什么是生命周期呢?

  • 当前组件在创建到销毁经历的一系列过程,称之为生命周期

生命周期的分为几个阶段?每个阶段有哪些钩子函数

生命周期分为3个阶段,这三个阶段分别是: 初始化 、 运行中 、 销毁
  • 初始化阶段:有4个钩子函数 , 触发条件是自动的

    • beforeCreate
      1. 组件即将创建,进行组件事件和生命周期的初始化
      2. 项目中一般不使用( 这里是个人观点,也可以使用)
      3. 有的开发者也会在这里进行数据请求
          beforeCreate () { 
              /* 
                  这个阶段:组件创建前
                  data  data选项中的数据获取不到
                  RDOM  拿不到
                  项目中: 没什么用
                  但是这个阶段是一个对事件和生命周期的准备阶段,也是必不可少的
              */
              console.log('1-beforeCreate')
              console.log( 'data', this.money )
              console.log( '真实DOM',document.querySelector('h3') )
          },
      
    • created
      1. 组件创建完成
      2. 项目中:
        1) 异步请求接口数据
        2) 数据修改
              created () { // 组件创建结束
                  /* 
                      这个阶段:
                      data  data选项中的数据获到了
                      RDOM  拿不到
                      项目中: 
                          数据的修改
                          异步数据请求
                  */
                  this.money = 20000
                  console.log('2-created')
                  console.log( 'data', this.money )
                  console.log( '真实DOM',document.querySelector('h3') )
              },
      
    • beforeMount
      1. 组件即将挂载
      2. 判断根实例组件是否有el选项,如果没有,那么手动挂载,判断根实例组件中的其他子组件是否有template选项,如果没有,那么使用outerHTML插入
      3. 项目中:
        1) 异步请求接口数据
        2) 数据修改
              beforeMount () { //组件即将挂载
                  /* 
                  这个阶段:
                  data  data选项中的数据获到了
                  RDOM  拿不到
                  项目中: 
                      数据的修改
                      异步数据请求
                  */
                  this.money = 10000000
                  console.log('3-beforeMount')
                  console.log( 'data', this.money )
                  console.log( '真实DOM',document.querySelector('h3') )
              },
      
    • mounted
      1. 组件挂载结束
      2. 使用真实DOM替换VDOM
      3. 项目中
        1) 异步请求接口数据
        2) 数据修改
        3) 真实DOM操作可以了( Vue一般情况下不要直接操作真实DOM, 一般可以进行第三方库的实例化(静态数据渲染来的) )
              mounted () { //组件挂载结束了
                  /* 
                      这个阶段:
                      data: 可以获得数据
                      RDOM: 拿到了
                      项目中: 
                          数据修改
                          异步数据请求
                          真实DOM操作可以了( Vue一般情况下不要直接操作真实DOM, 一般可以进行第三方库的实例化(静态数据渲染来的)  )
                  */
                  document.querySelector('h3').style.background  = 'red'
                  console.log('4-mounted')
                  console.log( 'data', this.money )
                  console.log( '真实DOM',document.querySelector('h3') )
                  }
              })
      
      • 总结: 初始化过程中在项目中使用
        数据请求:created
        DOM操作: mounted
        数据修改:created beforeMount mounted
  • 运行中阶段:有2个钩子函数 : 触发条件是: 当data选项中的数据发生改变时

    • beforeUpdate:
      1. 内部操作 : vdom生成和diff的对比
      2. 我们可以不使用
          beforeUpdate () { //表示组件即将更新   vdom --diff--> vdom的不同(patch对象)
              /* 
                  这个阶段: 
                  data: 拿到了
                  RDOM: 获得
                  这个阶段进行的是vdom的生成和diff算法的对比,都是内部进行的,我们在项目中可以不使用
              */
              console.log(' 1- beforeUpdate ')
              console.log( 'data', this.money )
              console.log( '真实DOM',document.querySelector('h3') )
          },
      
    • updated
      1. Rdom已经生成,可以进行异步数据请求得到的dom渲染的第三方库实例化
              updated () { // 组件更新结束 , 通过render函数将vdom渲染成了真实dom,然后驱动vue进行视图更新
                  /* 
                  这个阶段:
                      动态数据的渲染,进行dom操作( 第三方库的实例化 )
                  */
                  document.querySelector('h3').style.background = 'blue'
                  console.log(' 2- updated ')
                  console.log( 'data', this.money )
                  console.log( '真实DOM',document.querySelector('h3') )
              },
      

      第三方库的实例化的存在着问题(用swiper举例)

      • 原因: updated 这个钩子函数是当组件中的数据改变就会触发,swiper就会再次进行实例化
      • 解决一下
      • 方案一:
          //在updated里面这样
          if( this.swiper ){
               return false
          }
      
      • 方案二:
          //在created钩子函数里面请求数据的时候,使用异步操作(定时器)
              created () {
                  fetch('./data.json')
                      .then( res => res.json())
                      .then( data => {
                          this.lists = data
                          setTimeout(()=> {
                                  this.swiper = new Swiper ('.swiper-container', {
                                  loop: true, // 循环模式选项
                                  
                                  // 如果需要分页器
                                  pagination: {
                                      el: '.swiper-pagination',
                                  },
                                  
                                  // 如果需要前进后退按钮
                                  navigation: {
                                      nextEl: '.swiper-button-next',
                                      prevEl: '.swiper-button-prev',
                                  },
                                  
                                  // 如果需要滚动条
                                  scrollbar: {
                                      el: '.swiper-scrollbar',
                                  },
                                  },0)  
                          })
      
                      })
                      .catch( error => {
                      if( error ) throw error 
                      })
                  },
      
      • 方案三:(推荐)
          //Vue内部提供了一个Vue.nextTick/this.$nextTick(callback)
          //nextTick指的是new Vue 渲染dom结束之后才执行回调函数
              created () {
                  fetch('./data.json')
                      .then( res => res.json())
                      .then( data => {
                              this.lists = data
                              /*
                                  解决方案3:  【推荐】
                                  Vue内部提供了一个Vue.nextTick/this.$nextTick(callback)
                                  nextTick指的是new Vue 渲染dom结束之后才执行回调函数
                              */
                              this.$nextTick(() => {
                                  this.swiper = new Swiper ('.swiper-container', {
                                      loop: true, // 循环模式选项
                                      
                                      // 如果需要分页器
                                      pagination: {
                                      el: '.swiper-pagination',
                                      },
                                      
                                      // 如果需要前进后退按钮
                                      navigation: {
                                      nextEl: '.swiper-button-next',
                                      prevEl: '.swiper-button-prev',
                                      },
                                      
                                      // 如果需要滚动条
                                      scrollbar: {
                                      el: '.swiper-scrollbar',
                                      },
                                  })    
                              })
                      })
                      .catch( error => {
                          if( error ) throw error 
                          })
                  },
      
  • 销毁阶段: 有2个钩子函数 (组件销毁就会触发这两个)

    • beforeDestory: 组件即将销毁,准备调用 $destroy() 方法
            <template id="hello">
              <div>
                  <button @click = 'destory'> 销毁 </button>
                  <input type="text" v-model = "money">
                  <h3> {{ money }} </h3>
              </div>
            </template>
                methods: {
                  destory () {
                      this.$destroy()
                }
      
          methods: {
              destory () {
                  this.$destroy()
              }
          }
      
    • destoryed: 组件销毁结束
      • 这两个钩子函数没有什么去别,功能很相似
            <div id="app">
                <button @click = "flag = false"> 销毁 </button>
                <Hello v-if = "flag"></Hello>
            </div>
            <template id="hello">
                <div>
                <input type="text" v-model = "money">
                <h3> {{ money }} </h3>
                </div>
            </template>
        
            new Vue({
                // el: '#app',
                data: {
                    msg: 'hello 1902',
                    flag: true
                }
            }).$mount('#app')
        
    • 项目中:
      • 这两个钩子函数都可以用来做善后,把一些计时器,第三方库实例化出来的实例进行清理
        this.time = setInterval( () => {
            console.log( 1 )
        },1000)
      
            destroyed () {
                clearInterval( this.time )
                console.log( 'destroyed')
            }
      
    • 组件销毁的两种方式:
      1. 使用$destroy()方法(内部销毁)
        缺点: 会将组件的模板也保留下来
      2. 使用开关销毁(外部销毁)
        v-if
        这种类型的销毁不会留有模板
  • 有一个钩子函数可以不写,这个钩子函数就是我们 render 函数

swiper案例()
  • 数据是静态的
    <div id="app">
        <div class="swiper-container">
                <div class="swiper-wrapper" >
                        <div class="swiper-slide" v-for='item in img_url' :style="item | changge_url "></div>
                </div>
                <div class="swiper-pagination"></div>
        </div>
            
    </div>
    new Vue({
        el:'#app',
        data() {
            return {
                img_url:[
                    'img/nature1.jpg',
                    'img/nature2.jpg',
                    'img/nature3.jpg',
                    'img/nature4.jpg',
                    'img/nature5.jpg'
                ]
            }
        },
        filters:{
            changge_url(val){
                    return `background-image:url(${val})`

            }
        },
        mounted() {
            // var swiper = new Swiper('.swiper-container', {
            //如果想在全局使用swiper 则就将他给放在this上面,而不是给其定义变量 
            this.swiper = new Swiper('.swiper-container', {
                effect: 'cube',
                grabCursor: true,
                cubeEffect: {
                    shadow: true,
                    slideShadows: true,
                    shadowOffset: 20,
                    shadowScale: 0.94,
                },
                pagination: {
                    el: '.swiper-pagination',
                },
            });

        },
    })
  • 数据是动态的
    <div id="app">
        <div class="swiper-container">
            <div class="swiper-wrapper">
                <div class="swiper-slide" v-for='item in img_url' :style="item | changge_url "></div>
            </div>
            <div class="swiper-pagination"></div>
        </div>

    </div>
    new Vue({
        el: '#app',
        data() {
            return {
                img_url: null,
                money:100
            }
        },
        filters: {
            changge_url(val) {
                return `background-image:url(${val})`
            }
        },
        created() {
            fetch('./data.json')
                .then(res => res.json() )
                .then((data) => {
                    this.img_url = data;
                      this.$nextTick(()=>{
                        this.swiper = new Swiper('.swiper-container', {
                             effect: 'cube',
                             grabCursor: true,
                             cubeEffect: {
                                 shadow: true,
                                 slideShadows: true,
                                 shadowOffset: 20,
                                 shadowScale: 0.94,
                             },
                             pagination: {
                                 el: '.swiper-pagination',
                             },
                         });
                     })
                })
                .catch((err) => {
                    if (err)
                        console.log(err)
                })
        },
        updated() {
        },
    })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值