element-ui Tabs 标签页刷新页面状态不丢失

element-ui Tabs 标签页刷新页面状态不丢失

转载请表明出处 https://www.cnblogs.com/niexianda/p/14765111.html

效果

一般在使用Tabs组件,我们选择了标签2后刷新,tab组件会重新回到标签1,每次都需要在刷新后从新选择标签页。给人感觉不友好。

要求

  1. 尽量减少代码更改
  2. 记录当前tag选中信息,刷新后可以反选

思路

  1. 使用directives监听tab加载与切换
  2. 使用mixins确保全局可调用
  3. 在directives切换将信息写入到query中,刷新页面时读取query中信息进行反选

实现

  1. 首先创建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
                    }
                })
            }

        }
    }
}
  1. 在main.js中全局引用
// 全局mixin
import mixinsIndex from '@/mixins/index'
Vue.mixin(mixinsIndex)
  1. 使用
<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值

posted @ 2021-05-13 18:37  聂显达  阅读(3049)  评论(0编辑  收藏  举报