为你的网站提供更好的 SEO!Meta 插件可以动态更改页面标题、管理 <meta>
标签、管理 <html>
和 <body>
DOM 元素属性、在文档头部添加/删除/更改 <style>
和 <script>
标签(例如,对于 CDN 样式表或 json-ld 标记很有用),或管理 <noscript>
标签。
¥Better SEO for your website! The Meta plugin can dynamically change page title, manage <meta>
tags, manage <html>
and <body>
DOM element attributes, add/remove/change <style>
and <script>
tags in the head of your document (useful for CDN stylesheets or for json-ld markup, for example), or manage <noscript>
tags.
提示
充分利用此功能,并将其与 Quasar CLI 结合使用,尤其是在 SSR(服务器端渲染)构建中。将其用于 SPA(单页应用)也可能有意义,但是在这种情况下,元信息将在运行时添加,而不是由 Web 服务器直接提供(就像在 SSR 版本中一样)。像 Googlebot 这样的现代网络爬虫可以渲染动态页面并提取动态设置的元信息。
¥Take full advantage of this feature by using it with Quasar CLI, especially for the SSR (Server-Side Rendering) builds. It may make sense to use it for SPA (Single Page Applications) too, however the meta information in this case will be added at runtime and not supplied directly by the webserver (as on SSR builds). Modern web-crawlers like the Googlebot may render dynamic pages and extract out the dynamically set meta information.
// quasar.config file
return {
framework: {
plugins: [
'Meta'
]
}
}
用法(Usage)
¥Usage
Meta 插件的作用是,它允许在 Vue 组件中使用一个名为 meta
的特殊属性。查看下面的示例,它几乎包含了所有功能。
¥What the Meta plugin does is that it enables the use of a special property in your Vue components called meta
. Take a look at the example below, with almost all of its features.
重要!
确保不要复制 /index.html 中已存在的内容。如果你想使用 Meta 插件,建议从 HTML 模板中删除相同的标签。但在你知道某个标签永远不会改变并且你始终希望它被渲染的用例中,最好将其仅放在 html 模板中。
¥Make sure not to duplicate content that already exists in /index.html. If you want to use the Meta plugin, the recommended way is to remove the same tags from the html template. But on use-cases where you know a tag will never change and you always want it rendered, then it’s better to have it only on the html template instead.
组合 API(Composition API)
¥Composition API
我们将使用 useMeta 可组合项。
¥We will be using the useMeta composable.
import { useMeta } from 'quasar'
const metaData = {
// sets document title
title: 'Index Page',
// optional; sets final title as "Index Page - My Website", useful for multiple level meta
titleTemplate: title => `${title} - My Website`,
// meta tags
meta: {
description: { name: 'description', content: 'Page 1' },
keywords: { name: 'keywords', content: 'Quasar website' },
equiv: { 'http-equiv': 'Content-Type', content: 'text/html; charset=UTF-8' },
// note: for Open Graph type metadata you will need to use SSR, to ensure page is rendered by the server
ogTitle: {
property: 'og:title',
// optional; similar to titleTemplate, but allows templating with other meta properties
template (ogTitle) {
return `${ogTitle} - My Website`
}
}
},
// CSS tags
link: {
material: { rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons' }
},
// JS tags
script: {
ldJson: {
type: 'application/ld+json',
innerHTML: `{ "@context": "http://schema.org" }`
}
},
// <html> attributes
htmlAttr: {
'xmlns:cc': 'http://creativecommons.org/ns#', // generates <html xmlns:cc="http://creativecommons.org/ns#">,
empty: undefined // generates <html empty>
},
// <body> attributes
bodyAttr: {
'action-scope': 'xyz', // generates <body action-scope="xyz">
empty: undefined // generates <body empty>
},
// <noscript> tags
noscript: {
default: 'This is content for browsers with no JS (or disabled JS)'
}
}
export default {
setup () {
// needs to be called in setup()
useMeta(metaData)
}
}
如果你依赖组件的状态来计算元对象,那么你可以提供一个函数而不是对象本身。有关更多信息,请查看此页面上的 “响应式” 部分。
¥If you depend on the state of the component to compute the meta Object, then you can supply a Function instead of the Object itself. For more information, check the “Reactive” section on this page.
选项 API(Options API)
¥Options API
import { createMetaMixin } from 'quasar'
const metaData = {
// sets document title
title: 'Index Page',
// optional; sets final title as "Index Page - My Website", useful for multiple level meta
titleTemplate: title => `${title} - My Website`,
// meta tags
meta: {
description: { name: 'description', content: 'Page 1' },
keywords: { name: 'keywords', content: 'Quasar website' },
equiv: { 'http-equiv': 'Content-Type', content: 'text/html; charset=UTF-8' },
// note: for Open Graph type metadata you will need to use SSR, to ensure page is rendered by the server
ogTitle: {
property: 'og:title',
// optional; similar to titleTemplate, but allows templating with other meta properties
template (ogTitle) {
return `${ogTitle} - My Website`
}
}
},
// CSS tags
link: {
material: { rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons' }
},
// JS tags
script: {
ldJson: {
type: 'application/ld+json',
innerHTML: `{ "@context": "http://schema.org" }`
}
},
// <html> attributes
htmlAttr: {
'xmlns:cc': 'http://creativecommons.org/ns#', // generates <html xmlns:cc="http://creativecommons.org/ns#">
empty: undefined // generates <html empty>
},
// <body> attributes
bodyAttr: {
'action-scope': 'xyz', // generates <body action-scope="xyz">
empty: undefined // generates <body empty>
},
// <noscript> tags
noscript: {
default: 'This is content for browsers with no JS (or disabled JS)'
}
}
export default {
mixins: [
createMetaMixin(metaData)
]
}
对于 Options API 方法,如果你依赖组件的状态来计算元对象,则可以提供一个函数而不是对象本身:
¥For the Options API approach, if you depend on the state of the component to compute the meta Object, then you can supply a Function instead of the Object itself:
export default {
mixins: [
createMetaMixin(function () {
// "this" here refers to your component
return {
// assuming `this.myTitle` exists in your mixed in component
title: this.myTitle
}
})
]
}
工作原理(How It Works)
¥How It Works
Metas 是根据 .vue 文件计算出来的,其顺序取决于 Vue 组件被 Vue Router 激活的顺序(为了便于解释,我们称之为“链”)。示例:App.vue > SomeLayout.vue > IndexPage.vue > …?
¥Metas are computed from .vue files in the order their vue components are activated by Vue Router (let’s call this a chain for further explanations). Example: App.vue > SomeLayout.vue > IndexPage.vue > …?
当使用 Meta 插件的组件被渲染或销毁时,它会被添加到链中/从链中移除,并且元数据也会相应地更新。
¥When a component that uses Meta plugin gets rendered or destroyed, it is added/removed to/from the chain and metas are updated accordingly.
处理 HTML 属性(Handling HTML attributes)
¥Handling HTML attributes
当你需要在 meta
、link
或 script
部分设置布尔值 HTML 属性时,请将其值设置为布尔值 true
。
¥When you need to set a Boolean HTML attribute in meta
, link
or script
sections, set its value to Boolean true
.
script: {
myScript: {
src: 'https://...',
defer: true
}
}
// will output:
// <script src="https://..."
// defer
// data-qmeta="myScript">
如果你有一个属性,并且想要将其设置为 “true” 的实际值,请使用字符串形式。更多详情以下:
¥If you have an attribute and you want to set it to the actual value of “true”, then use String form. More details below:
someattribute: 'true'
// will output: someattribute="true"
someattribute: true
// will output: someattribute
someattribute: void 0
// will NOT output the attribute
// (useful when you set it upstream
// and want to remove it downstream)
someattribute: ''
// will output: someattribute=""
非响应式(Non-reactive)
¥Non-reactive
请注意,所有属性(title 和 titleTemplate 除外)都是对象;你可以再次使用相同的键来覆盖链中先前 Vue 组件中定义的元属性。示例:
¥Notice that all properties (except for title and titleTemplate) are Objects; you can override meta props defined in previous Vue components in the chain by using the same keys again. Example:
// first loaded Vue component
setup () {
useMeta({
meta: {
myKey: { name: 'description', content: 'My Website' }
}
})
}
// a subsequent Vue component in the chain;
// this will override the first definition on "myKey"
setup () {
useMeta({
meta: {
myKey: { name: 'description', content: 'Page 1' }
}
})
}
响应式(Reactive)
¥Reactive
在上面的部分中,你注意到所有元属性都是 “static”。但如果你愿意,它们可以是动态的(响应式的)。你可以这样像使用 Vue 计算属性一样管理它们:
¥In the section above, you noticed all of the meta props are “static”. But they can be dynamic (reactive) instead, should you wish. This is how you can manage them just as with a Vue computed property:
import { useMeta } from 'quasar'
import { ref } from 'vue'
export default {
setup () {
const title = ref('Some title') // we define the "title" prop
// NOTICE the parameter here is a function
// Under the hood, it is converted to a Vue computed prop for reactivity
useMeta(() => {
return {
// whenever "title" from above changes, your meta will automatically update
title: title.value
}
})
function setAnotherTitle () {
title.value = 'Another title' // will automatically trigger a Meta update due to the binding
}
return {
setAnotherTitle
}
}
}
测试元信息(Testing Meta)
¥Testing Meta
在部署之前,你务必确保元标记的编辑工作符合规范。虽然你可以直接将链接复制粘贴到 Discord 聊天、Facebook 帖子或推文中,但我们建议你使用 https://metatags.io/ 进行验证。
¥Before you deploy, you really should make sure that your work on the meta tags is compliant. Although you could just copy and paste your link into a Discord chat, a Facebook post or a Tweet, we recommend verifying with https://metatags.io/.
重要!
此测试仅适用于 SSR 构建,因为 SSR 在访问 Web 服务器时直接提供渲染后的 HTML(与 SPA 或 PWA 不同,SPA 或 PWA 会提供空白页面,然后加载在客户端浏览器上渲染页面的代码)。像上述服务(metatags.io)在获取页面时期望页面已经渲染完成(它不会自行运行 JS 进行渲染)。
¥This test will only work for SSR builds because SSR directly supplies the rendered HTML when accessing the webserver (as opposed to SPA or PWA which supplies an empty page then loads the code that renders the page on client’s browser). Services like above (metatags.io) expect the page to be already rendered when fetching it (it does not run the JS to render it themselves).