如何强制Nuxt直接访问页面时执行script标签,实现与NuxtLink跳转一致效果
根因分析
这一现象是Nuxt的渲染机制差异导致的:
- 通过NuxtLink跳转走的是客户端路由逻辑,页面完全在浏览器侧动态加载渲染,此时动态插入的script标签会被浏览器正常解析执行
- 直接输入URL访问时触发服务端渲染(SSR/SSG)流程,你从CMS获取的HTML内容大概率是通过
v-html指令渲染到页面,浏览器默认不会执行v-html内部插入的script标签,因此脚本失效。
解决方案
不需要硬编码任何CMS输出的脚本内容,只需要在页面客户端挂载完成后,手动提取CMS渲染容器内的script标签重建插入,即可触发浏览器执行脚本,示例代码如下:
<template> <!-- 渲染CMS返回的HTML内容的容器 --> <div ref="cmsContentRef" v-html="cmsHtmlContent" /> </template> <script setup> // 从CMS接口获取的完整HTML内容,包含你给出的脚本与DOM代码 const cmsHtmlContent = ref('') const cmsContentRef = ref(null) // Nuxt3可直接用useClientOnly判断客户端环境 const { isClient } = useClientOnly() onMounted(() => { if (!isClient.value || !cmsContentRef.value) return // 提取容器内所有的script标签 const originScripts = cmsContentRef.value.querySelectorAll('script') originScripts.forEach(oldScript => { // 新建全新的script标签替换原有标签 const newScript = document.createElement('script') // 复制原有标签的所有属性(比如src、type等) Array.from(oldScript.attributes).forEach(attr => { newScript.setAttribute(attr.name, attr.value) }) // 复制内联脚本的内容 if (oldScript.textContent) { newScript.textContent = oldScript.textContent } // 替换旧标签,新插入的标签会被浏览器自动执行 oldScript.parentNode.replaceChild(newScript, oldScript) }) }) </script>
如果是Nuxt2项目,去掉useClientOnly相关逻辑,直接用process.client判断是否在客户端环境即可。
该方案完全适配CMS动态输出的脚本内容,不需要在项目内硬编码任何脚本参数,同时保证客户端路由跳转和直接访问URL两种场景下脚本都能正常执行。
内容的提问来源于stack exchange,提问作者Michael Story
相关产品推荐
相关产品推荐

