web-dev-qa-db-ja.com

Vue.js:ページタイトルを異なるルートに割り当てる

Vue.js v1.0、vue-router v0.7、およびWebPackを使用してWebアプリケーションを構築しています。私は 単一ファイルコンポーネント パターンをフォローしており、ページごとに異なるコンポーネントがあります。

Webアプリのページをナビゲートしているときに、さまざまなルーティング(またはさまざまなコンポーネント)でページタイトルを変更する方法がわかりません。また、ブラウザの履歴でページタイトルを利用できるようにしたいと思います。

10
jmosawy

ここに投稿された以前の解決策に加えて、少し調査した後に見つけた2番目の方法があります:use Navigation Guards

以前の回答で詳しく説明したように、ここに問題があります:vue-routerは、初めて作成された後、ルートコンポーネントの再利用を開始する場合があります。ルート出口でこれらのコンポーネントを破棄し、後続のルート入口で再作成する必要は実際にはありません。したがって、以前のソリューションのcreatedフックは、同じルートへの後続の訪問で起動しない可能性があります。したがって、ウィンドウタイトルが期待どおりに機能しない可能性があります。

この問題を解決するために、route-changeイベントにウィンドウタイトルを設定できます。ルーターインスタンスには、ルート変更後に呼び出されるafterEachフックがあります。これは、以下に詳述するようにウィンドウタイトルを設定するために使用できます。

// Let's say this is your router instance, with all "Named Routes"
const ROUTER_INSTANCE = new VueRouter({
    mode: "history",
    routes: [
        { path: "/", name: "HomeComponentName", component: HomeComponent },
        { path: "/about", name: "AboutComponentName", component: AboutComponent },
        { path: "*", name: "RouteErrorName", component: RouteError }
    ]
})

// Assign page titles for each of the "named routes"
// Reason: This allows us to have short named routes, with descriptive title
const PAGE_TITLE = {
    "HomeComponentName": "Your Dashboard",
    "AboutComponentName": "About Us Page",
    "RouteErrorName": "Error: Page not found"
}

ROUTER_INSTANCE.afterEach((toRoute, fromRoute) => {
    window.document.title = PAGE_TITLE[toRoute.name]
    console.log(toRoute)  // this lets you check what else is available to you here
})

「/ user/foo」から「/ user/bar」など、同様のルート間を移動している場合でも、これは役に立たない可能性があります。タイトルバーまたは動的なページ固有の情報にユーザー名が必要な場合は、 http://router.vuejs.org/en/essentials/dynamicで詳しく説明されているようにルーターの変更への対応を確認してください。 -matching.html 。ドキュメントに基づいて、コンポーネントでwatchを次のように使用できるはずです。

watch: {
    '$route' (toRoute, fromRoute) {
        window.document.title = "some page title"
    }
}

それが役に立てば幸い!

11
Mani

数日前にも同じ問題が発生し、ルートコンポーネントの定義で次のように解決しました。

export default {
    created: function() {
        window.document.title = "Page Title for this route"
        ...
    },
    ...
}

それは本当に正しいやり方ではありません。理由:新しいルートに変更するたびにroute componentが作成されるという大きな仮定を立てています。現時点ではvue-routerに当てはまりますが、将来変更される可能性があります。

以前はAngular 1.4でui-routerを使用していました。これにより、ルートコンポーネントがメモリ(スティッキー状態)に存在できるため、ルートの変更は次の瞬間に行われます。時間。vue-routerスティッキー状態のようなものを実装した場合、上記のcreatedフックでタイトルを設定する方法は失敗します。

しかし、それが起こるまでは、このソリューションを使用できます。

4
Mani

私は解決策を持っていて、それを私の projects の1つで使用しました。

最初にディレクティブを作成します。

Vue.directive('title', {
  inserted: (el, binding) => document.title = binding.value,
  update: (el, binding) => document.title = binding.value
})

'MyComponent.vue'ファイルで作業しているとします。

次に、そのディレクティブをrouter-viewコンポーネントで使用します。

<router-view v-title="title" ></router-view>

export default {
  data(){
    return {
      title: 'This will be the title'
    }
  }
}

これは、コンポーネントが更新されたり、ページが再ロードされたりした場合でも機能します。

私にとってはとてもうまくいきました!

2
Faiyaz Shaikh