• VUE 生命周期


    VUE的那些状态翻译过来就是 

    创建前,
    创建完成,
    装载前,
    装载完成,
    更新数据时,
    销毁前,
    销毁完成。

    如下:

    beforeCreate

    在这个钩子函数里,只是刚开始初始化实例,你拿不到实例里的任何东西,比如data和methods和事件监听等。

    data: {
        msg: 'linlin'
      },
      methods: {
        getLists(){
          return 'aaa'
        }
      },
      beforeCreate() {
        console.log('beforeCreate',this.msg,this.getLists())
      }

    运行上面代码,控制台报错

    因为就像前面说的这个钩子函数里拿不到data和methods

    created

    在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el属性目前不可见。

    这是最早能拿到实例里面的数据和方法的一个钩子函数。应用场景:异步数据的获取和对实例数据的初始化操作都在这里面进行

    data: {
        msg: 'linlin',
        imgs: null
      },
    methods: {
        getLists(){
          this.$http.get(url).then(res=>{
            this.imgs = res.data.lists
            console.log(this.imgs)
          })
        }
      },
      created() {
        this.getLists()
      }

    beforeMount

    在挂载开始之前被调用:相关的render函数首次被调用

    不论是created还是beforeMount在它们里面都拿不到真实的dom元素,如果我们需要拿到dom元素就需要在mounted里操作

    <div id="app">
          <ul>
            <li v-for="(item,index) in arr" :key="index">{{item}}</li>
          </ul>
        </div>
    <script>
    let app = new Vue({
     data: {
        arr: [1,2,3]
      },
    created() {
        console.log('created',document.querySelectorAll('li').length)
      },
      beforeMount() {
        console.log('beforeMount',document.querySelectorAll('li').length)
      },
      mounted() {
        console.log('mounted',document.querySelectorAll('li').length)
      },
    })
    </script>

    mounted

    上面的案例mounted可以拿到dom元素,但也只是能拿到初始化数据里的dom元素,如果是存在异步对dom元素数据进行更改我们就只能在updated里获取,应用场景:初始数据(在data中有的)的dom渲染完毕,可以获取dom

    <div id="app">
          <ul>
            <li v-for="(item,index) in arr" :key="index">{{item}}</li>
          </ul>
        </div>
    
    created() {
        setTimeout(()=>{
          this.arr = [4,5,6,7]
          console.log('created',document.querySelectorAll('li').length)
        })   
      },
      mounted() {
        console.log('mounted',document.querySelectorAll('li').length)
      }

    执行上面代码,发现不管是mounted还是created里拿到的都是3,而不是4

    这里之所以先打印出mounted是因为created里面的是异步操作所以最后才执行完,而我们如果想要拿到正确的dom元素的个数就需要在updated里面获取

    updated(){
      console.log('updated',document.querySelectorAll('li').length)
    }

    另外$children子组件的获取也需要在mounted里

    beforeUpdate

    当数据更新后出发的钩子函数,这个钩子函数里拿到的是更改之前的数据,虚拟DOM重新渲染和打补丁之前被调用。

    你可以在这个钩子中进一步地修改data,这不会触发附加的重渲染过程。

    updated

    上面虽然能在update里拿到更改后的数据,但是并不建议在这里面进行对异步数据得到的dom操作,因为有可能你当前的数据不止更改一次,而update只要相关的数据更改一次就会执行一次,注意:updated是指mouted钩子后(包括mounted)的数据更改,在created里的数据更改不叫更改叫做初始化,所以我们下面在created里修改数据是通过一个异步来确保updated可以执行的。我们一般都是在事件方法里更改数据,然后通过updated对其操作。应用场景:如果dom操作依赖的数据是在异步操作中获取,并且只有一次数据的更改 ,也可以说是数据更新完毕:如果对数据更新做一些统一处理在updated钩子中处理即可。

    注意:当这个钩子被调用时,组件DOM的data已经更新,所以你现在可以执行依赖于DOM的操作。但是不要在当前钩子里修改当前组件中的data,否则会继续触发beforeUpdate、updated这两个生命周期,进入死循环!

    created() {
        setTimeout(()=>{
          this.arr = [4,5,6,7]
          console.log('created',document.querySelectorAll('li').length)
        })
        setTimeout(()=>{
          this.arr = [10,11,12,13,14]
          console.log('created',document.querySelectorAll('li').length)
        },1000)    
      },
    beforeUpdate() {
        console.log('beforeUpdate',document.querySelectorAll('li').length)
      },
      updated() {
        console.log('updated',document.querySelectorAll('li').length)
      },

    上面updated执行了两遍,之所以一开始created是3是因为上面我们说的他是在一个异步里,也是在mouted后获取的所以是3。

    在事件方法里更改数据

    <div id="app">
          <ul>
            <li v-for="(item,index) in arr" :key="index" @click="getAdd">{{item}}</li>
          </ul>
          <div>{{msg}}</div>
        </div>
    
    data: {
        arr: [1,2,3],
      },
      methods: {
        getAdd(){
          this.arr = [4,5,6,7]
        }
      },
      updated() {
        console.log(this.arr)
      }

    如果想分别区别不同的数据更新,同时要对dom进行操作那么需要使用nextTick函数处理

    created() {
        setTimeout(()=>{
          this.arr = [4,5,6,7]
          this.$nextTick(()=>{
            console.log('nextTick',document.querySelectorAll('li').length)
          })
        })
        setTimeout(()=>{
          this.arr = [10,11,12,13,14]
          this.$nextTick(()=>{
            console.log('nextTick',document.querySelectorAll('li').length)
          })
        },1000)
            
      },

    这样我们想对哪一次的数据进行操作就直接在this.$nextTick里面写就行

    在updated中修改数据陷入死循环

    <div id="app">
        {{a}}
        <button @click="a=2">点我</button>
      </div>
      <script>
        new Vue({
          el: '#app',
          data: {
            a: [1]
          },
          beforeUpdate() {
            console.log('beforeUpdate')
          },
          updated() {
            console.log(this.a)
            console.log('updated')
            this.a = [2]
    
          },
        })
      </script>

    updated,watch和nextTick区别

    updated对所有数据的变化进行统一处理

    watch对具体某个数据变化做统一处理

    nextTick是对某个数据的某一次变化进行处理

     

    如果实例里面没写el挂载点你就需要在实例后面通过.$mount('#app')来手动触发

    beforeDestroy

    实例销毁之前调用。在这一步,实例仍然完全可用

    destroyed

    Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    beforeDestroy和destroyed只能通过手动触发$destroy来调用

    let app = new Vue({
      beforeDestroy() {
        console.log('beforeDestroy')
      },
      destroyed() {
        console.log('destroyed')
      }
    
    })
    app.$destroy()
    @转发至知乎:https://zhuanlan.zhihu.com/p/53039906
  • 相关阅读:
    记录爱忘记的STL知识点
    小狼
    CVTE总结
    STL底层实现
    小狼,你家BOSS喊你面试啦!!!(四)
    npm属性笔记
    iview中关于table组件内放入Input会失去焦点
    js实现数组内数据的上移和下移
    google搜索使用技巧
    bat中实现代码拷贝到指定目录后启动命令行并更改默认路径
  • 原文地址:https://www.cnblogs.com/chenwolong/p/14070053.html
Copyright © 2020-2023  润新知