$30 off During Our Annual Pro Sale. View Details »

Vue.js 状態管理の選択肢 - そのVuex本当に必要ですか - / Vue.js State Management Options

ryo
March 17, 2021

Vue.js 状態管理の選択肢 - そのVuex本当に必要ですか - / Vue.js State Management Options

iCARE Dev Meetup #19 2021/03/17

ryo

March 17, 2021
Tweet

More Decks by ryo

Other Decks in Technology

Transcript

  1. Vue.js ঢ়ଶ؅ཧͷબ୒ࢶ
    ʙ ͦͷVuexຊ౰ʹඞཁͰ͔͢? ʙ
    @KawamataRyo
    2021/03/17 iCARE Dev Meetup #19

    View Slide

  2. ࣗݾ঺հ

    View Slide

  3. @KawamataRyo
    LAPRAS גࣜձࣾ
    TypeScript, Vue, Firebase, Ruby
    ݩফ๷࢜🔥🚒

    View Slide

  4. ࠓ೔࿩͢͜ͱ

    View Slide

  5. Vuex + α ͷঢ়ଶ؅ཧख๏ͷ঺հ
    ͦΕͧΕͷ Pros/Cons ͷ·ͱΊ

    View Slide

  6. ͳͥঢ়ଶ؅ཧΛςʔϚʹʁ🤔

    View Slide

  7. Vuex ݏΘΕ͗͢͡Όͳ͍͔..?

    View Slide

  8. Vuex 😭
    🐵
    🐶
    😼
    🦁
    🐯
    🐻
    🐹
    🦊

    View Slide

  9. ͦΕͬͯຊ౰ʹVuexͷ໰୊ͳͷͩΖ͏͔ʁ

    View Slide

  10. VuexΛ
    ద੾ʹར༻Ͱ͖ͯͳ͍
    or
    ద੾ͳ৔ॴͰར༻Ͱ͖ͯͳ͍
    ৔߹΋͋Δͷ͔΋ʁ

    View Slide

  11. VuexΛ
    ద੾ʹར༻Ͱ͖ͯͳ͍
    or
    ద੾ͳ৔ॴͰར༻Ͱ͖ͯͳ͍
    ৔߹΋͋Δͷ͔΋ʁ

    View Slide

  12. Vuex Ҏ֎ͷঢ়ଶ؅ཧΛ஌Δ͜ͱͰ
    ঢ়ଶ؅ཧͷબ୒ࢶΛ޿͍͛ͨ

    View Slide

  13. ঢ়ଶ؅ཧͷجຊ

    View Slide

  14. ͦ΋ͦ΋ঢ়ଶ؅ཧͱ͸ʁ

    View Slide

  15. ΞϓϦ͕࣋ͭ
    ঢ়ଶʢσʔλʣΛద੾ʹѻ
    ͍ΞϓϦΛਖ਼͘͠ಈ࡞ͤ͞
    Δํ๏

    View Slide

  16. ͳͥঢ়ଶ؅ཧϥΠϒϥϦ͕ඞཁʁ

    View Slide

  17. ίϯϙʔωϯτ͕૿͑Δͱ
    Props/EmitͰͷঢ়ଶͷ఻೻
    ͕ෳࡶʹ..

    View Slide

  18. ೝূ৘ใͳͲෳ਺ίϯϙʔωϯτ
    Ͱڞ௨ͷσʔλɾϩδοΫΛ࣋ͪ
    ͍ͨ..

    View Slide

  19. ෳ਺ͷίϯϙʔωϯτ͔Β
    ΞΫηεͰ͖Δάϩʔόϧͳ
    ঢ়ଶ͕ඞཁ
    => ঢ়ଶ؅ཧϥΠϒϥϦ

    View Slide

  20. ঢ়ଶ؅ཧͷબ୒ࢶ

    View Slide

  21. Vuex Pinia Vue Apollo
    Composition API
    Store

    View Slide

  22. Vuex Pinia Vue Apollo
    Composition API
    Store

    View Slide

  23. - Vueެࣜͷঢ়ଶ؅ཧϥΠϒϥϦ
    - FluxϥΠΫ
    - ୯Ұ Store
    vuejs / vuex (v4)

    View Slide

  24. Store import { InjectionKey } from "vue";
    import { createStore, Store } from "vuex";
    export interface State {
    count: number;
    }
    export const key: InjectionKey> = Symbol();
    export const store = createStore({
    state: {
    count: 0
    },
    mutations: {
    increment(state) { state.count++; },
    decrement(state) { state.count--; }
    },
    actions: {
    increment({ commit }) { commit("increment"); },
    decrement({ commit }) { commit("decrement"); }
    }
    });

    View Slide

  25. Store import { InjectionKey } from "vue";
    import { createStore, Store } from "vuex";
    export interface State {
    count: number;
    }
    export const key: InjectionKey> = Symbol();
    export const store = createStore({
    state: {
    count: 0
    },
    mutations: {
    increment(state) { state.count++; },
    decrement(state) { state.count--; }
    },
    actions: {
    increment({ commit }) { commit("increment"); },
    decrement({ commit }) { commit("decrement"); }
    }
    });
    createStoreͰstoreΛఆٛ
    mutations, actionsͰstateΛૢ࡞

    View Slide

  26. Store import { InjectionKey } from "vue";
    import { createStore, Store } from "vuex";
    export interface State {
    count: number;
    }
    export const key: InjectionKey> = Symbol();
    export const store = createStore({
    state: {
    count: 0
    },
    mutations: {
    increment(state) { state.count++; },
    decrement(state) { state.count--; }
    },
    actions: {
    increment({ commit }) { commit("increment"); },
    decrement({ commit }) { commit("decrement"); }
    }
    });
    provide/inject༻ͷΩʔ
    ʢTSͷܕఆٛऔಘͷͨΊʣ

    View Slide

  27. Install
    import { createApp } from "vue";
    import App from "./App.vue";
    import { store, key } from "./stores/vuex/store";
    const app = createApp(App);
    // vuex
    app.use(store, key);
    app.mount("#app");

    View Slide

  28. Install
    import { createApp } from "vue";
    import App from "./App.vue";
    import { store, key } from "./stores/vuex/store";
    const app = createApp(App);
    // vuex
    app.use(store, key);
    app.mount("#app");
    storeͱkeyΛొ࿥

    View Slide

  29. Components
    (read)
    <br/>import { defineComponent, computed } from "vue";<br/>import { useStore } from "vuex";<br/>import { key } from "@/stores/vuex/store";<br/>export default defineComponent({<br/>name: "Counter",<br/>setup() {<br/>const store = useStore(key);<br/>const count = computed(() => store.state.count);<br/>return {<br/>count<br/>};<br/>}<br/>});<br/>

    View Slide

  30. Components
    (read)
    <br/>import { defineComponent, computed } from "vue";<br/>import { useStore } from "vuex";<br/>import { key } from "@/stores/vuex/store";<br/>export default defineComponent({<br/>name: "Counter",<br/>setup() {<br/>const store = useStore(key);<br/>const count = computed(() => store.state.count);<br/>return {<br/>count<br/>};<br/>}<br/>});<br/>
    keyΛ౉ͯ͠storeΛऔಘ
    count͸numberܕͱͯ͠ਪ࿦

    View Slide

  31. <br/>import { defineComponent } from "vue";<br/>import { useStore } from "vuex";<br/>import { key } from "@/stores/vuex/store";<br/>export default defineComponent({<br/>name: "IncrementButton",<br/>setup() {<br/>const store = useStore(key);<br/>const increment = () => store.dispatch("increment");<br/>return {<br/>increment<br/>};<br/>}<br/>});<br/>
    Components
    (write)

    View Slide

  32. <br/>import { defineComponent } from "vue";<br/>import { useStore } from "vuex";<br/>import { key } from "@/stores/vuex/store";<br/>export default defineComponent({<br/>name: "IncrementButton",<br/>setup() {<br/>const store = useStore(key);<br/>const increment = () => store.dispatch("increment");<br/>return {<br/>increment<br/>};<br/>}<br/>});<br/>
    Components
    (write)
    dispatchͰactionsΛ࣮ޮ
    ܕิ׬͸ޮ͔ͳ͍

    View Slide

  33. - ެࣜϥΠϒϥϦ
    - υΩϡϝϯτɾࢀߟ৘ใͷ๛෋͞
    - DevToolsͷ࿈ܞ
    - ߏ଄Խ͞ΕͨύλʔϯʢFluxʣ
    - SSRରԠ
    Pros 😁

    View Slide

  34. - TypeScriptͷܕ෇͚΁ͷରԠ
    - هड़ྔͷଟ͞
    Cons 😵

    View Slide

  35. Vuex Pinia Vue Apollo
    Composition API
    Store

    View Slide

  36. - Composition APIઐ༻
    - ܰྔʢ1kbະຬʣ
    - ෳ਺Store
    posva / pinia

    View Slide

  37. Store
    import { defineStore } from "pinia";
    export const useCounterStore = defineStore({
    id: "counter",
    state: () => ({
    count: 0
    }),
    actions: {
    increment() {
    this.count++;
    },
    decrement() {
    this.count--;
    }
    }
    });

    View Slide

  38. Store
    import { defineStore } from "pinia";
    export const useCounterStore = defineStore({
    id: "counter",
    state: () => ({
    count: 0
    }),
    actions: {
    increment() {
    this.count++;
    },
    decrement() {
    this.count--;
    }
    }
    });
    mutations͸ͳ͘actionsͰ
    stateΛૢ࡞
    storeݻ༗ͷ
    idΛ࣋ͭ

    View Slide

  39. Install
    import { createApp } from "vue";
    import App from "./App.vue";
    import { createPinia } from "pinia";
    const app = createApp(App);
    // pinia
    app.use(createPinia());
    app.mount("#app");

    View Slide

  40. Install
    import { createApp } from "vue";
    import App from "./App.vue";
    import { createPinia } from "pinia";
    const app = createApp(App);
    // pinia
    app.use(createPinia());
    app.mount("#app");
    piniaͷrootετΞΛొ࿥

    View Slide

  41. Components
    (read)
    <br/>import { defineComponent, computed } from "vue";<br/>import { useCounterStore } from "@/stores/pinia/store";<br/>export default defineComponent({<br/>name: "Counter",<br/>setup() {<br/>const store = useCounterStore();<br/>const count = computed(() => store.count);<br/>return {<br/>count<br/>};<br/>}<br/>});<br/>

    View Slide

  42. Components
    (read)
    <br/>import { defineComponent, computed } from "vue";<br/>import { useCounterStore } from "@/stores/pinia/store";<br/>export default defineComponent({<br/>name: "Counter",<br/>setup() {<br/>const store = useCounterStore();<br/>const count = computed(() => store.count);<br/>return {<br/>count<br/>};<br/>}<br/>});<br/>
    numberܕͱͯ͠ਪ࿦
    exportͨ͠StoreΛར༻

    View Slide

  43. <br/>import { defineComponent } from "vue";<br/>import { useCounterStore } from "@/stores/pinia/store";<br/>export default defineComponent({<br/>name: "IncrementButton",<br/>setup() {<br/>const store = useCounterStore();<br/>const increment = () => store.increment();<br/>return {<br/>increment<br/>};<br/>}<br/>});<br/>
    Components
    (write)

    View Slide

  44. <br/>import { defineComponent } from "vue";<br/>import { useCounterStore } from "@/stores/pinia/store";<br/>export default defineComponent({<br/>name: "IncrementButton",<br/>setup() {<br/>const store = useCounterStore();<br/>const increment = () => store.increment();<br/>return {<br/>increment<br/>};<br/>}<br/>});<br/>
    Components
    (write)
    actionsͷ
    ܕิ׬͕ޮ͘

    View Slide

  45. Demo
    https://vue-state-management-samples.vercel.app/pinia

    View Slide

  46. - TypeScript ׬શରԠ
    - DevToolsͷ࿈ܞʢݱঢ়ࢀরͷΈʣ
    - γϯϓϧͳίʔυ
    - SSRରԠ
    Pros 😁

    View Slide

  47. - ৘ใྔͷগͳ͞
    - ਖ਼ࣜϦϦʔεલ
    - ։ൃͷܧଓੑ
    Cons 😵

    View Slide

  48. Vuex Pinia Composition API
    Store
    vue-apollo

    View Slide

  49. - Composition APIͰ
    ಠ࣮ࣗ૷ͨ͠Store
    Composition Store

    View Slide

  50. Store import { reactive, provide, InjectionKey, toRefs } from "vue";
    import { DeepReadonly } from "utility-types";
    export const createStore = () => {
    const state = reactive({
    count: 0
    });
    const actions = {
    increment: () => { state.count++; },
    decrement: () => { state.count--; }
    };
    return { state: toRefs(state), actions };
    };
    type Store = ReturnType>;
    export const STORE_KEY: InjectionKey = Symbol("Store");
    export const useStore = () => {
    return inject(STORE_KEY) as Store;
    };

    View Slide

  51. Store import { reactive, provide, InjectionKey, toRefs } from "vue";
    import { DeepReadonly } from "utility-types";
    export const createStore = () => {
    const state = reactive({
    count: 0
    });
    const actions = {
    increment: () => { state.count++; },
    decrement: () => { state.count--; }
    };
    return { state: toRefs(state), actions };
    };
    type Store = ReturnType>;
    export const STORE_KEY: InjectionKey = Symbol("Store");
    export const useStore = () => {
    return inject(STORE_KEY) as Store;
    };
    reactiveͰstateΛఆٛ
    ؔ਺ͰstateΛૢ࡞

    View Slide

  52. Store import { reactive, provide, InjectionKey, toRefs } from "vue";
    import { DeepReadonly } from "utility-types";
    export const createStore = () => {
    const state = reactive({
    count: 0
    });
    const actions = {
    increment: () => { state.count++; },
    decrement: () => { state.count--; }
    };
    return { state: toRefs(state), actions };
    };
    type Store = DeepReadonly>;
    export const STORE_KEY: InjectionKey = Symbol("Store");
    export const useStore = () => {
    return inject(STORE_KEY) as Store;
    };
    provide/inject༻ͷ
    ؔ਺ɾΩʔ
    DeepReadolyͰ
    stateͷ௚઀ॻ͖׵͑Λېࢭ্ͨ͠Ͱ
    InjectionKeyͷܕʹઃఆ

    View Slide

  53. Install
    import { createApp, provide } from "vue";
    import App from "./App.vue";
    import { STORE_KEY, createStore } from "@/stores/originalStore/store";
    const app = createApp(App);
    // Original Store
    app.provide(STORE_KEY, createStore());
    app.mount("#app");

    View Slide

  54. import { createApp, provide } from "vue";
    import App from "./App.vue";
    import { STORE_KEY, createStore } from "@/stores/originalStore/store";
    const app = createApp(App);
    // Original Store
    app.provide(STORE_KEY, createStore());
    app.mount("#app");
    Install
    Storeͷ࡞੒ͱprovideͰͷొ࿥

    View Slide

  55. Components
    (read)
    <br/>import { defineComponent, computed } from "vue";<br/>import { useStore } from "@/stores/originalStore/store";<br/>export default defineComponent({<br/>name: "Counter",<br/>setup() {<br/>const { state } = useStore();<br/>const count = computed(() => state.count.value);<br/>return {<br/>count<br/>};<br/>}<br/>});<br/>

    View Slide

  56. Components
    (read)
    <br/>import { defineComponent, computed } from "vue";<br/>import { useStore } from "@/stores/originalStore/store";<br/>export default defineComponent({<br/>name: "Counter",<br/>setup() {<br/>const { state } = useStore();<br/>const count = computed(() => state.count.value);<br/>return {<br/>count<br/>};<br/>}<br/>});<br/>
    injectͰͷstoreͷऔಘ
    numberܕͱͯ͠ਪ࿦

    View Slide

  57. <br/>import { defineComponent } from "vue";<br/>import { useStore } from "@/stores/originalStore/store";<br/>export default defineComponent({<br/>name: "IncrementButton",<br/>setup() {<br/>const { actions } = useStore();<br/>const increment = () => actions.increment();<br/>return {<br/>increment<br/>};<br/>}<br/>});<br/>
    Components
    (write)

    View Slide

  58. <br/>import { defineComponent } from "vue";<br/>import { useStore } from "@/stores/originalStore/store";<br/>export default defineComponent({<br/>name: "IncrementButton",<br/>setup() {<br/>const { actions } = useStore();<br/>const increment = () => actions.increment();<br/>return {<br/>increment<br/>};<br/>}<br/>});<br/>
    Components
    (write)
    ୯७ͳؔ਺ݺͼग़͠
    ͳͷͰܕิ׬͕ޮ͘

    View Slide

  59. Demo
    https://vue-state-management-samples.vercel.app/original-store

    View Slide

  60. - TypeScript ׬શରԠ
    - γϯϓϧͳίʔυ
    - ґଘͳ͠
    Pros 😁

    View Slide

  61. - ΦϨΦϨStoreͷ໰୊
    - DevTools ࿈ܞ
    - vue-routerɺSSRͷରԠ
    Cons 😵

    View Slide

  62. Vuex Pinia Vue Apollo
    Composition API
    Store

    View Slide

  63. - Apollo CacheΛStoreʹ
    - Query / MutationͰͷૢ࡞
    vuejs / vue-apollo

    View Slide

  64. GraphQLͷεΩʔϚఆٛ
    import gql from "graphql-tag";
    export const typeDefs = gql`
    extend type Store {
    count: Int!
    }
    extend type Mutation {
    increment: Int
    decrement: Int
    }
    extend type Query {
    CountQuery: Store
    }
    `;

    View Slide

  65. Queryͷఆٛ
    import gql from "graphql-tag";
    export const COUNT_QUERY = gql`
    query CountQuery {
    store @client {
    count
    }
    }
    `;

    View Slide

  66. Queryͷఆٛ
    import gql from "graphql-tag";
    export const COUNT_QUERY = gql`
    query CountQuery {
    store @client {
    count
    }
    }
    `;
    @clientͱσΟϨΫςΟϒΛ͚ͭΔ͜ͱͰɺ
    αʔόʔʹ໰͍߹ΘͤͣɺΩϟογϡͰॲཧ͢Δ

    View Slide

  67. import gql from "graphql-tag";
    export const INCREMENT_MUTATION = gql`
    mutation incrementMutation {
    increment @client
    }
    `;
    export const DECREMENT_MUTATION = gql`
    mutation decrementMutation {
    decrement @client
    }
    `;
    Mutationͷఆٛ

    View Slide

  68. Resolvers
    import { InMemoryCache } from "apollo-cache-inmemory";
    import { COUNT_QUERY } from "@/stores/apolloClient/queries";
    export const resolvers = {
    Mutation: {
    increment: ( _: unknown, _arg: unknown, { cache }: { cache: InMemoryCache }) => {
    const data = cache.readQuery({ query: COUNT_QUERY });
    data.store.count++;
    cache.writeQuery({ query: COUNT_QUERY, data });
    return data.store.count;
    },
    decrement: ( _: unknown, _arg: unknown, { cache }: { cache: InMemoryCache }) => {
    const data = cache.readQuery({ query: COUNT_QUERY });
    data.store.count--;
    cache.writeQuery({ query: COUNT_QUERY, data });
    return data.store.count;
    }
    }
    };

    View Slide

  69. Resolvers
    import { InMemoryCache } from "apollo-cache-inmemory";
    import { COUNT_QUERY } from "@/stores/apolloClient/queries";
    export const resolvers = {
    Mutation: {
    increment: ( _: unknown, _arg: unknown, { cache }: { cache: InMemoryCache }) => {
    const data = cache.readQuery({ query: COUNT_QUERY });
    data.store.count++;
    cache.writeQuery({ query: COUNT_QUERY, data });
    return data.store.count;
    },
    decrement: ( _: unknown, _arg: unknown, { cache }: { cache: InMemoryCache }) => {
    const data = cache.readQuery({ query: COUNT_QUERY });
    data.store.count--;
    cache.writeQuery({ query: COUNT_QUERY, data });
    return data.store.count;
    }
    }
    };
    queryͷcacheΛॻ͖׵͍͑ͯΔ

    View Slide

  70. Apollo Clientͷ࡞੒
    import ApolloClient from "apollo-boost";
    import { typeDefs } from "@/stores/apolloClient/typeDefs";
    import { InMemoryCache } from "apollo-cache-inmemory";
    import { resolvers } from "@/stores/apolloClient/resolvers";
    const cache = new InMemoryCache();
    export const apolloClient = new ApolloClient({ cache, typeDefs, resolvers });
    // storeͷॳظԽ
    cache.writeData({
    data: {
    store: {
    __typename: "Store",
    count: 0
    }
    }
    });

    View Slide

  71. Apollo Clientͷ࡞੒
    import ApolloClient from "apollo-boost";
    import { typeDefs } from "@/stores/apolloClient/typeDefs";
    import { InMemoryCache } from "apollo-cache-inmemory";
    import { resolvers } from "@/stores/apolloClient/resolvers";
    const cache = new InMemoryCache();
    export const apolloClient = new ApolloClient({ cache, typeDefs, resolvers });
    // storeͷॳظԽ
    cache.writeData({
    data: {
    store: {
    __typename: "Store",
    count: 0
    }
    }
    });
    cacheͷॳظԽॲཧ

    View Slide

  72. Install
    import { createApp } from "vue";
    import App from "./App.vue";
    import { DefaultApolloClient } from "@vue/apollo-composable";
    import { apolloClient } from "@/stores/apolloClient/apolloClient";
    const app = createApp(App);
    // vue-apollo
    app.provide(DefaultApolloClient, apolloClient);
    app.mount("#app");

    View Slide

  73. Install
    import { createApp } from "vue";
    import App from "./App.vue";
    import { DefaultApolloClient } from "@vue/apollo-composable";
    import { apolloClient } from "@/stores/apolloClient/apolloClient";
    const app = createApp(App);
    // vue-apollo
    app.provide(DefaultApolloClient, apolloClient);
    app.mount("#app");
    Apollo ClientΛprovide

    View Slide

  74. Components
    (read)
    <br/>import { defineComponent } from "vue";<br/>import { useQuery, useResult } from "@vue/apollo-composable";<br/>import { COUNT_QUERY } from "@/stores/apolloClient/queries";<br/>export default defineComponent({<br/>name: "Counter",<br/>setup() {<br/>const { result } = useQuery(COUNT_QUERY);<br/>const count = useResult(result, 0, data => data.store.count);<br/>return {<br/>count<br/>};<br/>}<br/>});<br/>

    View Slide

  75. Components
    (read)
    <br/>import { defineComponent } from "vue";<br/>import { useQuery, useResult } from "@vue/apollo-composable";<br/>import { COUNT_QUERY } from "@/stores/apolloClient/queries";<br/>export default defineComponent({<br/>name: "Counter",<br/>setup() {<br/>const { result } = useQuery(COUNT_QUERY);<br/>const count = useResult(result, 0, data => data.store.count);<br/>return {<br/>count<br/>};<br/>}<br/>});<br/>
    GraphQL QueryͰऔಘ

    View Slide

  76. Components
    (write)
    <br/>import { defineComponent } from "vue";<br/>import { useMutation } from "@vue/apollo-composable";<br/>import { INCREMENT_MUTATION } from "@/stores/apolloClient/mutations";<br/>export default defineComponent({<br/>name: "IncrementButton",<br/>setup() {<br/>const { mutate: increment } = useMutation(INCREMENT_MUTATION);<br/>return {<br/>increment<br/>};<br/>}<br/>});<br/>

    View Slide

  77. <br/>import { defineComponent } from "vue";<br/>import { useMutation } from "@vue/apollo-composable";<br/>import { INCREMENT_MUTATION } from "@/stores/apolloClient/mutations";<br/>export default defineComponent({<br/>name: "IncrementButton",<br/>setup() {<br/>const { mutate: increment } = useMutation(INCREMENT_MUTATION);<br/>return {<br/>increment<br/>};<br/>}<br/>});<br/>
    Components
    (write)
    MutationͰॻ͖׵͑

    View Slide

  78. Demo
    https://vue-state-management-samples.vercel.app/vue-apollo

    View Slide

  79. - StoreΛ࣋ͨͳ͍
    - DevToolsʢApolloʣରԠ
    Pros 😁

    View Slide

  80. - Vue ApolloɺGraphQL΁ͷґଘ
    - ঢ়ଶͷ೺Ѳ͕ͮ͠Β͍
    - ։ൃͷܧଓੑ
    - ίʔυྔͷ૿Ճ
    Cons 😵

    View Slide

  81. ·ͱΊ

    View Slide

  82. 7VFY 1JOJB
    $PNQPTJUJPO"1*
    4UPSF
    7VF"QPMMP
    4UPSFͷ਺ ୯Ұ ෳ਺ ෳ਺ ʢΩϟγϡʣ
    %FW5PPMTରԠ ˓ ˚ º ˚ʢ"QPMMPʣ
    5ZQF4DSJQUରԠ ˚ ˓ ˓ ˚
    ଟػೳੑ
    ʢ443FUDʣ
    ˓ ˚ º º
    ίʔυͷهड़ྔ ˚ ˓ ˓ º

    View Slide

  83. ࠓͷVueͷঢ়ଶ؅ཧ͸Vuex͚ͩͰ͸ͳ͍ɻ
    ΞϓϦέʔγϣϯͷن໛΍ॏࢹ͢Δ఺ʹ
    ߹Θͤͯద੾ͳঢ়ଶ؅ཧख๏Λબ୒
    ͢Δ͜ͱ͕େ੾

    View Slide

  84. ࢀߟ
    • you might not need Vuex: https://speakerdeck.com/ntepluhina/you-might-not-need-vuex
    • Do you really need Vuex: https://blog.logrocket.com/do-you-really-need-vuex
    • ΈΜͳͷVue.js: https://gihyo.jp/book/2021/978-4-297-11902-7
    • Pinia vs Vuex: https://www.youtube.com/watch?v=ht_1NR7OFWc
    • intro to vuex: https://www.vuemastery.com/courses/mastering-vuex/intro-to-vuex/
    • Pinia doc: https://pinia.esm.dev/
    • Vuex4 doc: https://next.vuex.vuejs.org/

    View Slide

  85. ͓·͚
    Vuex 5 RFCͷ·ͱΊ
    2021/03/14 ࣌఺
    https://github.com/kiaking/rfcs/blob/vuex-5/active-rfcs/0000-vuex-5.md

    View Slide

  86. Storeͷఆٛ Storeͷར༻
    Mutationsͷഇࢭ
    dispatchΛհͣ͞
    actionsΛ௚઀ݺ΂Δ
    ᶃ FluxϥΠΫύλʔϯΛഇࢭ

    View Slide

  87. Optional Store Composition Store
    ΄΅Composition APIͦͷ··
    ᶄ 2छྨͷStoreఆٛํ๏

    View Slide

  88. Store 1 Store 2
    ωετ͞ΕͨStoreʢModuleʣ
    Λഇࢭͯ͠ɺComposition Ͱ
    Storeͷ૬ޓར༻Λߦ͏
    ᶅωετ͞ΕͨStoreΛഇࢭ

    View Slide

  89. Store Component
    Optional Storeͷ৔߹͸
    ܕΞϊςʔγϣϯΛ͚ͭΔ
    ʢComposition StoreͰ͸ෆཁʣ
    ࢖༻࣌͸
    ܕิ׬͕׬શʹޮ͘
    ᶆ ׬શͳTypeScriptαϙʔτ

    View Slide