vue项目中用到了tab切换,由于切换模块过多,都写在同一组件中代码会越来越难维护,解决办法就是把每个tab页签内容拆分成单独的组件。
当然可以考虑直接每个tab页单独设置成一个路由,但有时候可能是弹出框中用到的tab切换,这时就不适用于路由来配置解决了。
这时可以使用component标签的is属性来动态切换组件,并配合keep-alive标签缓存组件,达到切换后保留组件填写内容等操作状态,并保持滚动条位置。
保持滚动条位置的功能是利用监听tab变化时来获取即将要切换走的组件外框的滚动条位置,在切换回来时在重新赋值其滚动位置。
为何不使用缓存组件的 deactivated 触发时来获取其位置呢?因为deactivated执行较慢,拿不到滚动位置。
使用了element-ui组件库
主体页面如下:
<template>
<div>
<el-tabs v-model="currentTab">
<el-tab-pane v-for="(item, index) in tabList" :key="index" :label="item.label" :name="item.name"></el-tab-pane>
</el-tabs>
<keep-alive>
<component
ref="tab"
:is="currentTab"
></component>
</keep-alive>
</div>
</template>
<script>
import material from "./material";
import system from "./system";
export default {
components: {
material,
system
},
data() {
return {
currentTab: 'material',
tabList: [
{
"label": "素材图片",
"name": "material"
},
{
"label": "系统图标",
"name": "system"
}
]
}
},
watch:{
currentTab(newValue) {
//切换时先记录其wrapper容器的scrollTop,以便在切换回来时保持滚动到的位置
this.$refs.tab.scrollTop = this.$refs.tab.$refs.wrapper.scrollTop;
}
}
}
</script>
子组件公共部分: (一些公共的js可以抽取成mixin)
<template> <div ref="wrapper" style="overflow-y: auto;">
</div>
</template>
<script> export default { data() { return { scrollTop: 0, //记录滚动条位置 } }, activated() { //保持滚动到的位置 this.$refs.wrapper.scrollTop = this.scrollTop; } } </script>