«

vue3写了一个路由标签导航栏组件

时间:2023-8-3 19:19     作者:小诸葛     分类: Vue     正在检查是否收录...


vue3里面引入就可以使用,vue2需要注册一下在调用。

大致思路,进入页面的时候监听路由,判断当前路由的地址,然后把这个地址用来做激活样式匹配,接下来就是点击事件,点击谁就把激活样式给谁,其次是删除如果删除的是第一个,下次跳转默认下标为0的标签,并且附带激活样式,如果不是就跳转上一个也是index+1。这里面用了一点ts语法!

<LabelNav />
<script lang="ts" setup>
import LabelNav from '../components/LabelNav.vue'
</script>

效果展示:

vue3写了一个路由标签导航栏组件

完整代码

<template>
    <div class="DynamicMenu">
        <el-scrollbar>
            <div class="scrollbar-flex-content">
                <div @click="switching(item.to)" :class="{ 'DynamicMenu-span': true, 'active': item.to == path }"
                    v-for="(item, index) in  label " :key="index">
                    <span>{{ item.title }}</span>
                    <span @click="removeTag(index); $event.stopPropagation()" class="ax"></span>
                </div>
            </div>
        </el-scrollbar>

    </div>
</template>

<script setup lang="ts">
import { reactive, watch, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
let $route = useRoute()
let $router = useRouter()
interface LabelItem {
    title: string;
    to: string;
}
let path = ref()
let label = reactive<LabelItem[]>([

])
path.value = $route.path
// 页面加载的时候读取本地tab标签
const storedTabs = localStorage.getItem('tab');
if (storedTabs) {
    const newTabs = JSON.parse(storedTabs) as LabelItem[];
    newTabs.forEach(newTab => {
        const hasDuplicate = label.some(item => item.title === newTab.title);
        if (!hasDuplicate) {
            label.push(newTab);
        }
    });
} else {
    label.push({ title: '后台首页', to: '/index' })
    localStorage.setItem('tab', JSON.stringify(label))
}

// 监听路由变化,进行激活样式更改和标签存储
watch(() => $route.meta.title, (newTitle) => {
    path.value = $route.path//激活样式
    let tis: string = newTitle as string;
    // 检查是否存在相同的项,存储标签
    const hasDuplicate = label.some(item => item.title === tis);
    if (!hasDuplicate) {
        label.push({ title: tis, to: $route.path });
        localStorage.setItem('tab', JSON.stringify(label))
    }
});

// 删除标签
let removeTag = (index: number) => {
    if (label.length === 1) {
        return;
    } else {
        label.splice(index, 1);
        // 如果删除的是第一个标签,则跳转下一个,反之则跳转上一个
        if (index === 0) {
            path.value = label[0].to;
            $router.push(label[0].to);
        } else {
            path.value = label[index - 1].to;
            $router.push(label[index - 1].to);
        }
        localStorage.setItem('tab', JSON.stringify(label));
    }
}
// 点击标签跳转
let switching = (to: string) => {
    path.value = to
    $router.push(to)
}

</script>

<style lang="scss" scoped>
.DynamicMenu {
    width: 100%;
    height: 30px;
    background-color: #f5f7fa;
    position: relative;
    top: 0;
    display: flex;
    align-items: center;

    .DynamicMenu-span {
        height: 25px;
        min-width: 100px;
        background-color: #35a2ef;
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 0 2px;
        padding: 0 10px;
        font-size: 12px;
        color: #fff;
        position: relative;

        span {
            height: 100%;
            line-height: 25px;
        }
    }

    .ax {
        width: 20px;
        height: 20px;
        position: relative;
        position: absolute;
        right: 0;
    }

    .DynamicMenu-span .ax::after,
    .DynamicMenu-span .ax::before {
        content: "";
        width: 2px;
        height: 10px;
        top: 6px;
        border-radius: 50%;
        background-color: #fff;
        right: 10px;
        position: absolute;
        transition: transform 0.3s ease;
    }

    .DynamicMenu-span .ax::after {
        transform: rotate(-45deg);
    }

    .DynamicMenu-span .ax::before {
        transform: rotate(45deg);
    }

    .DynamicMenu-span .ax:hover::after {
        transform: rotate(45deg);
        background-color: #ff0000;
    }

    .DynamicMenu-span .ax:hover::before {
        transform: rotate(-45deg);
        background-color: #ff0000;
    }

    .active {
        background-color: white;
        color: #35a2ef;
        border: 1px solid #35a2ef;
    }
}

.scrollbar-flex-content {
    display: flex;
}

.scrollbar-demo-item {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100px;
    height: 50px;
    margin: 10px;
    text-align: center;
    border-radius: 4px;
    background: var(--el-color-danger-light-9);
    color: var(--el-color-danger);
}
</style>

vue3如何自己写一个路由标签导航栏组件

推荐阅读:


扫描二维码,在手机上阅读