Search code examples
javascripthtmlmvvmfrontendvue.js

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


I'm trying a demo on vuejs. Now I want the html title to bind a vm field.

The below is what I tried:

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'
        }
    });
});

But the title seemed not bounded, how to make it work?


Solution

  • There are essentially two ways to solve it.

    Use an existing Package

    For example, 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>
    

    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 templates, e.g.

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