feat:文章页新增面包屑
This commit is contained in:
11
Yi.Bbs.Vue3/package-lock.json
generated
11
Yi.Bbs.Vue3/package-lock.json
generated
@@ -18,6 +18,7 @@
|
|||||||
"marked": "^4.2.12",
|
"marked": "^4.2.12",
|
||||||
"mavon-editor": "^3.0.0",
|
"mavon-editor": "^3.0.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
"path-to-regexp": "^6.2.1",
|
||||||
"pinia": "^2.0.32",
|
"pinia": "^2.0.32",
|
||||||
"pinia-plugin-persistedstate": "^3.2.0",
|
"pinia-plugin-persistedstate": "^3.2.0",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
@@ -2851,6 +2852,11 @@
|
|||||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/path-to-regexp": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
|
||||||
|
},
|
||||||
"node_modules/path-type": {
|
"node_modules/path-type": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz",
|
||||||
@@ -6087,6 +6093,11 @@
|
|||||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"path-to-regexp": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
|
||||||
|
},
|
||||||
"path-type": {
|
"path-type": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"marked": "^4.2.12",
|
"marked": "^4.2.12",
|
||||||
"mavon-editor": "^3.0.0",
|
"mavon-editor": "^3.0.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
|
"path-to-regexp": "^6.2.1",
|
||||||
"pinia": "^2.0.32",
|
"pinia": "^2.0.32",
|
||||||
"pinia-plugin-persistedstate": "^3.2.0",
|
"pinia-plugin-persistedstate": "^3.2.0",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
|
|||||||
84
Yi.Bbs.Vue3/src/components/Breadcrumb/index.vue
Normal file
84
Yi.Bbs.Vue3/src/components/Breadcrumb/index.vue
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<el-breadcrumb class="app-breadcrumb">
|
||||||
|
<el-breadcrumb-item v-for="(item, index) in breadcrumbs" :key="item.path">
|
||||||
|
<span
|
||||||
|
v-if="
|
||||||
|
item.redirect === 'noRedirect' || index === breadcrumbs.length - 1
|
||||||
|
"
|
||||||
|
class="no-redirect"
|
||||||
|
>
|
||||||
|
{{ item.meta.title }}
|
||||||
|
</span>
|
||||||
|
<a v-else @click.prevent="handleLink(item)">
|
||||||
|
{{ item.meta.title }}
|
||||||
|
</a>
|
||||||
|
</el-breadcrumb-item>
|
||||||
|
</el-breadcrumb>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch, defineProps } from "vue";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
import { compile } from "path-to-regexp";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 面包屑列表
|
||||||
|
breadcrumbsList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const breadcrumbs = ref([]);
|
||||||
|
|
||||||
|
const getBreadcrumb = () => {
|
||||||
|
breadcrumbs.value = props.breadcrumbsList;
|
||||||
|
};
|
||||||
|
|
||||||
|
const pathCompile = (path) => {
|
||||||
|
const { params } = route;
|
||||||
|
const toPath = compile(path);
|
||||||
|
return toPath(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleLink = (item) => {
|
||||||
|
const { redirect, path } = item;
|
||||||
|
if (redirect) {
|
||||||
|
router.push(redirect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
router.push(pathCompile(path));
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.path,
|
||||||
|
(path) => {
|
||||||
|
if (path.startsWith("/redirect/")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getBreadcrumb();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
getBreadcrumb();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-breadcrumb__inner,
|
||||||
|
.el-breadcrumb__inner a {
|
||||||
|
font-weight: 400 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-breadcrumb.el-breadcrumb {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: var(--v3-navigationbar-height);
|
||||||
|
margin-left: 8px;
|
||||||
|
.no-redirect {
|
||||||
|
color: #97a8be;
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -14,15 +14,16 @@ import directive from "./directive"; // directive
|
|||||||
|
|
||||||
import "./permission";
|
import "./permission";
|
||||||
|
|
||||||
const app = createApp(App);
|
(async () => {
|
||||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
const app = createApp(App);
|
||||||
app.component(key, component);
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
}
|
app.component(key, component);
|
||||||
|
}
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
pinia.use(piniaPluginPersistedstate);
|
pinia.use(piniaPluginPersistedstate);
|
||||||
|
app.use(pinia);
|
||||||
app.use(pinia);
|
directive(app);
|
||||||
directive(app);
|
app.use(router);
|
||||||
app.use(router);
|
await router.isReady();
|
||||||
app.mount("#app");
|
app.mount("#app");
|
||||||
|
})();
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ const router = createRouter({
|
|||||||
name: "index",
|
name: "index",
|
||||||
path: "/index",
|
path: "/index",
|
||||||
component: () => import("../views/home/Index.vue"),
|
component: () => import("../views/home/Index.vue"),
|
||||||
|
meta: {
|
||||||
|
title: "首页",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "article",
|
name: "article",
|
||||||
@@ -52,6 +55,9 @@ const router = createRouter({
|
|||||||
name: "discuss",
|
name: "discuss",
|
||||||
path: "/discuss/:plateId?",
|
path: "/discuss/:plateId?",
|
||||||
component: () => import("../views/Discuss.vue"),
|
component: () => import("../views/Discuss.vue"),
|
||||||
|
meta: {
|
||||||
|
title: "板块",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//artType:discuss主题、article文章
|
//artType:discuss主题、article文章
|
||||||
@@ -65,6 +71,14 @@ const router = createRouter({
|
|||||||
path: "/profile",
|
path: "/profile",
|
||||||
component: () => import("../views/profile/Index.vue"),
|
component: () => import("../views/profile/Index.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "themeCover",
|
||||||
|
path: "/article/:discussId",
|
||||||
|
component: () => import("../views/Article.vue"),
|
||||||
|
meta: {
|
||||||
|
title: "主题封面",
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ path: "/:pathMatch(.*)*", name: "NotFound", component: NotFound },
|
{ path: "/:pathMatch(.*)*", name: "NotFound", component: NotFound },
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<el-button
|
<el-button
|
||||||
style="width: 100%; margin-bottom: 0.8rem"
|
style="width: 100%; margin-bottom: 0.8rem"
|
||||||
@click="loadDiscuss(true)"
|
@click="loadDiscuss(true)"
|
||||||
>首页</el-button
|
>主题封面</el-button
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
v-hasPer="['bbs:article:add']"
|
v-hasPer="['bbs:article:add']"
|
||||||
@@ -51,6 +51,7 @@
|
|||||||
<el-col :span="14">
|
<el-col :span="14">
|
||||||
<el-row class="left-div">
|
<el-row class="left-div">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
|
<Breadcrumb :breadcrumbsList="breadcrumbsList" class="breadcrumb" />
|
||||||
<!-- {{ discuss.user }} -->
|
<!-- {{ discuss.user }} -->
|
||||||
<AvatarInfo
|
<AvatarInfo
|
||||||
:size="50"
|
:size="50"
|
||||||
@@ -170,7 +171,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { h, ref, onMounted } from "vue";
|
import { h, ref, onMounted, watch } from "vue";
|
||||||
import AvatarInfo from "@/components/AvatarInfo.vue";
|
import AvatarInfo from "@/components/AvatarInfo.vue";
|
||||||
import InfoCard from "@/components/InfoCard.vue";
|
import InfoCard from "@/components/InfoCard.vue";
|
||||||
import ArticleContentInfo from "@/components/ArticleContentInfo.vue";
|
import ArticleContentInfo from "@/components/ArticleContentInfo.vue";
|
||||||
@@ -185,6 +186,8 @@ import {
|
|||||||
del as articleDel,
|
del as articleDel,
|
||||||
get as articleGet,
|
get as articleGet,
|
||||||
} from "@/apis/articleApi.js";
|
} from "@/apis/articleApi.js";
|
||||||
|
import Breadcrumb from "@/components/Breadcrumb/index.vue";
|
||||||
|
|
||||||
//数据定义
|
//数据定义
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -205,6 +208,11 @@ const currentNodeKey = route.params.articleId;
|
|||||||
//目录数据
|
//目录数据
|
||||||
const catalogueData = ref([]);
|
const catalogueData = ref([]);
|
||||||
|
|
||||||
|
// 面包屑导航列表
|
||||||
|
const breadcrumbsList = ref([]);
|
||||||
|
// 当前文章名称
|
||||||
|
const currentArticle = ref("");
|
||||||
|
|
||||||
//子文章初始化
|
//子文章初始化
|
||||||
const loadArticleData = async () => {
|
const loadArticleData = async () => {
|
||||||
const response = await articleall(route.params.discussId);
|
const response = await articleall(route.params.discussId);
|
||||||
@@ -315,6 +323,7 @@ const updateArticle = (node, data) => {
|
|||||||
};
|
};
|
||||||
//单机节点
|
//单机节点
|
||||||
const handleNodeClick = async (data) => {
|
const handleNodeClick = async (data) => {
|
||||||
|
currentArticle.value = data?.name;
|
||||||
//跳转路由
|
//跳转路由
|
||||||
|
|
||||||
router.push(`/article/${route.params.discussId}/${data.id}`);
|
router.push(`/article/${route.params.discussId}/${data.id}`);
|
||||||
@@ -343,6 +352,35 @@ onMounted(async () => {
|
|||||||
await loadDiscuss();
|
await loadDiscuss();
|
||||||
await loadArticleData();
|
await loadArticleData();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const resultRouters = ["index", "discuss", "themeCover"];
|
||||||
|
breadcrumbsList.value = route.matched[0].children
|
||||||
|
.filter((item) => resultRouters.includes(item.name))
|
||||||
|
.sort((a, b) => {
|
||||||
|
return resultRouters.indexOf(a.name) - resultRouters.indexOf(b.name);
|
||||||
|
});
|
||||||
|
watch(
|
||||||
|
() => currentArticle.value,
|
||||||
|
(val) => {
|
||||||
|
if (val !== "") {
|
||||||
|
breadcrumbsList.value[3] = {
|
||||||
|
name: "article",
|
||||||
|
path: "/article/:discussId",
|
||||||
|
meta: {
|
||||||
|
title: currentArticle.value,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
watch(
|
||||||
|
() => route.params.articleId,
|
||||||
|
async (val) => {
|
||||||
|
if (val === "") {
|
||||||
|
discuss.value = (await discussGet(route.params.discussId)).data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.comment {
|
.comment {
|
||||||
@@ -425,4 +463,8 @@ h2 {
|
|||||||
.tab-divider {
|
.tab-divider {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1642,6 +1642,11 @@
|
|||||||
"resolved" "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz"
|
"resolved" "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz"
|
||||||
"version" "1.0.7"
|
"version" "1.0.7"
|
||||||
|
|
||||||
|
"path-to-regexp@^6.2.1":
|
||||||
|
"integrity" "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
|
||||||
|
"resolved" "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz"
|
||||||
|
"version" "6.2.1"
|
||||||
|
|
||||||
"path-type@^4.0.0":
|
"path-type@^4.0.0":
|
||||||
"integrity" "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
|
"integrity" "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
|
||||||
"resolved" "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz"
|
"resolved" "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user