前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你绝对不知道 Vue 也有生老病死

你绝对不知道 Vue 也有生老病死

作者头像
公众号---人生代码
发布2020-12-15 10:56:41
5470
发布2020-12-15 10:56:41
举报
文章被收录于专栏:人生代码

生命周期钩子

从今天开始我们开始学习 Vue 生命周期钩子,就像人的一生一样短暂,充满着未知情况,从一开始的出生,小孩,少年,青年,中年,晚年,直到死亡那刻来临,每一个阶段都会处理不同的事情,人的整个生涯就算走完。Vue 实例也一样有着一个完整的生命周期,也就是说从开始创建,初始化数据,编译模板,挂载DOM,渲染-更新-渲染,卸载等一系列过程,构成为 Vue 实例的生命周期,钩子就是在某个阶段做一些处理。

beforCreate (创建前)

在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还没创建,其中 data, el 并没有被初始化,因此没有办法获取 methods, data, computed, watch 等上的方法,属性。

我们先在 src/main.js 写下代码:

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  beforeCreate() {
    console.log("beforeCreate", "this.data===", this.data, "$el=====" , this.$el)
  }
})

app.use(store).use(router).mount('#app')

运行之后,我们看到控制台打印的数据如下:

代码语言:javascript
复制
beforeCreate this.data=== undefined $el===== null

created(创建后)

此时实例已经创建完成之后被调用,在这一步,实例已完成以下配置:数据观测,计算属性,watch/event 事件监听,完成 data 数据的初始化, el 此时还没挂载,所以不可见,这是一个常见的生命周期,因为你可以调用 methods 中方法,改变 data 中的数据,并且修改可以通过 Vue 响应式绑定在页面上,获取计算属性等,在这个期间我们可以做一些数据请求等。

我们继续向上面的代码添加 created:

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  beforeCreate() {
    console.log("beforeCreate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  created() {
    console.log("created", "this.$data===", this.$data, "$el=====" , this.$el)
  }
})

app.use(store).use(router).mount('#app')

我们看到控制台打印的数据如下:

代码语言:javascript
复制
beforeCreate this.$data=== {} $el===== null
created this.$data=== Proxy {a: 1, b: {…}}[[Handler]]: Object[[Target]]: Objecta: 1b: name: "haha"__proto__: Object__proto__: Object[[IsRevoked]]: false $el===== null

beforeMount(挂载之前)

挂载元素之前被调用,相关的 render 函数首次被调用(虚拟DOM),实例已经完成模板编译,把 data 里面的数据和模板,指令等生成 html, 完成 el 和 data 初始化,注意此时还没将 html 渲染到页面上。

我们继续向上面的代码:

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  beforeCreate() {
    console.log("beforeCreate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  created() {
    console.log("created", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeMount() {
    console.log("beforeMount", "this.$data===", this.$data, "$el=====" , this.$el)
  }
})

app.use(store).use(router).mount('#app')

此时控制台打印的数据如下:

代码语言:javascript
复制
beforeMount this.$data=== Proxy {a: 1, b: {…}} $el===== null

mounted(挂载之后)

挂载完成之后调用,也就是模板中的 HTML 已经渲染到页面上来了,此时一般可以做一些操作DOM,ajax 请求,mounted 只会执行一次。

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  beforeCreate() {
    console.log("beforeCreate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  created() {
    console.log("created", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeMount() {
    console.log("beforeMount", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  mounted() {
    console.log("mounted", "this.$data===", this.$data, "$el=====" , this.$el)
  }
})

app.use(store).use(router).mount('#app')

我们在控制台打印的数据如下:

代码语言:javascript
复制
mounted this.$data=== Proxy {a: 1, b: {…}} $el===== #text

beforeUpdate(更新之前)

在数据更新之前被调用,发生在虚拟的 DOM 重新渲染和打补丁之前,可以在该钩子进行更改状态,不会触发附加的重复渲染过程。

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  beforeCreate() {
    console.log("beforeCreate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  created() {
    console.log("created", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeMount() {
    console.log("beforeMount", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  mounted() {
    console.log("mounted", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeUpdate() {
    this.b = {}
    console.log("beforeUpdate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
})

app.use(store).use(router).mount('#app')

updated(更新之后)

在由于数据更改导致地虚拟DOM重新渲染和打补丁只会调用,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作,然后在大多是情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环,该钩子在服务器端渲染期间不被调用。

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  beforeCreate() {
    console.log("beforeCreate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  created() {
    console.log("created", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeMount() {
    console.log("beforeMount", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  mounted() {
    console.log("mounted", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeUpdate() {
    this.b = {}
    console.log("beforeUpdate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  updated() {
    console.log("update", "this.$data===", this.$data, "$el=====" , this.$el)
  },
})

app.use(store).use(router).mount('#app')


beforeUnmount(销毁前)

在实例销毁之前调用,实例仍然完全可用,

  1. 这一步还可以用this来获取实例,
  2. 一般在这一步做一些重置的操作,比如清除掉组件中的定时器 和 监听的dom事件
代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  beforeCreate() {
    console.log("beforeCreate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  created() {
    console.log("created", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeMount() {
    console.log("beforeMount", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  mounted() {
    console.log("mounted", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeUpdate() {
    this.b = {}
    console.log("beforeUpdate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  updated() {
    console.log("update", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeUnmount() {
    console.log("beforeDestroy", "this.$data===", this.$data, "$el=====" , this.$el)
  },
})

app.use(store).use(router).mount('#app')


unmounted(销毁之后)

在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁,该钩子在服务器端渲染期间不被调用。

代码语言:javascript
复制
import { createApp } from 'vue/dist/vue.esm-bundler.js'
// import App from './App.vue'
import router from './router'
import store from './store'
// let app = createApp(App)
let app = createApp({
  template: `
    <div>在data中监测的数据a -- {{a}}</div>
    <div>不在data中监测的数据b --- {{b}}</div>

    <props-demo-simple size="16" my-message="hahaja"></props-demo-simple>
    <props-demo-advanced :height="100" :age="100"></props-demo-advanced>
  `,
  data() {
    return {
      a: 1,
      b: {
        name: 'haha'
      }
    }
  },
  methods: {
    plus() {
      console.log(this.a + 1)
    },
    someMethod() {
      console.log("b发生变化了")
    }
  },
  beforeCreate() {
    console.log("beforeCreate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  created() {
    console.log("created", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeMount() {
    console.log("beforeMount", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  mounted() {
    console.log("mounted", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeUpdate() {
    this.b = {}
    console.log("beforeUpdate", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  updated() {
    console.log("update", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  beforeUnmount() {
    console.log("beforeDestroy", "this.$data===", this.$data, "$el=====" , this.$el)
  },
  unmounted() {
    console.log("unmounted", "this.$data===", this.$data, "$el=====" , this.$el)
  }
})

app.use(store).use(router).mount('#app')

activated

被 keep-alive 缓存的组件激活时调用。

该钩子在服务器端渲染期间不被调用。

deactivated

被 keep-alive 缓存的组件停用时调用。

该钩子在服务器端渲染期间不被调用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 生命周期钩子
    • beforCreate (创建前)
      • created(创建后)
        • beforeMount(挂载之前)
          • mounted(挂载之后)
            • beforeUpdate(更新之前)
              • updated(更新之后)
                • beforeUnmount(销毁前)
                  • unmounted(销毁之后)
                    • activated
                      • deactivated
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档