vue3 ts pinia element plus 实现标签页

145 阅读1分钟

项目地址:gitee.com/luobf22/vue…

  • 通过pinia创建useTabStore模块
  • tabArray数组存储当前标签页内容
  • currentPath表示当前页面的path
  • increment方法表示点击菜单时,判断菜单是否已经存在标签页中,如果存在即跳转,不存在就添加到标签页,并将所有的标签页的状态type进行修改,如果标签页大于5个内容时,删除第一个内容
  • tabClose方法表示点击删除时,如果标签页没有内容了,添加一个主页进入标签页,如果还有内容,就将当前页设置为标签页最后一个内容
  • tabClick方法表示点击标签,跳转到该标签的path,其他标签状态type修改
// 标签页数据
import { defineStore } from 'pinia';

import router from "../../router";

interface tabType {
    title: string;
    path: string,
    type: string
}

interface TabState {
    tabArray: tabType[],
    currentPath: string
}

export const useTabStore = defineStore('tab', {
    // 初始化状态
    state: (): TabState => ({
        tabArray: [
            { title: '主页', path: './', type: 'success' }
        ],
        currentPath: ''
    }),
    // 计算属性
    getters: {
        
    },
    // 操作方法
    actions: {
        // 增加
        increment(title: string, path: string) {
            // 是否为新的tab
            let result = this.tabArray.every(function (item) {
                return item.title !== title;
            });

            if (result) {
                // 将新的tab改为success
                this.tabArray.push({ title: title, path: path, type: 'success' })
                if(this.tabArray.length>5){
                    this.tabArray.shift()
                }
            } else {
                // 如果不是新的tab 就将当前选中的旧的tab改为success
                this.tabArray.map(i => {
                    if (i.title == title) {
                        i.type = 'success'
                    }
                })
            }
            // 将不是当前的页面 type修改为primary
            this.tabArray.map(i => {
                if (i.title !== title) {
                    i.type = 'primary'
                }
            })
        },
        // 删除 close
        tabClose(val: any) {
            this.tabArray = this.tabArray.filter(item => item.title !== val.title);
            if (this.tabArray.length == 0) {
                this.tabArray.push({ title: '主页', path: './', type: 'success' })
                router.replace('./')
            }else{
                router.replace(this.tabArray[this.tabArray.length - 1].path);
            }
            

        },
        // 点击 click
        tabClick(val: any) {
            router.replace(val.path);
            this.tabArray.map(i => {
                if (i.path !== val.path) {
                    i.type = 'primary'
                }
            })
        },
    },

});
  • 给标签页组件赋值useTabStore().tabArray数组,tabClick点击方法以及tabClose删除方法
<template>
  <div class="tabBox">
    <el-tag
      v-for="tag in useTabStore().tabArray"
      :key="tag.title"
      closable
      :type="tag.type"
      @click="tabClick(tag)"
      @close="tabClose(tag)"
    >
      {{ tag.title }}
    </el-tag>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref } from "vue";
import { useTabStore } from "../store/modules/tabStore";
export default defineComponent({
  name: "Tab",
  setup() {
    const tabClick = (val: any) => useTabStore().tabClick(val);
    const tabClose = (val: any) => useTabStore().tabClose(val);
    return {
      tabClick,
      tabClose,
      useTabStore,
    };
  },
});
</script>

<style lang="less" scoped>
@import "../less/components/tab.less";
</style>