How can I bind the html <title> content in vuejs?

断了今生、忘了曾经 提交于 2019-11-28 04:19:56
str

As I prefer to set the <title> from the view part, there are essentially two ways to solve it.

Use an existing Component

For example, vue-headful:

Install

npm i vue-headful

Register the component:

import Vue from 'vue';
import vueHeadful from 'vue-headful';

Vue.component('vue-headful', vueHeadful);

new Vue({
    // your configuration
});

And then use the vue-headful component in every of your views:

<template>
    <div>
        <vue-headful
            title="Title from vue-headful"
            description="Description from vue-headful"
        />
    </div>
</template>

Note that vue-headful not only supports the title, but also several meta tags and the document language.

Create your own Component

Create a vue file containing:

<script>
    export default {
        name: 'vue-title',
        props: ['title'],
        watch: {
            title: {
                immediate: true,
                handler() {
                    document.title = this.title;
                }
            }
        },
        render () {
        },
    }
</script>

Register the component using

import titleComponent from './title.component.vue';
Vue.component('vue-title', titleComponent);

Then you can use it in your views, e.g.

<vue-title title="Static Title"></vue-title>
<vue-title :title="dynamic.something + ' - Static'"></vue-title>

You can do it with 1 line in the App.vue file, like this:

<script>
    export default {
        name: 'app',
        created () {
            document.title = "Look Ma!";
        }
    }
</script>

Or change the <title> tag content in public/index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Look Ma!</title> <!- ------ Here ->
  </head>
...

This answer is for vue 1.x

using 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>

you can do it like this using the ready function to set the initial value and watch to update when the data changes.

<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>

also i tried this based on your original code and it works

<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>

Title and meta tags can be edited and updated asynchronously.

You can use state management, create a store for SEO using vuex and update each part accordingly.

Or you can update the element by yourself easily

created: function() {  

  ajax().then(function(data){
     document.title = data.title  
     document.head.querySelector('meta[name=description]').content = data.description
  })

}

Just to chime in here. I have read that VueJS wants nothing to do with the meta stuff so I would do such things outside of the "VueJS" realm.

Basically make a plain vanilla js service like below. Here you could add all the functions to handle the meta data stuff such as the Open Graph data.

meta.js

export setTitle(title) {
    document.title = title  
}

Now we can import the service in main and then provide it to any component in the app who wants it. I could even use my meta service in other projects too which use different frameworks like React or Angular. Portability is super cool!

main.js

import meta from './meta'
new Vue({
    router,
    render: h => h(App),
    provide: {
        meta: meta
    }
}).$mount('#app')

Here the component injects the meta service it wants to use.

someView.vue

export default {
    name: 'someView',
    inject: ['meta'],
    data: function() {
        returns {
            title: 'Cool title'
        }
    },
    created: function() {
        this.meta.setTitle(this.title);
    }
}

This way the meta service is decoupled from the app because different parent components can provide different versions of the meta service. Now you can implement various strategies to see which one is right for you or even different strategies per component.

Basically the inject walks up the component hierarchy and takes the meta service from the first parent who provides it. As long as the meta service follows a proper interface, you're golden.

Decoupling with DI is super cool 😃

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!