# Nuxt3 將 API 獲取的 HTML 中的 a 標籤轉換成 NuxtLink 假設我們從後端獲取到一篇部落格的 `html` 要渲染到畫面上 但裡面有很多連結,且有些是連到網站其他分頁 點擊連結後會發現 `Network` 發送了許多不必要的請求,將網站整個 reload 了 解決方式:自己建立一個 `v-interpolate` 去將點擊事件轉換成執行 `navigateTo` `post.vue` 檔案: ```htmlembedded= <template> <div v-interpolate v-html="data"></div> </template> <script setup> import { vInterpolate } from '~/directives/vInterpolate'; const { data } = await useFetch('/api/test') </script> ``` `/directives/vInterpolate.js` 檔案: ```javascript= export const vInterpolate = { mounted(el) { // 遍歷所有 a 標籤 const links = Array.from(el.getElementsByTagName('a')).filter(item => { // 取出 href 屬性 const href = item.getAttribute('href') // 判斷 href 是否不存在,回傳 false 不處理 if (!href) return false // 判斷 href 如果開頭為 / 或與當前網頁同網域,回傳 true 改造 return href.startsWith('/') || isSameDomainUrl(href) }) // 自定義 addListeners 事件,傳入所有需要被改造的連結 addListeners(links) // 自定義 $componentUpdated 隱藏事件,用來 clean up el.$componentUpdated = () => { removeListeners(links) nextTick(() => addListeners(links)) } // 自定義 $destroy 隱藏事件,用來銷毀 el.$destroy = () => removeListeners(links) }, updated: (el) => el.$componentUpdated?.(), beforeUnmount: (el) => el.$destroy?.() } // 自定義 navigate 事件,將 a 連結點擊事件改為 navigateTo function navigate(event) { const target = event.target const href = target.getAttribute('href') event.preventDefault() // 取消預設的 a 連結點擊事件 return navigateTo(href) // 回傳調用 navigateTo } function addListeners(links) { // 遍歷所有需要被改造的連結 links.forEach((link) => { // 監聽點擊事件,傳入自定義的 navigate 事件 link.addEventListener('click', navigate, false) }) } function removeListeners(links) { // 遍歷所有需要被改造的連結 links.forEach((link) => { // 取消監聽點擊事件,傳入自定義的 navigate 事件 link.removeEventListener('click', navigate, false) }) } // 判斷傳入的連結是否與當前網站在同一個網域 function isSameDomainUrl(url) { var urlObject = new URL(url); var linkDomain = urlObject.hostname; var currentDomain = window.location.hostname; return currentDomain === linkDomain; } ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up