LoginSignup
1
1

More than 5 years have passed since last update.

初心者がVuexの公式ガイドを勉強するメモ コアコンセプト ステート編

Last updated at Posted at 2018-03-07

Vuex コアコンセプト ステート編

今回のお題は、こちらです。

https://vuex.vuejs.org/ja/core-concepts.html

構成

.
├── README.md
├── index.html
├── package-lock.jsona
├── package.json
├── src
│   ├── App.vue
│   ├── assets
│   │   └── logo.png
│   ├── main.js
│   └── store.js
└── webpack.config.js

ステート

Vuex の状態を Vue コンポーネントに入れる

  • App.vue

<template lang="pug">
  #app
    Counter
</template>

<script>
import Vue from 'vue'
import store from './store.js'

const Counter = {
  name: 'Counter',
  template: `<div>{{ count }}</div>`,
  computed: {
    //- アロー関数
    count: () => store.state.count
  }
}
Vue.component('Counter', Counter)

export default {
  name: 'app',
  data () {
    return {
      privateState: {},
    }
  },
  computed: {
    count () {
      return store.state.count
    }
  },
  methods: {
    increment() {
      return store.commit('increment')
    },
    decrement() {
      return store.commit('decrement')
    }
  }
}
</script>
  • src/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 51
  },
  mutations: {
    increment: (state) => {
      state.count++
    },
    decrement: state => state.count--,
  }
})
export default store
  • es6 の省略記法は、見比べていたら慣れてくるので、使うようにします。
  • storeのstateをコンポーネントのcomputedを使って、表示させているだけです。

ルートインスタンスに store オプションを渡す

  • App.vue

<template lang="pug">
  #app
    Counter
    button(@click="increment") +
    button(@click="decrement") -
</template>

<script>
import Vue from 'vue'
import store from './store.js'

const Counter = {
  name: 'Counter',
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}
Vue.component('Counter', Counter)

export default {
  name: 'app',

  //
  // store option
  //

  store,
  data () {
    return {
      privateState: {},
    }
  },
  computed: {
    count () {
      return this.$store.state.count
    }
  },
  methods: {
    increment() {
      return this.$store.commit('increment')
    },
    decrement() {
      return this.$store.commit('decrement')
    }
  }
}
</script>
  • ルートで storeを指定することで、別ファイルのコンポーネントであろうが、すべて this.$store で storeにアクセスできるみたいです。
  • thisを使っている箇所は、参照先が異なるので、アロー関数から変更しています。

コンポーネントを別ファイルにしてみる。

  • 別ファイルにして、storeをimport にしなくても問題ないことを確認します。
  • 構成
.
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── src
│   ├── App.vue
│ * ├── Counter.vue
│   ├── assets
│   │   └── logo.png
│   ├── main.js
│   └── store.js
└── webpack.config.js
  • src/Counter.vue

<template lang="pug">
  div {{ count }}
</template>

<script>
export default {
  name: 'Counter',
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}

</script>

<style lang="scss" scoped>
</style>

  • App.vue

<template lang="pug">
  #app
    Counter
    button(@click="increment") +
    button(@click="decrement") -
</template>

<script>
import Vue from 'vue'
import store from './store.js'
import Counter from './Counter'

Vue.component('Counter', Counter)

export default {
  name: 'app',
  store,
  data () {
    return {
      privateState: {},
    }
  },
  computed: {
    // count () {
    //   return this.$store.state.count
    // }
  },
  methods: {
    increment() {
      return this.$store.commit('increment')
    },
    decrement() {
      return this.$store.commit('decrement')
    }
  }
}
</script>
  • 表示部分を別ファイルにしましたが、特に問題なく表示されていますね。

mapState ヘルパー

  • Counter.vue

<template lang="pug">
  div
    div {{ count1 }}
    div {{ count2 }}
    div {{ count3 }}
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'Counter',
  data: () => ({
    localCount: 999
  }),
  computed: mapState({
    count1: state => state.count,
    count2: 'count',
    count3 (state) {
      return state.count + this.localCount
    }
  })
}

</script>

<style lang="scss" scoped>
</style>

  • App.vue
<template lang="pug">
  #app
    Counter
    button(@click="increment") +
    button(@click="decrement") -
</template>

<script>
import Vue from 'vue'
import store from './store.js'
import Counter from './Counter'

Vue.component('Counter', Counter)

export default {
  name: 'app',
  store,
  data () {
    return {
      privateState: {},
    }
  },
  computed: {
  },
  methods: {
    increment() {
      return this.$store.commit('increment')
    },
    decrement() {
      return this.$store.commit('decrement')
    }
  }
}
</script>

  • mapStateヘルパーを使うことで、computedでの関数を纒めて、作れるみたいですね。
  • count1 は、アロー省略記法です。
  • count2 は vuexの省略記法みたいです。
  • count3 は、thisの関係で通常の関数です。
  • this.$storeで書くより楽ですね。

配列で渡す

  • Counter.vue

<template lang="pug">
  div
    div {{ count }}
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'Counter',
  data: () => ({
    localCount: 999
  }),
  computed: mapState([
    'count'
  ])
  // computed: mapState({
  //   count1: state => state.count,
  //   count2: 'count',
  //   count3 (state) {
  //     return state.count + this.localCount
  //   }
  // })
}

</script>

<style lang="scss" scoped>
</style>
  • 名前を変えないのであれば配列で渡すとさらに、省略できますね。

オブジェクトスプレッド演算子

  • App.vue

<template lang="pug">
  div
    div {{ count }}
    div {{ localCount }}
    div {{ localComputed }}
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'Counter',
  data: () => ({
    localCount: 999
  }),
  computed: {
    localComputed () {
      return this.localCount + 1
    },
    ...mapState([
      'count'
    ])
  }
}

</script>

<style lang="scss" scoped>
</style>


  • スプレッド演算子は、スマートにローカル側とstore側を連結できます。

  • ステート編は、これで終了です。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1