github.com/avenga/couper@v1.12.2/docs/website/components/PageToc.vue (about) 1 <template> 2 <nav class="w-1/5 grow-0 p-2"> 3 <h2 class="text-amber-500">On this Page</h2> 4 <ul v-if="toc && toc.links"> 5 <li v-for="link in toc.links" :key="link.text"> 6 <NuxtLink :href="`#${link.id}`"> 7 {{ link.text }} 8 </NuxtLink> 9 <ul v-if="link.children"> 10 <li v-for="child in link.children" :key="child.id"> 11 <NuxtLink class="pl-2" :href="`#${child.id}`"> 12 {{ child.text }} 13 </NuxtLink> 14 </li> 15 </ul> 16 </li> 17 </ul> 18 </nav> 19 </template> 20 21 <script> 22 const headlineTags = ["h2", "h3", "h4", "attributes", "duration", "blocks"] 23 24 function getText(element) { 25 let text = element.value ?? "" 26 for (const child of element.children ?? []) { 27 text += getText(child) 28 } 29 return text 30 } 31 32 async function createPageToC() { 33 const { path } = useRoute() 34 const result = await queryContent(path).findOne() 35 36 const tocEntries = result.body.children.filter((element) => { 37 return headlineTags.includes(element.tag) 38 }).map((element) => { 39 let id, text 40 if (element.tag === "attributes" || element.tag === "duration" || element.tag === "blocks") { 41 id = element.tag 42 text = element.tag.substring(0, 1).toUpperCase() + element.tag.substring(1) 43 } else { 44 id = element.props.id 45 text = getText(element) 46 } 47 48 return { id: id, text: text , children: [] } 49 }) 50 51 return {links: tocEntries} 52 } 53 54 export default { 55 data() { 56 return { 57 toc: {links:[]} 58 } 59 }, 60 async mounted() { 61 this.toc = await createPageToC() 62 }, 63 watch: { 64 async $route(to, from) { 65 this.toc = await createPageToC() 66 } 67 } 68 } 69 </script>