Vue関連の小ネタ

# Vue
## unwatchしたい
```js
export default {
  props : {
    value : {
      type : String,
      required : true
    }
  }
  data(){
    watcher : null
  },
  created(){
    this.watcher = this.$watch(value, (newVal, oldVal) => {
      this.unsetWatcher();
    });
  },
  methods : {
    unsetWatcher(){}
  }
}
```


https://stackoverflow.com/questions/46987893/vuejs2-how-can-i-destroy-a-watcher

# Vuex
## 値をwatchしたい
```javascript
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state : {
    name : 'Nozomi',
    changed : false,
  },
  commit : {
    transform: ( state ) => {
      // のぞみはキュアドリームに変身するココ
      state.name = "CureDream"
    },
    cancel: ( state ) => {
      // キュアドリームの変身を解除するナツ
      state.name = "Nozomi"
    }
  }
});


store.watch(
  state => state.changed,
  (newVal, oldVal) => {
    if(newVal){
      store.commit('transform')
    } else {
      store.commit('cancel')
    }
  }
);

export default store;
```

## Promiseを用いた再帰呼出し
◎contextからdispatchを分割代入にて取得、dispatchを行うメソッド名を、実行されている関数と同じ名前を引数にわたすことにより、再帰処理が実現される。


```javascript
import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

Vue.use(Vuex);

const store = new Vuex.Store({
  action : {
    getResource : ({ dispatch }, payload) => {
      const { result } = payload;
      if ( result === 'ok' ){
        // dispatch('getResource')の戻り値になる
        return Promise.resolve(result);
      } else {
        return new Promise(resolve, reject)=> {
          // http://sample.api.co.jp/api/からajaxにより値を取得
          axios.get('http://sample.api.co.jp/api/')
            .then(result => {
              if ( result !== 'ok' ){
                // ここで再帰呼び出し
                // dispatchの戻り値がPromise.resolveならば、次のthenへ
                // dispatchの戻り値がPromise.rejectならば、catchされる
                return dispatch('getResource', result )
              }
              // 次のthenに進む
              return resolve(result)
            })
            .then(result => {
              // この段階で、ajaxにて取得した処理を返却
              // 呼び出し元にて、何らかの処理を行えるようになります
              return resolve(result)
            })
            .catch(err => {
              return reject(err)
            })
        }
      }
    }
  }
});

export default store;
```

## リロードが行われても、storeの中身はそのままにしておく
storeの値はリロード時にはサーバーサイドから値を返却してもらうか、localStrageに保存しておくかを考慮しておく必要があります。自前で実装しても問題ありませんが、以下のプラグインを利用すると楽に実装できます。車輪の再発明はしない...！！

◎vuex-persistedstate
https://github.com/robinvdvleuten/vuex-persistedstate

```javascript
import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from "vuex-persistedstate";

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    heros : [
      { name: 'nagisa', id: 1 },
      { name: 'honoka', id: 2 },
    ]
  },
  mutations: {},
  actions: {},
  getters: {},
  // pluginを追加
  plugins: [createPersistedState()]
});

export default store;

```

参考：『【Vuex】リロードしてもStateの中身を消さずに維持する方法』
https://pizzamanz.net/web/vue/vuex-persistedstate/

# Vue-Router
## uriは異なるけれどだいたい同じような画面にはしておきたい
◎childrenというプロパティを使う

```javascript
import Vue from 'vue';
import Router from 'vue-router';
import PrecureFive from '@PrecureFive'
import PrecureFiveGoGo from '@PrecureFiveGoGo'
import Ch01 from '@Ch01'
import Ch02 from '@Ch02'
import Ch01ex from '@Ch01ex'
import Ch02ex from '@Ch02ex'

Vue.use(Router);

export default new Router({
    mode: 'history',
    base: '/precure-five',
    routes: [
        {
            // プリキュア5のページ
            path: '/',
            component: PrecureFive,
            props: true,
            children: [
                {
                    // /precure-five/ch-01 にアクセスしたら表示されるページ
                    path: 'ch-01',
                    component: Ch01
                },
                {
                    // /precure-five/ch-02 にアクセスしたら表示されるページ
                    path: 'ch-02',
                    component: Ch02
                }
            ]
        },
        {
            // プリキュア5GoGo用に新しくページが追加された
            path: '/go-go',
            component: PrecureFiveGoGo,
            children: [
                {
                    // /precure-five/go-go/ch-01 にアクセスしたら表示されるページ
                    path: 'ch-01',
                    component: Ch01ex
                },
                {
                    // /precure-five/go-go/ch-02 にアクセスしたら表示されるページ
                    path: 'ch-02',
                    component: Ch02ex
                }
            ]
        }
    ]
});
```

これだけ書いてもイメージはわきにくいのですが、uriの切り替えにより、共通の部分はそのままにしながら、uriをみて中身のコンテンツだけ差し替わる感じです。

... 以降もちょいちょい書く予定。（2019-09-23 updated）