基于vue+elementPlus的动态导航标签栏-tabs

今天来写一个导航标签栏,哈哈,我也不清楚这个功能是不是这个名字。

今天领导说要在系统重添加个导航标签栏的功能,虽然很简单但我是第一次做这个功能,有些地方可能想的不够完美,希望如果有更好想法的朋友能指点指点。如果还可以,也希望给各位同行提供一个小demo,用的时候可以直接拿来用。嘻嘻!!!

实现思路

首先用到了element-plus框架中tabs的组件,然后数据我这里是通过vuex来维护的。在点击菜单的同时往vuex相关数据数组中添加一项数据即可,删除也一样的道理。具体的实现如下:

具体过程

首先,创建一个HeaderTabs.vue的组件,我们使用时直接引用即可

<template>
    <div class="head_tabs">
      <keep-alive>
          <el-tabs
              v-model="HeaderTabsActiveName"
              type="card"
              @tab-click="handlePathSwicth"
              class="handleTabs"
              closable
              @tab-remove="removeHeaderTabsList"
          > 
              <el-tab-pane
                  v-for="(item,index) in HeaderTabsList"
                  :key="index"
                  :label="item.topic"
                  :name="item.path"
                  >
              </el-tab-pane>
          </el-tabs>
      </keep-alive>
    </div>
</template>
<script setup>
import { ref ,watch,computed, onMounted} from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex';
// 声明路由对象
const router = useRouter();
// 声明vuex对象
const store = useStore();

const HeaderTabsActiveName = ref('')
const HeaderTabsList = ref([])

onMounted(()=>{
  // 这里的数据都是在vuex中获取的
  HeaderTabsList.value = store.state.HeaderTabs;
  HeaderTabsActiveName.value = store.state.TabsActiveName;
})

// 这里直接监听vuex的数据会导致失效,这里可能是因为vue性能问题,vue的底层没有给vuex的数据也进行数据绑定吧
// 因此,这里使用computed这个api函数来返回vuex中的值,然后将此方法体放入watch中监听
const getTabsActiveName = computed(()=>{
	return store.state.TabsActiveName;
})

// 使用watch监听vuex的数据,并开启第一次绑定监听--immediate 
watch(getTabsActiveName,(o1)=>{
  if(o1){
    // 我们每添加条数据都需要修改相关的tabs索引,否则选中项是不会高亮的
    HeaderTabsActiveName.value = o1;
  }
},{ immediate: true })

// 标签点击触发
const handlePathSwicth = (targetName)=>{
  let name = targetName.props.name;
  store.commit("updateTabsActiveName",name);
  HeaderTabsActiveName.value = name;
  // 手动跳转,组件不会提供跳转功能
  router.push({
    path:name
  })
}
// 删除tabs触发
const removeHeaderTabsList = (targetName) => {
  // 使用vuex中自定义的方法删除数据
  store.commit('removeHeaderTabs', targetName)

  setTimeout(()=>{
    // 利用定时器达到延时方法,防止HeaderTabsActiveName还未变就执行下面的跳转
    router.push({
      path:HeaderTabsActiveName.value
    })
  },0)
}
</script>

下面我们开始编写vuex中的内容

vuex主要的角色是来维护我们的数据,让我们的数据达到共享的效果,使得我们的数据可以在系统中共同使用和维护。 但是使用vuex时需要的代码量要比pinia要麻烦点。因为本系统采用的是vuex的数据存储方法,因此我们使用vuex的写法,用pinia编写时的逻辑都是一样的。(这里只将关键代码显示出来。vuex的具体用法直接百度即可)

首先在state.ts文件中编写声明相关数据。

import {ref} from 'vue'
//初始化vuex的数据
const state = {
    // tabs面包屑的数据
    HeaderTabs:[
      {
        topic:"首页",
        path:'/home'
      }
    ],
    TabsActiveName: ref("/home")
  }
export { state }

然后在mutations.ts文件中编写相关方法。

// 修改tabs的索引绑定
updateTabsActiveName(state,msg){
  // 修改标签索引
  state.TabsActiveName = msg
},
// 添加tabs标签
addHeaderTabs(state,msg){
  // 用filter过滤器看添加项是否已存在,如果存在则不添加
  let f = state.HeaderTabs.filter(t=>{
    return t.path == msg.path
  })
  if(f.length==0){
    state.HeaderTabs.push(msg)
  }
  state.TabsActiveName = msg.path
},
// 删除tabs标签
removeHeaderTabs(state,msg){
  // 如果要删除的是首页就直接退出,这里根据业务而定
  if(msg=="/home") return;
  // 通过循环方式找到要删除的数据项
  state.HeaderTabs.forEach((item,index)=>{
    if(item.path==msg){
      state.HeaderTabs.splice(index,1);
      return true;
    }
  })
  // 如果当前显示页如删除项一样,则自动跳转会首页,这里也是根据具体业务而定
  if(state.TabsActiveName==msg){
    state.TabsActiveName = "/home"
  }
}

菜单项调用添加逻辑

最后在需要添加的tabs标签的地方增加新增按钮即可,这里直接在系统的菜单栏操作。当用户点击菜单项时不仅跳转相关路由,还调用刚才相关的方法,具体代码如下:

// 这里是LeftMenu.vue中
// 菜单点击时触发的方法
menuClick(row){
    // 将当前点击的对象传递给指定方法
    this.store.commit("addHeaderTabs",row)
    // 跳转相关路由
    this.router.push({
        path:row.path
    })
}

应用于界面 

最后,最关键的一步,我们现在只是写好了逻辑,但是还没在页面上显示呢。接下来在自己的主界面上引入组件。

不使用setup语法糖时:

<template>
    <div class="index">
      <HeaderTabs></HeaderTabs>
    </div>
</template>
<script>
import { defineComponent } from '@vue/composition-api'
//@ 后是自己组件的真实路径
import HeaderTabs from '@/components/page/component/HeaderTabs.vue'
export default defineComponent({
    components:{
        HeaderTabs
    },
})
</script>

 使用setup语法糖:

<template>
    <div class="index">
      <HeaderTabs></HeaderTabs>
    </div>
</template>
<script setup>
import HeaderTabs from '@/components/page/component/HeaderTabs.vue'
</script>
实现效果

新增:

 删除:

公司系统是保密项,不能直接放出来,我直接在自己的毕设项目上添加的,所有样式看起来有点仓促。哈哈。 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值