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>