如何在 vuejs 中绑定 html <title> 内容?
How can I bind the html <title> content in vuejs?
我正在尝试使用 vuejs 进行演示。现在我想要 html 标题绑定一个 vm 字段。
下面是我试过的:
index.html
<!DOCTYPE html>
<html id="html">
<head>
<title>{{ hello }}</title>
<script src="lib/requirejs/require.min.js" data-main="app"></script>
</head>
<body>
{{ hello }}
<input v-model="hello" title="hello" />
</body>
</html>
app.js
define([
'jquery', 'vue'
], function ($, Vue) {
var vm = new Vue({
el: 'html',
data: {
hello: 'Hello world'
}
});
});
但是标题好像没有绑定,请问如何设置?
此答案适用于 vue 1.x
使用 requirejs。
define([
'https://cdn.jsdelivr.net/vue/latest/vue.js'
], function(Vue) {
var vm = new Vue({
el: 'html',
data: {
hello: 'Hello world'
}
});
});
<!DOCTYPE html>
<html id="html">
<head>
<title>{{ hello }}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.js" data-main="app"></script>
</head>
<body>
{{ hello }}
<input v-model="hello" title="hello" />
</body>
</html>
你可以像这样使用 ready 函数来设置初始值并在数据变化时观察更新。
<html>
<head>
<title>Replace Me</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<input v-model="title">
</div>
<script>
new Vue({
el: '#app',
ready: function () {
document.title = this.title
},
data: {
title: 'My Title'
},
watch: {
title: function (val, old) {
document.title = val
}
}
})
</script>
</body>
</html>
我也根据您的原始代码尝试了这个并且有效
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<input v-model="title">
</div>
<script>
new Vue({
el: 'html',
data: {
title: 'My Title'
}
})
</script>
</body>
</html>
基本上有两种方法可以解决。
使用现有的包
例如,vue-meta:
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
metaInfo: {
// if no subcomponents specify a metaInfo.title, this title will be used
title: 'Default Title',
// all titles will be injected into this template
titleTemplate: '%s | My Awesome Webapp'
}
}
</script>
创建您自己的组件
创建一个 vue 文件包含:
<script>
export default {
name: 'vue-title',
props: ['title'],
watch: {
title: {
immediate: true,
handler() {
document.title = this.title;
}
}
},
render () {
},
}
</script>
使用
注册组件
import titleComponent from './title.component.vue';
Vue.component('vue-title', titleComponent);
然后您可以在模板中使用它,例如
<vue-title title="Static Title"></vue-title>
<vue-title :title="dynamic.something + ' - Static'"></vue-title>
标题和元标记可以异步编辑和更新。
您可以使用状态管理,使用 vuex 创建 SEO 商店并相应地更新每个部分。
或者您可以自己轻松更新元素
created: function() {
ajax().then(function(data){
document.title = data.title
document.head.querySelector('meta[name=description]').content = data.description
})
}
您可以在 App.vue 文件中使用 1 行,如下所示:
<script>
export default {
name: 'app',
created () {
document.title = "Look Ma!";
}
}
</script>
或在public/index.html
中更改<title>
标签内容
<!DOCTYPE html>
<html>
<head>
<title>Look Ma!</title> <!- ------ Here ->
</head>
...
只是想在这里插话。我读过 VueJS 不想与元数据有任何关系,所以我会在 "VueJS" 领域之外做这样的事情。
基本上制作如下所示的普通 js 服务。您可以在此处添加所有函数来处理元数据,例如 Open Graph 数据。
meta.js
export setTitle(title) {
document.title = title
}
现在我们可以在 main 中导入服务,然后将其提供给应用程序中需要它的任何组件。我什至可以在其他项目中使用我的 meta
服务,这些项目使用不同的框架,如 React 或 Angular。便携性超棒!
main.js
import meta from './meta'
new Vue({
router,
render: h => h(App),
provide: {
meta: meta
}
}).$mount('#app')
这里组件注入它想要使用的元服务。
someView.vue
export default {
name: 'someView',
inject: ['meta'],
data: function() {
returns {
title: 'Cool title'
}
},
created: function() {
this.meta.setTitle(this.title);
}
}
通过这种方式,元服务与应用程序分离,因为不同的父组件可以 provide
不同版本的 meta
服务。现在您可以实施各种策略来查看哪一种适合您,甚至可以针对每个组件实施不同的策略。
基本上,注入沿着组件层次结构向上走,并从提供它的第一个父级那里获取 meta
服务。只要元服务遵循正确的接口,您就万事大吉。
用 DI 解耦超爽
如果您正在使用 Vuex 并希望 <title>
成为您应用程序状态的一部分,那么:
- 在 Vuex 中创建一个
pageTitle
状态变量
- 使用
mapState()
将状态映射到模板
watch
它在模板中,可能添加 immediate: true
以立即触发观察者
- 在观察者中,
document.title = pageTitle
这将允许您使用 Vuex 管理标题并使它们保持同步。我发现它对 SPA 很有用。
通过这样做,您不必弄乱原来的 HTML 模板,因为大多数时候 Vue 根模板驻留在 <body>
.
中
这是用于 Vue 2.x。
router.beforeEach((to, from, next) => {
let mohican = to.path; if (mohican == '/') mohican = 'Home'
document.title = mohican.replace('/','');
next();
return;
});
我有一个应用程序工具栏组件,它对我的 SPA 网站的所有页面都是通用的,并且嵌套在 App.vue 中。在每个页面中,我使用 Vuex store 在页面的 created 挂钩中更新我的常用工具栏标题:
//in every page.vue
created() {
this.$store.commit('toolBar', { pageTitle: this.pageTitle, ... })
},
为了自动更新网站标题(连同工具栏标题),我在商店中使用了这个突变:
//store.js
toolBar(state,val){
document.title = val.pageTitle
state.toolBar = val
},
同样,我使用相同的机制来更新例如SEO 元数据
我正在尝试使用 vuejs 进行演示。现在我想要 html 标题绑定一个 vm 字段。
下面是我试过的:
index.html
<!DOCTYPE html>
<html id="html">
<head>
<title>{{ hello }}</title>
<script src="lib/requirejs/require.min.js" data-main="app"></script>
</head>
<body>
{{ hello }}
<input v-model="hello" title="hello" />
</body>
</html>
app.js
define([
'jquery', 'vue'
], function ($, Vue) {
var vm = new Vue({
el: 'html',
data: {
hello: 'Hello world'
}
});
});
但是标题好像没有绑定,请问如何设置?
此答案适用于 vue 1.x
使用 requirejs。
define([
'https://cdn.jsdelivr.net/vue/latest/vue.js'
], function(Vue) {
var vm = new Vue({
el: 'html',
data: {
hello: 'Hello world'
}
});
});
<!DOCTYPE html>
<html id="html">
<head>
<title>{{ hello }}</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.js" data-main="app"></script>
</head>
<body>
{{ hello }}
<input v-model="hello" title="hello" />
</body>
</html>
你可以像这样使用 ready 函数来设置初始值并在数据变化时观察更新。
<html>
<head>
<title>Replace Me</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<input v-model="title">
</div>
<script>
new Vue({
el: '#app',
ready: function () {
document.title = this.title
},
data: {
title: 'My Title'
},
watch: {
title: function (val, old) {
document.title = val
}
}
})
</script>
</body>
</html>
我也根据您的原始代码尝试了这个并且有效
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<input v-model="title">
</div>
<script>
new Vue({
el: 'html',
data: {
title: 'My Title'
}
})
</script>
</body>
</html>
基本上有两种方法可以解决。
使用现有的包
例如,vue-meta:
<template> <div id="app"> <router-view></router-view> </div> </template> <script> export default { name: 'App', metaInfo: { // if no subcomponents specify a metaInfo.title, this title will be used title: 'Default Title', // all titles will be injected into this template titleTemplate: '%s | My Awesome Webapp' } } </script>
创建您自己的组件
创建一个 vue 文件包含:
<script>
export default {
name: 'vue-title',
props: ['title'],
watch: {
title: {
immediate: true,
handler() {
document.title = this.title;
}
}
},
render () {
},
}
</script>
使用
注册组件import titleComponent from './title.component.vue';
Vue.component('vue-title', titleComponent);
然后您可以在模板中使用它,例如
<vue-title title="Static Title"></vue-title>
<vue-title :title="dynamic.something + ' - Static'"></vue-title>
标题和元标记可以异步编辑和更新。
您可以使用状态管理,使用 vuex 创建 SEO 商店并相应地更新每个部分。
或者您可以自己轻松更新元素
created: function() {
ajax().then(function(data){
document.title = data.title
document.head.querySelector('meta[name=description]').content = data.description
})
}
您可以在 App.vue 文件中使用 1 行,如下所示:
<script>
export default {
name: 'app',
created () {
document.title = "Look Ma!";
}
}
</script>
或在public/index.html
<title>
标签内容
<!DOCTYPE html>
<html>
<head>
<title>Look Ma!</title> <!- ------ Here ->
</head>
...
只是想在这里插话。我读过 VueJS 不想与元数据有任何关系,所以我会在 "VueJS" 领域之外做这样的事情。
基本上制作如下所示的普通 js 服务。您可以在此处添加所有函数来处理元数据,例如 Open Graph 数据。
meta.js
export setTitle(title) {
document.title = title
}
现在我们可以在 main 中导入服务,然后将其提供给应用程序中需要它的任何组件。我什至可以在其他项目中使用我的 meta
服务,这些项目使用不同的框架,如 React 或 Angular。便携性超棒!
main.js
import meta from './meta'
new Vue({
router,
render: h => h(App),
provide: {
meta: meta
}
}).$mount('#app')
这里组件注入它想要使用的元服务。
someView.vue
export default {
name: 'someView',
inject: ['meta'],
data: function() {
returns {
title: 'Cool title'
}
},
created: function() {
this.meta.setTitle(this.title);
}
}
通过这种方式,元服务与应用程序分离,因为不同的父组件可以 provide
不同版本的 meta
服务。现在您可以实施各种策略来查看哪一种适合您,甚至可以针对每个组件实施不同的策略。
基本上,注入沿着组件层次结构向上走,并从提供它的第一个父级那里获取 meta
服务。只要元服务遵循正确的接口,您就万事大吉。
用 DI 解耦超爽
如果您正在使用 Vuex 并希望 <title>
成为您应用程序状态的一部分,那么:
- 在 Vuex 中创建一个
pageTitle
状态变量 - 使用
mapState()
将状态映射到模板
watch
它在模板中,可能添加immediate: true
以立即触发观察者- 在观察者中,
document.title = pageTitle
这将允许您使用 Vuex 管理标题并使它们保持同步。我发现它对 SPA 很有用。
通过这样做,您不必弄乱原来的 HTML 模板,因为大多数时候 Vue 根模板驻留在 <body>
.
这是用于 Vue 2.x。
router.beforeEach((to, from, next) => {
let mohican = to.path; if (mohican == '/') mohican = 'Home'
document.title = mohican.replace('/','');
next();
return;
});
我有一个应用程序工具栏组件,它对我的 SPA 网站的所有页面都是通用的,并且嵌套在 App.vue 中。在每个页面中,我使用 Vuex store 在页面的 created 挂钩中更新我的常用工具栏标题:
//in every page.vue
created() {
this.$store.commit('toolBar', { pageTitle: this.pageTitle, ... })
},
为了自动更新网站标题(连同工具栏标题),我在商店中使用了这个突变:
//store.js
toolBar(state,val){
document.title = val.pageTitle
state.toolBar = val
},
同样,我使用相同的机制来更新例如SEO 元数据