vue生命周期的理解

vue生命周期的理解

生命周期是什么?

Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

生命周期 发生了什么
beforeCreate 初始化界面前 : 在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问
created 初始化界面后 : 在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数,也就是不会更新视图,SSR可以放这里。
beforeMount 挂载前 :完成模板编译,虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated
mounted 挂在完成 : 将编译好的模板挂载到页面 (虚拟DOM挂载) ,可以在这进行异步请求以及DOM节点的访问,在vue用$ref操作
beforeUpdate 更新数据前 : 组件数据更新之前调用,数据都是新的,页面上数据都是旧的 组件即将更新,准备渲染页面 , 可以在当前阶段进行更改数据,不会造成重渲染
updated 组件更新后 : render重新渲染 , 此时数据和界面都是新的 ,要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新
beforeDestroy 组件卸载前 : 实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器
destroyed 组件卸载后 : 组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。
activited keep-alive 专属 , 组件被激活时调用
deactivated keep-alive 专属 , 组件被销毁时调用

实践:

  beforeCreate() {
    console.group("-----beforeCreate 创建前的状态-----");
    console.log("%c%s", "color:red", `el : ${this.$el}`);
    console.log("%c%s", "color:blue", this.$el);
    console.log("%c%s", "color:red", `data : ${this.$data}`);
    console.log("%c%s", "color:red", `message : ${this.messages}`);
  },
  
 ...
image.png

如果在mouted以外的函数操作DOM就会报错(vue cli 创建的),如果是直接使用CDN方式在html文件中引入vue.js就不会报错,而且在beforeMount中可以得到渲染好的模板,因为得到的是一个el实例的对象引用。

验证数据更新,在beforeUpdate和Updated钩子函数里面都加上这样一段(CDN引入vue方式):

用vue-cli 生成的项目,引用的应该是运行时版本,所以,在beforeMount阶段,控制台打印不出el, 博主用到应该是src 引入的方式,所以在控制台中,beforeMount阶段也可以打印出el, 只是此时模板中的数据任然是未替换前的占位,我已经验证,总的来说,beforeMount阶段应该是虚拟DOM,到了mounted阶段才有真实的DOM

      let text = document.getElementsByTagName('p')[0].textContent;
​      console.log(text)

然后触发函数更新:vm.message = '触发组件更新'

image.png

created钩子函数和beforeMount间的生命周期

el选项****如果有的话就继续向下编译,如果没有el选项**,则停止编译,也就意味着停止了生命周期,直到在该vue实例上调用vm.$mount(el)。此时注释掉代码中:

el: '#app',

然后运行可以看到到created的时候就停止了。

如果我们在后面继续调用vm.$mount(el),可以发现代码继续向下执行了。

    var el = document.getElementById('app')
    vm.$mount(el) //这个el参数就是挂在的dom接点

template参数选项的有无对生命周期的影响。
(1).如果vue实例对象中有template参数选项,则将其作为模板编译成render函数。
(2).如果没有template选项,则将外部HTML作为模板编译。
(3).可以看到template中的模板优先级要高于outer HTML的优先级。

这下就可以想想什么el的判断要在template之前了~是因为vue需要通过el找到对应的outer template。

在vue对象中还有一个render函数,它是以createElement作为参数,然后做渲染操作,而且我们可以直接嵌入JSX.

    <div id="app">
        <p>{{message}}</p>
    </div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'hello'
        },
        render(c){
            return c('p',`this is contentElement ----${this.message}`)
        },
        template:`<p>这是template中的innerHTML 优先级高---{{message}}</p>`,

此时页面会得到:

image.png

所以综合排名优先级:
render函数选项 > template选项 > outer HTML.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。