需求:把不同的页面封成组件,再放在el-tabs里面用标签切换。
遇到的问题:因为本质上这些页面组件都同一个页面,所以会同时执行created钩子,造成性能浪费。我想点哪个组件,就执行此页面的初始化方法。(之前碰到七个标签页的crud页面,一起调会卡顿)。
解决:用this.$refs[this.activeName].init()调用组件内的初始化方法,而不是放到created。
注意:
用 this. $ nextTick(() => { this.$refs[this.activeName].init();} );来处理dom异步渲染
<template>
<div>
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
<el-tab-pane label="按上传途径" name="upload">
<upload ref="upload"></upload>
</el-tab-pane>
<el-tab-pane label="按用户类型" name="user">
<user ref="user"></user>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import upload from "./upload";
import user from "./user";
export default {
components: {
upload,
user
},
data() {
return {
activeName: "upload"
};
},
created() {
this.goRoute();
//配上路由处理是为了给每个标签页的地址加上activeName,可以通过路由直接定位到该标签页
this.$nextTick(() => {
this.$refs[this.activeName].init();
});
},
watch: {
$route(n) {
this.activeName = n.query.activeName;
this.$refs[this.activeName].init();
},
activeName(n) {
this.$router.push({
path: "/statisticAnalysis/picStatistic/index",
query: {
activeName: n
}
});
}
},
methods: {
goRoute() {
if (this.$route.query.activeName) {
this.activeName = this.$route.query.activeName;
}
},
handleClick(tab, event) {
this.$refs[this.activeName].init();
}
}
};
</script>
如果此时this.activeName=upload,那么就是this.$ refs[this.activeName]就等于this.$refs[upload],访问的就是upload组件。
所以要在upload的组件里定义一个init()方法,一点击标签就会跳到相应组件,并且同时调用init()
upload组件里:
<template>
<div>
</div>
</template>
<script>
export default {
data() {
return {
},
// created() {
// 不用生命周期函数
// },
methods: {
init() {
//想干什么就在init里写
console.log("来到了upload组件")
},
}
</script>
简单转载一个$nextTick例子
(链接有详细讲解)
作者:Ruheng
链接:
https://www.jianshu.com/p/a7550c0e164f
先来一个示例了解下关于Vue中的DOM更新以及nextTick的作用。
模板
<div class="app">
<div ref="msgDiv">{{msg}}</div>
<div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
<div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
<div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
<button @click="changeMsg">
Change the Message
</button>
</div>
Vue实例
new Vue({
el: '.app',
data: {
msg: 'Hello Vue.',
msg1: '',
msg2: '',
msg3: ''
},
methods: {
changeMsg() {
this.msg = "Hello world."
this.msg1 = this.$refs.msgDiv.innerHTML
this.$nextTick(() => {
this.msg2 = this.$refs.msgDiv.innerHTML
})
this.msg3 = this.$refs.msgDiv.innerHTML
}
}
})
点击前
点击后
从图中可以得知:msg1和msg3显示的内容还是变换之前的,而msg2显示的内容是变换之后的。其根本原因是因为Vue中DOM更新是异步的。