2025-09-05 14:59:21 +08:00

62 lines
1.8 KiB
Vue

<script>
import { toRefs, defineComponent, h, useSlots, computed } from "vue";
import { hash } from "ohash";
import { useAsyncData, fetchContentNavigation, useState, useContent } from "#imports";
import { NuxtLink } from "#components";
const ContentNavigation = defineComponent({
name: "ContentNavigation",
props: {
/**
* A query to be passed to `fetchContentNavigation()`.
*/
query: {
type: Object,
required: false,
default: void 0
}
},
async setup(props) {
const {
query
} = toRefs(props);
const queryBuilder = computed(() => {
if (typeof query.value?.params === "function") {
return query.value.params();
}
return query.value;
});
if (!queryBuilder.value && useState("dd-navigation").value) {
const { navigation: navigation2 } = useContent();
return { navigation: navigation2 };
}
const { data: navigation } = await useAsyncData(
`content-navigation-${hash(queryBuilder.value)}`,
() => fetchContentNavigation(queryBuilder.value)
);
return { navigation };
},
/**
* Navigation empty fallback
* @slot empty
*/
render(ctx) {
const slots = useSlots();
const { navigation } = ctx;
const renderLink = (link) => h(NuxtLink, { to: link._path }, () => link.title);
const renderLinks = (data, level) => h(
"ul",
level ? { "data-level": level } : null,
data.map((link) => {
if (link.children) {
return h("li", null, [renderLink(link), renderLinks(link.children, level + 1)]);
}
return h("li", null, renderLink(link));
})
);
const defaultNode = (data) => renderLinks(data, 0);
return slots?.default ? slots.default({ navigation, ...this.$attrs }) : defaultNode(navigation);
}
});
export default ContentNavigation;
</script>