浅谈vue —— 生命周期

本文详细介绍了Vue.js中的生命周期钩子函数,包括beforeCreate、created、beforeMount、mounted等,并通过示例代码展示了它们的执行时机及用途。

记于vue生命周期的学习

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

比如我们经常用到的created钩子:

export default { 
    created() { 
        ...在这里我们通常发起异步请求,得到数据 
        
    } 
    
} 


<!--注意-->
<!--
    这里的created函数不能使用箭头函数,因为箭头函数中的this指向的是上一级的this。
-->
复制代码

接下来我们看一下有哪些钩子函数:

方法作用
beforeCreate组件实例刚被创建,在data属性之前。
created组件实例创建完成,data属性、computed、props、methods、watch已绑定,但DOM还未生成。
beforeMount
mountedDOM已生成,但不保证已全部挂载在document中(用this.$nextTick 可以保证已经在document中)
beforeUpdate
updated更新时触发
beforeDestroy组件销毁之前触发 (可以用于清除定时器,取消全局的注册事件),此时的this还是指向vue实例
destroyed此时的this不指向vue实例

单个组件的生命周期

<template lang="html">
    <div class="life-cycle">
        <h1 ref="title">lifr-cycle</h1>

        <h2>{{ a }} {{watchVal}}</h2>

        <ul>
            <li v-for="(item, index) in data" ref="item" @click="setNumber(index)">{{ item }}</li>
        </ul>

        <button type="button" name="button" @click="setData">设置item的个数</button>
        
        <!--<child-file-cycle :data="data"></child-file-cycle>-->
    </div>
</template>

<script>

let oDDEven = true;

import {mapGetters} from "vuex"
import childFileCycle from "./childFileCycle"
export default {
    data() {
        return {
            number: 1,
            watchVal: 1,
            data: ["Hellow"]
        }
    },
    computed: {
        ...mapGetters([
            "value"
        ]),
    },
    // 组件实例刚被创建,在data属性之前。
    beforeCreate() {
        this.a = "a"
        console.log(this.$el, "---", this.data, "---", "beforeCreate", "---", this.$refs.title, "---", this.value);
    },
    // 组件实例创建完成,data属性、computed、props、methods、watch已绑定,但DOM还未生成。
    created() {
        setTimeout(() => {
            this.data = ["Javascript", "Java", "PHP"];
        }, 3000);

        console.log(this.watchVal);
        console.log(this.$el, "---", this.data, "---", "created", "---", this.$refs.title, "---", this.value);
    },
    beforeMount() {
        console.log(this.$el, "---", this.data, "---", "beforeMount", "---", this.$refs.title, "---", this.value);
    },
    // DOM已生成,但不保证已全部挂载在document中(用this.$nextTick 可以保证已经在document中)
    mounted() {
        this.$nextTick(() => {
            console.log(this.$el, "---", this.data, "---", "mounted", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
        })
        console.log(this.$el, "---", this.data, "---", "mounted", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
    },
    beforeUpdate() {
        console.log(this.$el, "---", this.data, "---", "beforeUpdate", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
    },
    // 更新时触发
    updated() {
        console.log(this.$el, "---", this.data, "---", "update", "---", this.$refs.title, "---", this.$refs.item, "---", this.value);
    },
    beforeDestroy() {
        console.log(this.$el, "---", this.data, "---", "beforeDestory", "---", this.$refs.title);
    },
    destroyed() {
        console.log(this.$el, "---", this.data, "---", "destroyed", "---", this.$refs.title);
    },
    methods: {
        setNumber(index) {
            this.number = index;
            console.log(index);
        },
        setData() {
            if (oDDEven) {
                this.data = ["hellow"];
                oDDEven = false;

                return;
            }

            this.data = ["Javascript", "Java", "PHP"];
            oDDEven = true;
        }
    },
    watch: {
        watchVal: function(newVal, oldVal) {
            return newVal;
        }
    },
    components: {
        childFileCycle
    }
}
</script>

<style lang="css">
</style>

复制代码

由上述执行结果:
我们可以得出,每一个vue实例都会执行beforeCreat、created、beforeMount、mounted这四个钩子并且只执行一次,
再有数据(必须是与视图绑定的数据)更新的时候才会执行beforeUpdate、updated这两个钩子,
beforeDestroy、destroyed在视图销毁的时候触发。
复制代码
子组件
<template lang="html">
    <div class="child-file-cycle">
        <h2>child-file-cycle</h2>
        <div class="">
            child - {{ number }}
        </div>
        <button type="button" name="button" @click="setNumber">setNumber</button>
        <ul>
            <li v-for="(item, index) in data" ref="item" @click="setNumber(index)">child - {{ item }}</li>
        </ul>
    </div>
</template>

<script>
export default {
    props: {
        data: {
            type: Array,
            default: []
        }
    },
    data() {
        return {
            number: Math.random()
        }
    },
    computed: {
    },
    // 组件实例刚被创建,在data属性之前。
    beforeCreate() {
        console.log("beforeCreate");
    },
    // 组件实例创建完成,data属性、computed、props、methods、watch已绑定,但DOM还未生成。
    created() {
        console.log("created", this.data);
    },
    beforeMount() {
        console.log("beforeMount");
    },
    // DOM已生成,但不保证已在document中(用this.$nextTick 可以保证已经在document中)
    mounted() {
        console.log("mounted");
    },
    beforeUpdate() {
        console.log("beforeUpdate");
    },
    // 更新时触发
    updated() {
        console.log("update");
    },
    beforeDestroy() {
        console.log("beforeDestory");
    },
    destroyed() {
        console.log("destroyed");
    },
    methods: {
        setNumber() {
            this.number = Math.random();
        }
    }
}
</script>

<style lang="css">
</style>

复制代码

在父组件的beforeMount钩子之后会执行子组件一系列的钩子函数,将子组件挂载在父组件之后,再将父组件挂载。


更新props影响的钩子函数

更新props的值的时候,会触发父组件的beforeUpdate,同时也会触发子组件的beforeUpadte、updated钩子,最后触发父组件的updated钩子。


再一次感谢您花费时间阅读这份稿!

作者 [@xinwuliu][2]
2018 年 05月 08日

转载于:https://juejin.im/post/5aeff61cf265da0b9f403358

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值