Как я могу связать HTML-контент <title> в 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'
}
});
});
Но название казалось не ограниченным, как заставить его работать?
9 ответов
Как я предпочитаю устанавливать <title>
с точки зрения, есть, по сути, два пути ее решения.
Использовать существующий компонент
Например, vue-headful:
устанавливать
npm i vue-headful
Зарегистрировать компонент:
import Vue from 'vue'; import vueHeadful from 'vue-headful'; Vue.component('vue-headful', vueHeadful); new Vue({ // your configuration });
А затем используйте компонент vue-headful в каждом из ваших представлений:
<template> <div> <vue-headful title="Title from vue-headful" description="Description from vue-headful" /> </div> </template>
Обратите внимание, что vue-headful поддерживает не только заголовок, но также несколько метатегов и язык документа.
Создайте свой собственный компонент
Создайте файл VUE, содержащий:
<script>
export default {
name: 'vue-title',
props: ['title'],
created () {
document.title = this.title;
},
watch: {
title () {
// only used when the title changes after page load
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>
Вы можете сделать это с 1 строкой в файле App.vue, например так:
<script>
export default {
name: 'app',
created () {
document.title = "Look Ma!";
}
}
</script>
Или изменить <title>
пометить содержимое в public/index.html
<!DOCTYPE html>
<html>
<head>
<title>Look Ma!</title> <!- ------ Here ->
</head>
...
Этот ответ для 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>
Просто позвонить сюда. Я читал, что 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 очень круто
Заголовок и метатеги могут редактироваться и обновляться асинхронно.
Вы можете использовать управление состоянием, создать магазин для SEO с помощью vuex и соответственно обновить каждую часть.
Или вы можете легко обновить элемент самостоятельно
created: function() {
ajax().then(function(data){
document.title = data.title
document.head.querySelector('meta[name=description]').content = data.description
})
}
Если вы используете Vuex и хотите
<title>
чтобы быть частью состояния вашего приложения, тогда:
- создать
pageTitle
переменная состояния в Vuex - сопоставить состояние с шаблоном, используя
mapState()
-
watch
это в шаблоне, возможно, добавитьimmediate: true
сразу вызвать наблюдателя - в наблюдателе,
document.title = pageTitle
Это позволит вам управлять заголовками с помощью Vuex и синхронизировать их. Я нашел это полезным для СПА.
Таким образом вам не придется возиться с исходным 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:
//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.