使用vue3.2实现多页签导航

 更新时间:2023年12月06日 11:13:12   作者:前端er小芳  
这篇文章主要为大家详细介绍了如何使用vue3.2 + elementPlus + pinia 实现多页签导航,文中的示例代码讲解详细,有需要的小伙伴可以参考一下

一、实现思路

  • 单击菜单时数据添加store对象,添加数据时要去重以及数量限制,不可无限添加
  • 多页签导航数据从store对象里取
  • 初始化会显示【首页】标签导航,同时固定不可删除
  • 单击多页签导航,跳转到对应路由
  • 激活样式处理
  • 持久化处理
  • 删除多页签导航事件

二、具体实现步骤

1. 定义store

// src/store/tag-list.js
import { defineStore } from "pinia";

export const useTagStore = defineStore('tag',{
    state: ()=> ({
        tagList: [
            // 初始化默认展示【首页】标签导航
            {
                path:'/index',
                name: 'index',
                meta: { title: '首页'}
            }
        ]
    }),
    getters: {
        tagListGetter: state=> state.tagList
    },
    actions: {
        addTag(item) {
            this.tagList.push(item)
        },
        delTag(item) {
            // 找出要删除的tag的索引值
            const i = this.tagList.findIndex(v => v.path === item.path)
            this.tagList.splice(i,1)
        }
    },
    // 持久化
    persist: {
        enabled: true, // 开启
        strategies: [
            {
                key: 'tagList',
                storage: sessionStorage
            }
        ]

    }

2. 单击菜单时数据添加store对象

在导航组件中(naveItem.vue)添加点击事件addTag

    <!-- 无子级 -->
    <el-menu-item :index="item.path" v-if="!item.children" @click="addTag(item)">
        <el-icon><Menu /></el-icon>
        <span>{{item.meta.title}}</span>
    </el-menu-item>
    <!-- 有子级 -->
    <el-sub-menu :index="item.path" v-else>
        <template #title>{{item.meta.title}}</template>
        <nav-item v-for="sub in item.children" :key="sub.path" :item="sub"></nav-item>
    </el-sub-menu>

addTag方法逻辑如下,已有注释,不再详细说明。

import { storeToRefs } from 'pinia'
import { useTagStore } from '@/store/tag-list.js'
const tagStore = useTagStore()
const { tagList } = storeToRefs(tagStore)

const { item } = defineProps({
    item: {
        type: Object
    }
})

// 点击路由,添加标签导航,注意去重
const addTag = (item) => {
    // 添加前判断是否已存在
    const isRepeat = tagList.value.some(v => v.path === item.path) // 找到则返回true,否则返回false
    if(isRepeat) return
    // 限制最多只能打开10个标签导航页
    if(tagList.value.length === 10) {
        // 自动把第二个删除
        tagStore.delTag(tagList.value[1])
    }
    // 添加
    tagStore.addTag(item)
}

3. 定义一个tag组件

定义一个tag组件,从store中取出tagList并渲染;

1.首页标签导航不可关闭,通过当前tag的path不等于首页的path来控制el-tag的closeable是否展示;

2.定义默认展示的导航标签defaultUrl,默认为首页的path(/index);通过监听路由变化,将defaultUrl 等于变化后的路由地址;并且在template中判断:tag的path是否等于defaultUrl,是则不设置type(el-tag不设置type默认为蓝色),其他则为type=info;

3.点击导航标签,能够跳转到对应路由,给标签添加handleJump事件。

4.删除导航标签事件

a.删除的不是当前激活模块,正常删除

b.删除的是当前激活模块

  • 当前激活模块是最后一个导航标签,则需要高亮前一个导航标签
  • 当前激活模块不是最后一个导航标签,则需要高亮后一个导航标签

代码代码如下:

    <div class="tags">
        <el-scrollbar class="scroll-container">
            <el-tag
                v-for="(tag,index) in tagList"
                :key="tag.path"
                class="mx-1"
                :closable="tag.path !== '/index'"
                :type="tag.path === defaultUrl? '' : 'info'"
                @click="handleJump(tag)"
                @close="handleClose(tag,index)"
            >
                {{ tag?.meta?.title }}
            </el-tag>
        </el-scrollbar>
    </div>
import { ref,watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { useTagStore } from '@/store/tag-list.js'

const route = useRoute()
const router = useRouter()
const tagStore =  useTagStore()
const { tagList } = storeToRefs(tagStore)

// 高亮当前路由导航的标签页
const defaultUrl = ref('/idnex')
watch(route,(newVal,oldVal) => {
    defaultUrl.value = newVal.path

},{deep: true,immediate: true})

// 跳转路由
const handleJump = (tag) => {
    // 重复点击标签,不跳转
    if(route.path === tag.path) return
    router.push(tag.path)
}

// 关闭标签
const handleClose = (tag, i) => {
    // store 删除
    tagStore.delTag(tag)
    // 1.删除非当前模块,正常删除
    if(route.path !== tag.path) return
    // 2.删除当前模块
    if(i === tagList.value.length) {
        // 2.1当前模块属于最后一个模块,删除后需要高亮前一个模块
        handleJump(tagList.value[i-1])
    }else {
        // 2.2当前模块属于中间模块模块,删除后需要高亮后一个模块
        handleJump(tagList.value[i])
    }
}

具体效果

到此这篇关于使用vue3.2实现多页签导航的文章就介绍到这了,更多相关vue多页签导航内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Unocss(原子化css) 使用及vue3 + vite + ts讲解

    Unocss(原子化css) 使用及vue3 + vite + ts讲解

    这篇文章主要介绍了Unocss(原子化css)使用vue3 + vite + ts的方法,简单介绍了Unocss使用及图标库使用,通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • Vue生成随机卡密并绑定到表单输入框的实现技巧

    Vue生成随机卡密并绑定到表单输入框的实现技巧

    在现代Web应用中,随机生成验证码、卡密等是一项常见需求,对于开发人员来说,如何在表单中快速生成一个符合格式的随机卡密,并与其他表单字段一同提交,是一个常见的场景,本篇文章将详细介绍如何在Vue.js框架中实现一个随机卡密生成功能,需要的朋友可以参考下
    2024-11-11
  • 浅谈Vue单页面做SEO的四种方案

    浅谈Vue单页面做SEO的四种方案

    Vue SPA单页面应用对SEO不友好,当然也有相应的解决方案,通过查找资料,大概有以下4种方法,本文就详细的介绍一下
    2021-10-10
  • vue将后台数据时间戳转换成日期格式

    vue将后台数据时间戳转换成日期格式

    这篇文章主要为大家详细介绍了vue将后台数据时间戳转换成日期格式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • vue cli+axios踩坑记录+拦截器使用方式,代理跨域proxy

    vue cli+axios踩坑记录+拦截器使用方式,代理跨域proxy

    这篇文章主要介绍了vue cli+axios踩坑记录+拦截器使用方式,代理跨域proxy,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Vant picker 多级联动操作

    Vant picker 多级联动操作

    这篇文章主要介绍了Vant picker 多级联动操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Vuex unknown action type报错问题及解决

    Vuex unknown action type报错问题及解决

    这篇文章主要介绍了Vuex unknown action type报错问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • vue用BMap百度地图实现即时搜索功能

    vue用BMap百度地图实现即时搜索功能

    这篇文章主要为大家详细介绍了vue用BMap百度地图实现即时搜索功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • ElementUI中<el-form>标签中ref、:model、:rules的作用浅析

    ElementUI中<el-form>标签中ref、:model、:rules的作用浅析

    Element官方文档中写到,model是表单数据对象,rules是表单验证规则,下面这篇文章主要给大家介绍了关于ElementUI中<el-form>标签中ref、:model、:rules作用的相关资料,需要的朋友可以参考下
    2023-01-01
  • vue事件监听函数on中的this指针域使用

    vue事件监听函数on中的this指针域使用

    这篇文章主要介绍了vue事件监听函数on中的this指针域使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08

最新评论