Vue组件里动态设置SEO标题和meta标签为什么没效果?

夏侯威威 阅读 37

我在用Vue 3开发博客页面时,想在组件里动态设置SEO标题和description标签。按照文档用了vue-meta插件,但页面加载后这些标签都没渲染出来,浏览器标题还是默认的”Vue App”。

代码是这样的:


<template>
  <div>
    <Head>
      <Title>{{ article.title }} | 博客</Title>
      <Meta name="description" :content="article.summary" />
    </Head>
    <!-- 页面内容 -->
  </div>
</template>

<script setup>
import { ref } from 'vue'
const article = ref({ title: '测试文章', summary: '这是测试简介' })
</script>

我已经安装了vue-meta并在main.js里注册了,但控制台没报错。用开发者工具查看head标签时,连meta标签的结构都没生成。是不是动态数据加载顺序有问题?或者需要额外配置什么?

我来解答 赞 11 收藏
二维码
手机扫码查看
2 条解答
Mc.芯依
Mc.芯依 Lv1
我猜你用的应该是 vue-meta 这个老版本插件,但它在 Vue 3 里其实已经不维护了,而且和 Vue 3 的 Composition API 不太兼容,所以你写 <Head> <Title> 这些标签根本不会被识别,也不会被渲染到 <head> 里。

Vue 3 推荐用的是 @vueuse/head 这个库,它更轻量、更符合 Vue 3 的风格,也支持 SSR(服务端渲染),而且和 Composition API 天然契合。

下面我给你一步步来改:

第一步,先卸载旧的 vue-meta(如果装了的话):

npm uninstall vue-meta


第二步,装新库:

npm install @vueuse/head


第三步,在 main.js 里正确注册(注意不是 app.use(),而是直接挂载到 app 的 config.globalProperties 里,或者更推荐的方式是用 app.use() 但得用新写法):

// main.js
import { createApp } from 'vue'
import { createHead } from '@vueuse/head'
import App from './App.vue'

const app = createApp(App)
const head = createHead()

app.use(head)
app.mount('#app')


这里要注意:一定要在 createApp 之后、mount 之前调用 createHead()app.use(head),顺序错了也会不生效。

第四步,改你的组件写法:

<template>
<div>
<h1>{{ article.title }}</h1>
<p>{{ article.summary }}</p>
<!-- 页面内容 -->
</div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useHead } from '@vueuse/head'

const article = ref({
title: '测试文章',
summary: '这是测试简介'
})

// 用 useHead 这个 composable 函数来动态设置 meta
useHead({
title: () => article.value.title + ' | 博客',
meta: [
{
name: 'description',
content: () => article.value.summary
}
]
})
</script>


这里要注意几个细节:

- titlecontent 都可以写成函数,这样当 article 是响应式数据时,它会自动更新 head 内容,不需要你手动 watch
- 如果你用的是静态值,也可以直接写字符串,比如 title: '固定标题'
- 有些浏览器里你可能看到 title 没变,但刷新一下页面(或者在开发者工具的 Network 里切到 Disable cache)就能看到效果

第五步,验证是否生效:

打开浏览器开发者工具,切换到 Elements 标签,找到 <head>,你应该能看到类似这样的内容:

<head>
<title>测试文章 | 博客</title>
<meta name="description" content="这是测试简介">
<!-- 其他默认 meta -->
</head>


如果还是没变化,建议你检查:

- 确保 main.jsapp.use(head) 写对了位置(必须在 app.mount 之前)
- 确保你没在 head 里手动写死 <title>Vue App</title>,如果写死了,后面动态设置的可能会被覆盖(虽然一般不会,但有时候会)
- 如果你用了 Vue Router,确保路由跳转时组件确实被重新渲染了(不是 keep-alive 缓存的)

另外,如果你项目里用了 SSR(比如 Nuxt),那这套写法也适用,但得注意 useHead 要在组件 setup 里调用,不能放在 onMounted 里,不过你这应该是 SPA,所以没问题。

我之前踩过一个坑:用 vue-meta 的时候,文档写得挺模糊,它要求你在组件里写 <Head>,但这个组件必须是根组件或者某个特定结构,而 Vue 3 里根本没这个限制——@vueuse/head 直接用 useHead 函数,更灵活也更符合 Vue 3 的习惯。

如果按上面步骤还是不行,把你的 main.js 和组件完整代码贴出来,我帮你看看是不是哪里漏了。
点赞 3
2026-02-26 20:02
Designer°翌萌
你这个问题是因为vue-meta在Vue 3里已经被废弃了,现在官方推荐用@vueuse/head。我之前也踩过这个坑,换这个库就解决了。

把代码改成这样:
import { useHead } from '@vueuse/head'

const article = ref({ title: '测试文章', summary: '这是测试简介' })
useHead({
title: article.value.title + ' | 博客',
meta: [
{ name: 'description', content: article.value.summary }
]
})


记得先安装依赖 npm install @vueuse/head,然后在main.js里注册 import { createHead } from '@vueuse/head'; app.use(createHead())。动态数据建议在onMounted里设置,确保加载顺序没问题。
点赞 4
2026-02-19 13:10