element-ui Tabs 标签页刷新页面状态不丢失
element-ui Tabs 标签页刷新页面状态不丢失
效果
一般在使用Tabs组件,我们选择了标签2后刷新,tab组件会重新回到标签1,每次都需要在刷新后从新选择标签页。给人感觉不友好。
要求
- 尽量减少代码更改
- 记录当前tag选中信息,刷新后可以反选
思路
- 使用directives监听tab加载与切换
- 使用mixins确保全局可调用
- 在directives切换将信息写入到query中,刷新页面时读取query中信息进行反选
实现
- 首先创建mixins文件
param2Obj 方法
export function param2Obj (url) {
const search = url.split('?')[1];
if (!search) {
return {}
}
return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}');
}
mixins/index.js
import { param2Obj } from '@/utils/index'
// 全局引用方法
export default {
// v-tab-change:activeName="setActiveName"
directives: {
'tab-change': {
// 绑定时读取query是否有action字段
bind(el, binding) {
let param = param2Obj(window.location.href)
if (param.active) {
binding.value({ action: 'setActiveName', key: binding.arg}, param.active);
}
},
// 切换时query写入action字段
update(el, binding) {
// setTimeout(0) 等待dom完成后进行操作
setTimeout(() => {
let param = param2Obj(window.location.href)
// 获取dom
// 此处详见 注1
let queryList = document.querySelectorAll('.el-tabs__item')
for (let index = 0; index < queryList.length; index++) {
const item = queryList[index]
if (item.className.indexOf('is-active') !== -1) {
let activeName = item.id.split('-')[1]
// 防止重复调用push方法
if (param.active !== activeName) {
binding.value({ action: 'setPath' }, activeName);
}
}
}
}, 0);
}
}
},
methods: {
setActiveName({ action, key }, activeName) {
// 写入tabs默认值
if (action === 'setActiveName') {
this[key] = activeName
} else {
// 使用 replace 方法防止产生记录
this.$router.replace({
query: {
active: activeName
}
})
}
}
}
}
- 在main.js中全局引用
// 全局mixin
import mixinsIndex from '@/mixins/index'
Vue.mixin(mixinsIndex)
- 使用
<template>
<!-- activeName为当前绑定的v-model,key值。 setActiveName是mixin定义的方法 -->
<el-tabs v-model="activeName" v-tab-change:activeName="setActiveName">
<el-tab-pane label="tab1" name="tab1">tab1 </el-tab-pane>
<el-tab-pane label="tab2" name="tab2">tab2 </el-tab-pane>
<el-tab-pane label="tab3" name="tab3">tab3</el-tab-pane>
</el-tabs>
</template>
<script>
export default {
name: 'tabDemo',
data () {
return {
activeName: 'tab1'
}
}
}
</script>
注1:
is-active
为当前选中的tab,class中包含当前的name值