VUE 生命周期大全,包含路由器生命周期,单组件生命周期,父子组件嵌套生命周期

目录

1. 路由器生命周期(思维导图我大致画了一下)

2.单组件生命周期

3.父子组件嵌套生命周期

4.使用keep-alive场合时,进入某个页面两次触发的生命周期

5.实际使用场景

1. 路由器生命周期(思维导图我大致画了一下)

1. beforeRouteLeave => 2. beforeEach =>   3. beforeRouteUpdate => 4. beforeEnter => 

5. beforeRouteEnter => 6.beforeResolve => 7.afterEach

(组件路由:1,3,5  独享路由:4  全局路由:2,6,7)

路由的钩子函数,根据配置的地方不同,大致分为三种

第一种:全局路由 包含:

        全局前置防守:router.beforeEach,(每次路由跳转前的处理,可以用来判断当前用户是否在登录状态,开始进度条等...)

        全局解析守卫:router.beforeResolve,(每次路由跳转完毕的处理,可以用来结束进度条等...)

        全局后置防守:router.afterEach,(每次路由跳转完毕的处理,可以用来结束进度条等...)

第二种:独享路由 包含

        独享路由防守:beforeEnter (在进入路由时触发)

第三种:组件路由 包含

        组件路由:beforeRouteEnter(在渲染该组件的对应路由被验证前触发)

        组件路由:beforeRouteUpdate (在当前路由改变,但是该组件被复用时调用)

        组件路由:beforeRouteLeave(在导航离开渲染该组件的对应路由时调用)

注意:在使用的过程中,如果发现路由卡住不动的情况下,仔细检查 next 的操作

拿 beforeEnter 举例,如果你配置了 beforeEnter ,就需要设置 next() ,让它有个出口,不然它就卡住了

注意:beforeEach 里可能会因为你的写法问题,陷入无限循环,请仔细检查,确保 next 在任何情况下严格调用一次,if判断时,需严格加上else

 全局路由:

import NProgress from 'nprogress' // Progress 进度条
import { getToken } from '@/utils/auth' // 验权
import router from './router'

/*
* 确保 next 在任何给定的导航守卫中都被严格调用一次。
* 它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,
* 否则钩子永远都不会被解析或报错。
*/
router.beforeEach((to, from, next)=>{
    // 进度条开始
    NProgress.start()
    // 判断 token 是否存在
    if(getToken()){
        next()
    }else{
        next('/login')
    }
})

/*
* beforeResolve 与 beforeEach 类似
* 官方说明:它在 每次导航时都会触发,但是确保在导航被确认之前  
* 同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用。
*/
router.beforeResolve((to, from, next)=>{
    console.log(' wosjio ')
})

/*
* 这个钩子不会接受 next 函数也不会改变导航本身
*/
router.afterEach((to, from) => {
    // 进度条结束
    NProgress.done()
})

独享路由:

/*
* 直接在路由配置上定义守卫
* 只在进入路由时触发,(它们只有在 从一个不同的 路由导航时,才会被触发)。
*/
{
    path: 'password',
    name: 'password',
    component: () => import('@/views/pms/publisherInfo/password'),
    meta: {
        title: '密码管理',
        keepAlive: true 
    },
    hidden: true,
    beforeEnter: (to, from, next) => {
        console.log('my is beforeEnter')
        next()
    },
},

组件路由:

beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` !
    // 因为当守卫执行时,组件实例还没被创建!
    console.log('my is beforeRouteEnter')
    next(vm => {
        // 通过 `vm` 访问组件实例
        console.log(vm.text)
    })
},

beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
    // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
    console.log('my is beforeRouteUpdate')
    next()
},
beforeRouteLeave(to, from, next) {
    // 在导航离开渲染该组件的对应路由时调用
    // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
    console.log('my is beforeRouteLeave')
    next()
},

2.单组件生命周期

单组件页面加载时触发四个钩子 依次顺序:

beforeUpdate => updated => beforeMount => mounted

单组件页面改动时触发钩子:

beforeUpdate => updated

单组件页面离开时触发两个钩子 依次顺序:

beforeDestroy => deactivated

3.父子组件嵌套生命周期

父子组件嵌套页面加载时触发八个钩子 依次顺序:

父组件 beforeUpdate => 父组件 updated => 父组件 beforeMount =>

 子组件 beforeUpdate => 子组件 updated => 子组件 beforeMount => 子组件 mounted=> 父组件 mounted

父组件最后完成加载

父子组件嵌套页面改动时触发钩子:

修改哪个组件里的数据,就触发哪个组件内的 beforeUpdate => updated

父子组件嵌套页面离开时触发四个钩子 依次顺序:

父组件 beforeDestroy => 子组件 beforeDestroy => 子组件 deactivated  => 父组件 deactivated

父组件最后完成销毁

4.使用keep-alive场合时,进入某个页面两次触发的生命周期

第一次进入 a 触发钩子:

[a] beforeCreate => [a] created => [a] beforeMount => [a] mounted => [a] activated

跳转至 b 触发钩子:

[b] beforeCreate => [b] created => [b] beforeMount => [a] deactivated => [b] mounted => [b] activated

第二次进入 a:
[a] activated

5.实际使用场景

created:摘取路由上的参数,发送请求

mounted:获取 DOM

nextTick:数据更新后的立即执行 操作DOM相关业务

updated:任何数据的更新,如果要做统一的业务逻辑处理

beforeUpdate:编辑的数据还没有保存,询问用户是否保存后再退出当前页面

watch:监听具体数据变化,并做相应的处理

beforeCreate() {
    /*
    * 在实例初始化之后,数据观测和事件配置之前被调用,
    * 此时组件的选项对象还未创建,el 和 data 并未初始化,
    * 因此无法访问methods, data, computed等上的方法和数据。
    */
    console.log('my is beforeCreate')
},
created() {
    /*
    * 实例已经创建完成之后被调用,在这一步,实例已完成以下配置:数据观测、属性和方法的运算,watch/event事件回调,完成了data 数据的初始化,
    * 在这里可以进行调用data数据,以及方法,发送ajax一些操作
    */
    console.log('created')
},
beforeMount() {
    /*
    * DOM 渲染之前被调用,并且开始通过 render 建立虚拟 DOM
    */
    console.log('beforeMount')
},
mounted() {
    /*
    * DOM 渲染完成被调用,这时页面已经渲染完毕
    * 可以通过 ref 获取页面元素的 DOM 了
    */
    console.log('mounted')
},
beforeUpdate(){
    /*
    * 数据更新前被调用
    * data 数据有更新时,内存中重新编译了最新模板字符串,但还未重新渲染DOM
    */
    console.log('beforeUpdate')
},
updated() {
    /*
    * 数据更新完成后被调用
    * 已经重新渲染 DOM ,这时你可以继续操作 DOM
    */
    console.log('updated')
},
beforeDestroy() {
    /*
    * 实例销毁之前调用
    * 这时date内数据以及方法,过滤器等依然还可以使用
    */
    console.log('beforeDestroy')
},
destroyed() {
    /*
    * 实例销毁完成后调用
    * 实例的所有东西都会解绑销毁
    */
    console.log('deactivated')
},

欢迎同学们发表评论!

猜你喜欢

转载自blog.csdn.net/weixin_43221910/article/details/123228541