💬
Vue2 + pinia
vue2でもcomposition apiを入れていればpiniaを使えるということで、
早速実装してみました。
追記)composition apiを入れてなくても使えるようになっているみたいです。
公式のしたがってインストールから実装までやっていきたいと思います。
(typescriptにも対応していますが、この記事ではjavascriptを例に書いています)
Step 1 インストール
npm install pinia
main.js(ts)に追記します。
main.js
import Vue from "vue"
import App from "./App.vue"
import router from "./router"
import VueCompositionApi from "@vue/composition-api"
import vuetify from "./plugins/vuetify"
import { createPinia, PiniaVuePlugin } from "pinia" // 追加
Vue.use(VueCompositionApi)
Vue.use(PiniaVuePlugin) //追加
const pinia = createPinia()
Vue.config.productionTip = false
new Vue({
router,
vuetify,
pinia, //追加
render: function (h) {
return h(App)
},
}).$mount("#app")
Step 2 store定義
defineStoreでstoreを定義します。
第一引数は、storeのIDになるので、一意である必要があります。
/store/counterStore.js
import { defineStore } from "pinia"
export const useCounter = defineStore("counter", {
//vueで言うdata()に値する:reactiveなデータ
state: () => ({
count: 0,
}),
//vueで言うcomputed()に値する
getters: {
doubledCount() {
return this.count * 2
},
},
//vueで言うmethods()に値する
actions: {
increment() {
this.count++
},
},
})
基本構成は、state, getters, actionsの3つであり、
これはvueでいうdata(), computed(), methodsに値します。
命名規則について特に指定はないようですが、
gettersはcomputed()と同じ位置づけということなので、名詞がよさそうです。
step 3 storeを使う(基本の書き方)
storeファイルをimportして、この一行を書くだけで使えるようになります。
const store = useCounter()
sample.vue
<template>
<div>
<p>currentCount: {{ store.count }}</p>
<v-btn @click="upCount">カウントアップ</v-btn>
</div>
</template>
<script>
import { defineComponent } from "@vue/composition-api"
import { useCounter } from "@/store/counterStore.js"
export default defineComponent({
setup() {
const store = useCounter()
//store.countでstateのプロパティ(count)にアクセスできる
console.log("currentCount", store.count)
//store.でdoubledCountのgetters(doubledCount)にアクセスできる
console.log("doubledCount", store.doubledCount)
const upCount = () => {
//store.アクション名でstoreのアクションを使える
store.increment()
}
return { store, upCount }
},
})
</script>
注意点としては、分割代入↓を使うとreactive性が失われます。
const store = useCounter()
const {count} = store
reactive性を維持するためには、別の方法を使う必要があります。
sample.vue
<script>
import { storeToRefs } from 'pinia'
import { useCounter } from "@/store/counterStore.js"
const store = useCounter()
const { count, doubledCount } = storeToRefs(store)
</script>
Step 4 storeを使う(色々)
stateの値を変更する
sample.vue
<script>
import { defineComponent } from "@vue/composition-api"
import { useCounter } from "@/store/counterStore.js"
export default defineComponent({
setup() {
const store = useCounter()
store.count = 3 //直接変更できる
return { store }
},
})
</script>
その他
global state検証
あるコンポーネントで変更した値が、ほかのコンポーネントでも変更されるか?
Counter1.vueとCounter2.vueにそれぞれcounterStoreを入れて試したところ、
しっかり、反映されていることが確認出来ました!
Discussion