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值