vue学习之五生命周期

一、vue生命周期图解

下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。

二、vue钩子函数使用

2.1beforeCreate

在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>

</head>
<body>

    <div id="app">
        {{ message }}
    </div>

    <script>

        new Vue({
            el: "#app",
            data: {
                message: "Hello Vue",
            },
            methods: {
                myInit: function () {
                    console.log(this.message);
                }
            },
            beforeCreate(){
                console.group('beforeCreate: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            }
        })
    </script>
</body>
</html>

  

2.2created

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

!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>

</head>
<body>

    <div id="app">
        {{ message }}
    </div>

    <script>

        new Vue({
            el: "#app",
            data: {
                message: "Hello Vue",
            },
            methods: {
                myInit: function () {
                    console.log(this.message);
                }
            },
            beforeCreate(){
                console.group('beforeCreate: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            created(){
                console.group('created: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            }
        })
    </script>
</body>
</html>

  

2.3beforeMount

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>

</head>
<body>

    <div id="app">
        {{ message }}
    </div>

    <script>

        new Vue({
            el: "#app",
            data: {
                message: "Hello Vue",
            },
            methods: {
                myInit: function () {
                    console.log(this.message);
                }
            },
            beforeCreate(){
                console.group('beforeCreate: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            created(){
                console.group('created: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            beforeMount(){
                console.group('beforeMount: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            }
        })
    </script>
</body>
</html>

  

2.4mounted

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>

</head>
<body>

    <div id="app">
        {{ message }}
    </div>

    <script>

        new Vue({
            el: "#app",
            data: {
                message: "Hello Vue",
            },
            methods: {
                myInit: function () {
                    console.log(this.message);
                }
            },
            beforeCreate(){
                console.group('beforeCreate: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            created(){
                console.group('created: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            beforeMount(){
                console.group('beforeMount: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            mounted(){
                console.group('mounted: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            }
        })
    </script>
</body>
</html>

  

2.5beforeUpdate

数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。

!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>

</head>
<body>

    <div id="app">
        {{ message }}
        <button @click="myClick">点击修改欢迎语</button>
    </div>

    <script>

        new Vue({
            el: "#app",
            data: {
                message: "Hello Vue",
            },
            methods: {
                myInit: function () {
                    console.log(this.message);
                },
                myClick: function () {
                    this.message = "Hello World";
                }
            },
            beforeCreate(){
                console.group('beforeCreate: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            created(){
                console.group('created: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            beforeMount(){
                console.group('beforeMount: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            mounted(){
                console.group('mounted: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            beforeUpdate(){
                console.group('beforeUpdate: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
                console.log("beforeData: ", document.getElementById("app").innerHTML);
            }
        })
    </script>
</body>
</html>

  

该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行

2.6updated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>

</head>
<body>

    <div id="app">
        {{ message }}
        <button @click="myClick">点击修改欢迎语</button>
    </div>

    <script>

        new Vue({
            el: "#app",
            data: {
                message: "Hello Vue",
            },
            methods: {
                myInit: function () {
                    console.log(this.message);
                },
                myClick: function () {
                    this.message = "Hello World";
                }
            },
            beforeCreate(){
                console.group('beforeCreate: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            created(){
                console.group('created: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            beforeMount(){
                console.group('beforeMount: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            mounted(){
                console.group('mounted: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
            },
            beforeUpdate(){
                console.group('beforeUpdate: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
                console.log("beforeData: ", document.getElementById("app").innerHTML);
            },
            updated(){
                console.group('updated: ');
                console.log('el: ', this.$el);
                console.log('data: ', this.$data);
                console.log('myInit: ', this.myInit);
                console.log('message: ', this.message);
                console.log("updated: ", document.getElementById("app").innerHTML);
            }
        })
    </script>
</body>
</html>

  

2.7activated

keep-alive 组件激活时调用。<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../statics/vue.min.js"></script>

</head>
<body>

<div id="app">

</div>

<script>

let MyLifeCycle = {
template: `
<div>
<span>这是beforeDestroy</span>
</div>
`,
created(){
console.log("created");
},
activated(){
console.log("activated");
},
deactivated(){
console.log("deactivated");
},
beforeDestroy(){
console.log("beforeDestroy");
},
destroyed(){
console.log("destroyed");
}
};

let App = {
template: `
<div>
<keep-alive>
<my-lifecycle v-if="isShow"></my-lifecycle>
</keep-alive>
<button @click="myClick">点击创建消除beforeDestroy</button>
</div>
`,
components: {
'my-lifecycle': MyLifeCycle
},
data(){
return {
isShow: true,
}
},
methods: {
myClick: function () {
this.isShow = !this.isShow;
}
}
};

new Vue({
el: "#app",
template: `<App></App>`,
data: {
message: "Hello Vue",
},
methods: {
myInit: function () {
console.log(this.message);
},
myClick: function () {
this.message = "Hello World";
}
},
components: {
App
}
})
</script>
</body>
</html>

  

2.8deactivated

keep-alive 组件停用时调用。

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../statics/vue.min.js"></script>

</head>
<body>

<div id="app">

</div>

<script>

let MyLifeCycle = {
template: `
<div>
<span>这是beforeDestroy</span>
</div>
`,
created(){
console.log("created");
},
activated(){
console.log("activated");
},
deactivated(){
console.log("deactivated");
},
beforeDestroy(){
console.log("beforeDestroy");
},
destroyed(){
console.log("destroyed");
}
};

let App = {
template: `
<div>
<keep-alive>
<my-lifecycle v-if="isShow"></my-lifecycle>
</keep-alive>
<button @click="myClick">点击创建消除beforeDestroy</button>
</div>
`,
components: {
'my-lifecycle': MyLifeCycle
},
data(){
return {
isShow: true,
}
},
methods: {
myClick: function () {
this.isShow = !this.isShow;
}
}
};

new Vue({
el: "#app",
template: `<App></App>`,
data: {
message: "Hello Vue",
},
methods: {
myInit: function () {
console.log(this.message);
},
myClick: function () {
this.message = "Hello World";
}
},
components: {
App
}
})
</script>
</body>
</html>

  

2.10destroyed

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

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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../statics/vue.min.js"></script>

</head>
<body>

    <div id="app">

    </div>

    <script>

        let MyLifeCycle = {
            template: `
                <div>
                    <span>这是beforeDestroy</span>
                </div>
            `,
            created(){
                console.log("created");
            },
            beforeDestroy(){
                console.log("beforeDestroy");
            },
            destroyed(){
                console.log("destroyed");
            }
        };

        let App = {
            template: `
                <div>
                    <my-lifecycle v-if="isShow"></my-lifecycle>
                    <button @click="myClick">点击创建消除beforeDestroy</button>
                </div>
            `,
            components: {
                'my-lifecycle': MyLifeCycle
            },
            data(){
                return {
                    isShow: true,
                }
            },
            methods: {
                myClick: function () {
                    this.isShow = !this.isShow;
                }
            }
        };

        new Vue({
            el: "#app",
            template: `<App></App>`,
            data: {
                message: "Hello Vue",
            },
            methods: {
                myInit: function () {
                    console.log(this.message);
                },
                myClick: function () {
                    this.message = "Hello World";
                }
            },
            components: {
                App
            }
        })
    </script>
</body>
</html>

  

posted @ 2018-10-30 15:17  shuyang  阅读(244)  评论(0编辑  收藏  举报