Search code examples
typescriptvue.jsreactive-programmingvuexvue-composition-api

Using Vuex and the Composition API, is there a way to access reactive properties?


If I design my component like this:

<template>
  <div>
    <button @click="increment">Count is: {{ store.getters.count }}</button>
  </div>
</template>

<script>
import { reactive } from "@vue/composition-api";
import store from "../store";

export default {
  name: "Count",

  setup() {
    const state = reactive({
      store
    });
    const increment = () => {
      store.dispatch.increment();
    };
    return {
      ...state,
      increment
    };
  }
};
</script>

And my store is defined like this:

import Vue from "vue";
import Vuex from "vuex";
import { createDirectStore } from "direct-vuex";

Vue.use(Vuex);

const {
  store,
  rootActionContext,
  moduleActionContext,
  rootGetterContext,
  moduleGetterContext
} = createDirectStore({
  state: {
    count: 0
  },
  getters: {
    count: state => state.count
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit("increment");
    }
  }
});

// Export the direct-store instead of the classic Vuex store.
export default store;

// The following exports will be used to enable types in the
// implementation of actions and getters.
export {
  rootActionContext,
  moduleActionContext,
  rootGetterContext,
  moduleGetterContext
};

// The following lines enable types in the injected store '$store'.
export type AppStore = typeof store;
declare module "vuex" {
  interface Store<S> {
    direct: AppStore;
  }
}

Is there any way I can access the count better than {{ store.getters.count }} in the template? Ideally, I'd like to just access it like {{ count }}, but it seems like only store is reactive. In other words, if I dispatch the increment action, ``{{ count }}` doesn't update, even if I try to define count in various ways. Here's one thing I've tried:

  setup() {
    const state = reactive({
      store,
      count: store.getters.count
    });
    const increment = () => {
      store.dispatch.increment();
    };
    return {
      ...state,
      count: state.count,
      increment
    };
  }

Why isn't {{ count }} reactive in this case?


Solution

  • count: store.getters.count means that you're storing the current value of store.getters.count as the default value of your state count.

    That means it won't be reactive. Notice that count in the store is a function.

    You could try making your state count a computed property instead so it would properly update.

    I haven't tried the Composition API yet, but I hope I could help.