vue3封装页面顶部动态标签栏

开始的想法是通过路由拦截器去实现,但是发现初始化的时候会有冲突,所以后面还是改在框架中去实现。
核心的方法呢就是通过el-tag与路由器去实现。设置watch去监听当前的路由,记得设置deep和immediate,这样才能在初次加载时获取。
 

<template>
  <div >
    <el-tag
      v-for="tag in tags"
      :key="tag.name"
      closable
      @close="closeTag(tag)"
      @click="clickTag(tag)"
      :class="{ isChecked: tag.name === checked }"
      style="margin-right: 10px; font-size: 14px; cursor: pointer"
    >
      {{ tag.name }}
    </el-tag>
  </div>
</template>

<script lang="ts" setup>
import { ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'

interface Tag {
  name: string
  path: string
}

const $route = useRoute()
const $router = useRouter()
const tags = ref<Tag[]>([])
const checked = ref('')

watch(
  $route,
  (newValue) => {
    addTag(newValue)
  },
  { immediate: true }
)

function addTag(data: any) {
  const findData = tags.value.find((item) => item.name === data.meta.title)
  if (!findData) {
    tags.value.push({ name: data.meta.title, path: data.path })
  }
  checked.value = data.meta.title
}

function closeTag(tag: Tag) {
  if (tags.value.length === 1) return

  const index = tags.value.findIndex((item) => item.name === tag.name)
  tags.value.splice(index, 1)

  const lastTag = tags.value[tags.value.length - 1]
  checked.value = lastTag.name
  $router.push(lastTag.path)
}

function clickTag(tag: Tag) {
  $router.push(tag.path)
}
</script>
<script lang="ts">
export default {
  name: 'Tabs'
}
</script>
<style scoped lang="scss">
.isChecked {
  background-color: #09f;
  color: #fff;
  border: none;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值