Vue3+Inertia.js项目FAQ板块如何实现无刷新内部链接跳转
Vue 3 + Inertia.js 站点FAQ板块内部无刷新跳转实现方案
核心逻辑说明
Inertia 提供的 <Link> 组件本质是拦截链接默认点击行为,通过XHR请求完成页面切换,避免整页重载。根据FAQ内容在数据库的存储格式不同,对应两种落地实现方式,不需要额外依赖第三方包。
场景1:FAQ为结构化存储(推荐存储方式)
如果后端返回的FAQ数组中,链接信息是独立字段存储(而非混在HTML字符串里),直接在模板中渲染<Link>组件即可。
后端返回数据结构参考:
[ { id: 1, question: "如何申请发票?", answer: "订单完成后你可以前往 {page} 提交开票申请,电子发票会在1-3个工作日发送到你的预留邮箱。", link_text: "发票管理中心", link_path: "/user/invoice" } ]
页面代码实现:
<script setup> import { Link } from '@inertiajs/vue3' defineProps({ faqList: Array }) </script> <template> <div class="faq-container"> <div v-for="faq in faqList" :key="faq.id" class="faq-item"> <h4>{{ faq.question }}</h4> <p> {{ faq.answer.split('{page}')[0] }} <Link :href="faq.link_path" class="text-primary hover:underline"> {{ faq.link_text }} </Link> {{ faq.answer.split('{page}')[1] }} </p> </div> </div> </template>
场景2:FAQ为富文本HTML存储
如果FAQ内容是富文本编辑器生成的HTML字符串,内部混写了原生<a>标签,不需要把字符串解析替换成Vue组件,通过事件委托拦截站内链接点击、手动调用Inertia路由方法即可,性能更高。
页面代码实现:
<script setup> import { router } from '@inertiajs/vue3' defineProps({ faqList: Array }) const handleFaqContentClick = (e) => { // 向上查找当前点击的是否为a标签 const activeLink = e.target.closest('a') if (!activeLink) return const linkHref = activeLink.getAttribute('href') // 仅拦截站内相对路径链接,外链、下载链接、mailto/tel等特殊链接走默认逻辑 if (linkHref?.startsWith('/') && !linkHref.startsWith('//')) { e.preventDefault() router.visit(linkHref) } } </script> <template> <div class="faq-container"> <div v-for="faq in faqList" :key="faq.id" class="faq-item"> <h4>{{ faq.question }}</h4> <div class="faq-answer" v-html="faq.answer_html" @click="handleFaqContentClick" ></div> </div> </div> </template>
注意事项
不要尝试通过正则替换v-html内的a标签为Link组件,v-html渲染的原生HTML无法解析Vue自定义组件,会直接失效。
- 上述逻辑自动兼容带hash锚点的内部链接(如
/docs/intro#install),Inertia跳转完成后会自动滚动到对应锚点位置 - 所有站外链接、非GET请求的跳转不会被拦截,保持原生行为符合用户预期
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

