最近一直在加班,都没时间学习,真的是对于vue的知识没有多少进步,昨天还在公司加班,今天抽空学习一下生命周期吧。
生命周期基本介绍
官方文档相关介绍生命周期。
还是先举例子:
<template>
<div class="app-container">
<div>
<h2>{{message}}</h2>
</div>
</div>
</template>
<script>
export default {
data() {
return {
message: "测试生命周期以及路由"
};
},
computed: {
route () {
return this.$route
}
},
beforeRouteEnter(to, from, next) {
console.group("父组件beforeRouterEnter 路由进入===============》");
console.log("%c%s", "color:red", "this : " + this);
next(vm => {
});
},
beforeRouteUpdate(to, from, next) {
console.group("父组件beforeRouterUpdate 路由更新===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
next(vm => {
});
},
beforeRouteLeave(to, from, next) {
console.group("父组件beforeRouteLeave 路由离开===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
next(vm => {
});
},
beforeCreate() {
console.group("父组件beforeCreate 创建前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
var self = this;
setTimeout(()=>{
self.message = '修改父组件'
}, 1000)
},
created() {
console.group("父组件created 创建完毕状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeMount() {
console.group("父组件beforeMount 挂载前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
mounted() {
console.group("父组件mounted 挂载结束状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeUpdate() {
console.group("父组件beforeUpdate 更新前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
updated() {
console.group("父组件updated 更新完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
beforeDestroy() {
console.group("父组件beforeDestroy 销毁前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
destroyed() {
console.group("父组件destroyed 销毁完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
}
};
</script>
<style lang="scss" scoped>
</style>
进入路由页面
得到结果:
- beforecreated:el 和 data 并未初始化
- created:完成了 data 数据的初始化,el没有
- mounted :完成了 el 和 data 初始化
离开当前路由
得到结果:
包含子组件的生命周期
<template>
<div class="app-container">
<div>
<h2>{{message}}</h2>
<search-condition></search-condition>
</div>
</div>
</template>
<script>
import SearchCondition from "./SearchCondition";
export default {
components: {
'search-condition': SearchCondition
},
data() {
return {
message: "测试生命周期以及路由"
};
},
computed: {
route() {
return this.$route;
}
},
beforeRouteEnter(to, from, next) {
console.group("父组件beforeRouterEnter 路由进入===============》");
console.log("%c%s", "color:red", "this : " + this);
next(vm => {});
},
beforeRouteUpdate(to, from, next) {
console.group("父组件beforeRouterUpdate 路由更新===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
next(vm => {});
},
beforeRouteLeave(to, from, next) {
console.group("父组件beforeRouteLeave 路由离开===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
next(vm => {});
},
beforeCreate() {
console.group("父组件beforeCreate 创建前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
// var self = this;
// setTimeout(() => {
// self.message = "修改父组件";
// }, 1000);
},
created() {
console.group("父组件created 创建完毕状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeMount() {
console.group("父组件beforeMount 挂载前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
mounted() {
console.group("父组件mounted 挂载结束状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeUpdate() {
console.group("父组件beforeUpdate 更新前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
updated() {
console.group("父组件updated 更新完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
beforeDestroy() {
console.group("父组件beforeDestroy 销毁前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
destroyed() {
console.group("父组件destroyed 销毁完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
}
};
</script>
<style lang="scss" scoped>
</style>
<template>
<el-card shadow="never">
<h2>{{message}}</h2>
<div class="search-condition">
<!-- 查询操作 -->
<div class="search-condition-buttons">
<el-input v-model="filterInfo" placeholder="请输入" clearable></el-input>
</div>
</div>
</el-card>
</template>
<script>
export default {
name: "SearchCondition",
components: {},
data() {
return {
message: '子组件',
filterInfo: ""
};
},
beforeCreate() {
console.group("子组件beforeCreate 创建前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //undefined
console.log("%c%s", "color:red", "message: " + this.message);
// var self = this;
// setTimeout(()=>{
// self.message = '子组件修改'
// }, 1000)
},
created() {
console.group("子组件created 创建完毕状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeMount() {
console.group("子组件beforeMount 挂载前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
mounted() {
console.group("子组件mounted 挂载结束状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeUpdate() {
console.group("子组件beforeUpdate 更新前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
updated() {
console.group("子组件updated 更新完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
beforeDestroy() {
console.group("子组件beforeDestroy 销毁前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
destroyed() {
console.group("子组件destroyed 销毁完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
methods: {
// 点击事件
onSearchClick() {
this.$emit("onSearchClick", this.filterInfo);
}
}
};
</script>
<style lang="stylus">
.el-card__body {
padding: 0px !important;
}
</style>
<style lang="stylus" scoped>
.el-card__body {
padding: 0px !important;
}
</style>
得到结果:
- 子组件的创建在父组件beforeMount之后,而不是在父组件create之后
- 父组件挂载必须在子组件挂载成功之后才会开始
父组件更新data
将父组件的setTimeout函数注释去掉
得到结果:
- 父组件的页面重新渲染不会影响到子组件
子组件更新data
注释父组件的setTimeout,将子组件的setTimeout事主是去掉
得到结果
- 子组件的页面重新渲染不会影响到父组件
父组件更新传递给子组件的prop
修改代码,子组件接受父组件的props
<search-condition :parentMessage="childMessage"></search-condition>
父组件在1000ms之后修改子组件的props,并且子组件接受该参数在页面显示
var self = this;
setTimeout(() => {
self.childMessage = "修改子组件props";
}, 1000);
得到结果:此时产生两次父组件的更新,一次子组件的更新
猜测:父组件的第一次更新为父组件向子组件传递值的内容变化引起,第二次为子组件页面的重新渲染引起。为了侧面查看,我在父子组件的输出内容里,输出了子组件的parentMessage属性值。
输出结果:父组件的第二次更新为子组件渲染过程
父组件beforeUpdate 更新前状态===============》
index.vue?6c72:83 更新子组件的prop
index.vue?6c72:86 父组件updated 更新完成状态===============》
index.vue?6c72:91 更新子组件的prop
index.vue?6c72:78 父组件beforeUpdate 更新前状态===============》
index.vue?6c72:82 message: 测试生命周期以及路由
index.vue?6c72:83 更新子组件的prop
index.vue?ee1d:60 子组件beforeUpdate 更新前状态===============》
index.vue?ee1d:65 修改子组件props
index.vue?ee1d:68 子组件updated 更新完成状态===============》
index.vue?ee1d:73 修改子组件props
index.vue?6c72:86 父组件updated 更新完成状态===============》
index.vue?6c72:91 修改子组件props
问题:子路由创建数据然后跳转父路由列表,父路由上的设置依然存在
这个问题的来源为:项目开发中,碰到主页面为数据列表,带有查询条件以及分页信息,主页面可以跳转到添加页面,添加页面数据之后,跳转回到列表页面,不想之前的查询信息以及分页信息会改变。
这里需要将主列表数据页面设置成父路由,然后添加页面设置为子路由,为了在渲染子路由页面的时候父路由信息不显示,需要使用v-show进行处理,但是不能使用v-if。v-if会造成页面的重新渲染。
<template>
<!-- 父组件 -->
<div class="app-container">
<div v-show="route.path === `/example/tree`">
<h2>{{message}}</h2>
<SearchCondition></SearchCondition>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
<router-link :to="`create`" append>
<el-button type="primary" class="model-list-actions-button">
添加
</el-button>
</router-link>
</div>
<router-view/>
</div>
</template>
<script>
import SearchCondition from "./SearchCondition";
import "./Utils";
export default {
components: {
SearchCondition
},
data() {
return {
message: "测试生命周期以及路由",
tableData: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄"
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄"
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄"
},
{
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1516 弄"
}
]
};
},
computed: {
route () {
return this.$route
}
},
beforeRouteEnter(to, from, next) {
console.group("父组件beforeRouterEnter 路由进入===============》");
console.log("%c%s", "color:red", "this : " + this); //undefined
next(vm => {
//某些不可告人的操作
});
},
beforeRouteUpdate(to, from, next) {
console.group("父组件beforeRouterUpdate 路由更新===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //undefined
console.log("%c%s", "color:red", "message: " + this.message);
next(vm => {
//某些不可告人的操作
});
},
beforeRouteLeave(to, from, next) {
console.group("父组件beforeRouteLeave 路由离开===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //undefined
console.log("%c%s", "color:red", "message: " + this.message);
next(vm => {
//某些不可告人的操作
});
},
beforeCreate() {
console.group("父组件beforeCreate 创建前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //undefined
console.log("%c%s", "color:red", "message: " + this.message);
// var self = this;
// setTimeout(()=>{
// self.message = '修改父组件'
// }, 1000)
},
created() {
console.group("父组件created 创建完毕状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeMount() {
console.group("父组件beforeMount 挂载前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
mounted() {
console.group("父组件mounted 挂载结束状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeUpdate() {
console.group("父组件beforeUpdate 更新前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
updated() {
console.group("父组件updated 更新完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
beforeDestroy() {
console.group("父组件beforeDestroy 销毁前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
destroyed() {
console.group("父组件destroyed 销毁完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
}
};
</script>
<style lang="scss" scoped>
</style>
<template>
<el-card shadow="never">
<h2>{{parentMessage}}</h2>
<div class="search-condition">
<!-- 查询操作 -->
<div class="search-condition-buttons">
<el-input v-model="filterInfo" placeholder="请输入" clearable></el-input>
</div>
</div>
</el-card>
</template>
<script>
export default {
name: "SearchCondition",
props: {
parentMessage: {
type: String
}
},
components: {},
data() {
return {
message: '子组件',
filterInfo: ""
};
},
beforeCreate() {
console.group("子组件beforeCreate 创建前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //undefined
console.log("%c%s", "color:red", "message: " + this.message);
// var self = this;
// setTimeout(()=>{
// self.message = '子组件修改'
// }, 1000)
},
created() {
console.group("子组件created 创建完毕状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeMount() {
console.group("子组件beforeMount 挂载前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
mounted() {
console.group("子组件mounted 挂载结束状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
},
beforeUpdate() {
console.group("子组件beforeUpdate 更新前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
console.log(this.parentMessage)
},
updated() {
console.group("子组件updated 更新完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
console.log(this.parentMessage)
},
beforeDestroy() {
console.group("子组件beforeDestroy 销毁前状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
console.log(this.parentMessage)
},
destroyed() {
console.group("子组件destroyed 销毁完成状态===============》");
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
},
methods: {
// 点击事件
onSearchClick() {
this.$emit("onSearchClick", this.filterInfo);
}
}
};
</script>
<style lang="stylus">
.el-card__body {
padding: 0px !important;
}
</style>
<style lang="stylus" scoped>
.el-card__body {
padding: 0px !important;
}
</style>
联系:从上面的生命周期可以看到当路由重新跳转到主路由的时候,会有着对应生命周期方法触发,所有对于列表数据的更新只需要在对应生命周期方法执行就可以了。
之前有看过keep-alive也有着类似的效果,还没有去研究过,后面去学习吧。希望年后回来找个好工作!
参照:
- https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90
- https://segmentfault.com/a/1190000008010666?utm_source=tag-newest