vue-headとVuexを組み合わせて使う。

#Vuexとvue-head
備忘録です。
動的にページを書き換える事が多い場合は、Vuexで管理します。
いろんなページにメタタグ書き換えを書きまくった結果、ドコで何がメタタグの書き換えをしてるのやら
自分でもワケがわからない感じになってしまったので、一括で管理してやろう、というわけです、

##version
```
$ vue --version
3.5.1
```
私のvueのバージョンは「3」でした。

##tree
```
src
├ views
│　└ Top.vue
├ App.vue
├ main.js
├ router.js
├ store.js
└ vue.config.js
```
大体いつもこんな構成です。

##main.js
```js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import VueHead from 'vue-head'
Vue.use(VueHead,{separator:' '})
new Vue({
  router,
  store,
  render: (h) => h(App)
}).$mount('#app')
```
ココの定義は、まあ普通かと思います。

##store.js
```js
state: {
    meta:{
      title:'',
      description: '',
      keyword: '',
      canonical: '',
      next: '',
      site: '',
      og_image: '',
      author: '',
      apple: '',
      ms: '',
      manifest: '',
    }
},
getters:{
  meta(state) {
    return state.meta;
  },
},
mutations: {
  updateStoreMeta(state, _payload){
    this.state.meta = _payload;
  },
},
actions: {
  // ← ホントはココに書くべき。
}
```
※本当は「actions」にちゃんと書くべきですが、説明めんどいし、コンポーネントに書いちゃう。

##App.vue

```vue
<template>
  <div id="app">
    <router-view />
  </div>
</template>
```
本筋とは関係ないかもですが、vue-routerを使ってます。

```vue
<script>
export default {
  computed:{
    meta(){
      const self = this;
      return self.$store.getters['meta']
    },
  },
  watch: {
    meta(){
      const self = this
      self.$emit('updateHead')
    },
  },
  head:{
    title () {
      const self = this
      return {
        inner: self.meta.title
      }
    },
    meta(){
      const self = this
      return[
        { name: 'format-detection', content: 'telephone=no'},
        { name: 'description', content: self.meta.description },
        { name: 'keyword', content: self.meta.keyword },
        { property: 'og:title', content: self.meta.title },
        { property: 'og:type', content: 'website'},
        { property: 'og:url', content: self.meta.site },
        { property: 'og:image', content: self.meta.og_image},
        { property: 'og:site_name', content: 'サイト名'},
        { property: 'og:description', content: self.meta.description },
        { property: 'og:locale', content: 'ja_JP'},
        { name: 'twitter:card', content: 'summary'},
        { name: 'twitter:site', content: self.meta.site },
        { name: 'twitter:title', content: self.meta.title },
        { name: 'twitter:description', content: self.meta.description },
        { name: 'twitter:image', content: self.meta.og_image },
        { name: 'msapplication-TileImage', content: self.meta.ms },
      ]
    },
    link() {
      const self = this
      return[
        { rel: 'icon', href: '/roujinhome/favicon.ico?', sizes: '48x48'},
        { rel: 'canonical', href: self.meta.canonical },
        { rel: 'next', href: self.meta.next },
        { rel: 'author', href: self.meta.author , undo: false },
        { rel: 'apple-touch-icon', href: self.meta.apple },
        { rel: 'manifest', href: self.meta.manifest },
      ]
    },
  },
}
</script>
```
$store.state.metaをcomputedで呼び出してwatchで監視する。
`manifest.json` とか、いちいち変数にしなくていいやつは適宜除外してください。

##router.js

```js

import Router from 'vue-router'
import Top from './views/Top.vue'
Vue.use(Router)

const router = new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'Top',
      component: Top,
    },
  ],
});
```
例として、ここでは「Top」というコンポーネントをよびだしています。


##Top.vue

```vue
<script>
export default {
  name: 'SrcViewsTopVue',
  created(){
    this.initMeta()
  },
  initMeta(){
      const word = 'トップページ'
      const a = 'https://sample.com/'
      const b = 'vue/'
      const c = 'assets/common/'
      this.$store.commit('updateStoreMeta',{
        title: word + '|ウェブアプリの名前',
        description: word + 'です。ここに説明をかきます',
        keyword: word +'ここに,キーワード,を,たし,ます。',
        canonical: a + b,
        next: a + b,
        site: a + b,
        og_image: a + b + c +'img/og.png',
        author: a + 'wordpress/author/nishi/',
        apple: a + b + c +'img/icon.png',
        ms: a + b+ c +'img/tile.png?fit=270%2C270',
        manifest: a + b + c + 'json/manifest.json',
      });
  },
}
</script>
```
※サンプルなので、変数名にa,b,cとか使っちゃってます。
※使い回せるような説明とかがあれば、別の変数を呼んで使っても、良いと思います。

直接mutationsに投げちゃってるんですが、Vuexをやるからにはめんどくさがらずに、
dispatchとかで書くべきだと思います。↓多分こんなやつ

```js
//上のinitMetaの中身の.commitって書いてある部分の所。
this.$store.dispatch( 'getStoreMeta', {
  //配列
}
```

```js
//store.jsのactions
getStoreMeta( dispatch, array ){
  this.commit( 'updateStoreMeta', array );
},
```
「actions」にまとめた方が、全体的に見通しが良くなると思う。
以上です。