championswimmer / vuex-persist

A Vuex plugin to persist the store. (Fully Typescript enabled)
http://championswimmer.in/vuex-persist
MIT License
1.67k stars 116 forks source link

vuex-persist does not store in localStorage: vue3 migration #259

Open Wrishi opened 2 years ago

Wrishi commented 2 years ago

I am trying to migrate a project from vue 2 to vue 3. The project uses vuex and vuex-persist to store the state of the application in localStorage.

In vue2, the code was as follows:

import Vuex from 'vuex';
import Vue from 'vue';
import Vapi from 'vuex-rest-api';
import VuexPersistence from 'vuex-persist';

Vue.use(Vuex);

const vuexLocal = new VuexPersistence({
  storage: window.localStorage,
});

const dashboardAPI = new Vapi({
  baseURL,
  axios,
  state: {
    posts: [],
  },
})
.post({...})
.post({...})
.getStore();

const dashboardStore = {
  modules: {
    dashboard,
  },
  plugins: [vuexLocal.plugin],
  ...dashboardAPI,
};

export default new Vuex.Store(dashboardStore);
import router from '@/router';
import store from '@/store';
import App from '@/App';

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>',
});

Vue.config.devtools = true;

In vue3, the code was as follows:

import Vuex from 'vuex';
import Vapi from 'vuex-rest-api';
import VuexPersistence from 'vuex-persist';

const dashboardAPI = new Vapi({
  baseURL,
  axios,
  state: {
    posts: [],
  },
})
.post({...})
.post({...})
.getStore();

const vuexLocal = new VuexPersistence({
  storage: window.localStorage,
});

const dashboardStore = {
  modules: {
    dashboard,
  },
  plugins: [vuexLocal.plugin],
  ...dashboardAPI,
};

export default createStore(dashboardStore);
import {createApp} from 'vue'
import App from '@/App';
import router from '@/router';
import store from '@/store';

const app = createApp(App)

app.use(router);
app.use(store);

app.config.devtools = true;
app.config.globalProperties.emitter = emitter;
app.config.globalProperties.$filters = filters

app.mount('#app');

In Vue2 version of the app, the intended data gets stored in localStorage, but in the Vue3 version , it does not. The variables at every stage holds the intended value. The localStorage is added in vue2 code as soon as app is created with new Vue({...}), whereas in case of vue3, const app = createApp(App) and app.use(store); does not do the same.

Am I doing something wrong?

nsano-rururu commented 1 year ago

https://github.com/championswimmer/vuex-persist/issues/224

nsano-rururu commented 1 year ago

Vue2

vue 2.6.14 vuex 3.6.4 vuex-persist 3.1.3

my-appvue\src\App.vue

<template>
  <div id="app">
    <CountValue />
  </div>
</template>

<script>
import CountValue from './components/CountValue.vue';

export default {
  name: 'app',
  components: {
    CountValue,
  },
};
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

my-appvue\src\main.js

import Vue from 'vue';
import App from './App.vue';
import store from './store';

Vue.config.productionTip = false;

new Vue({
  store,
  render: (h) => h(App),
}).$mount('#app');

my-appvue\src\store.js

import Vue from 'vue';
import Vuex from 'vuex';
import counter from './store/modules/counter';
import VuexPersist from 'vuex-persist';

Vue.use(Vuex);

const vuexLocalStorage = new VuexPersist({
  key: 'sano-vuex', // The key to store the state on in the storage provider.
  storage: window.localStorage, // or window.sessionStorage or localForage
  // Function that passes the state and returns the state with only the objects you want to store.
  // reducer: state => state,
  // Function that passes a mutation and lets you decide if it should update the state in localStorage.
  //
});

export default new Vuex.Store({
  strict: process.env.NODE_ENV !== 'production',
  modules: {
    counter,
  },
  state: {},
  mutations: {},
  actions: {},
  plugins: [vuexLocalStorage.plugin],
});

my-appvue\src\store\modules\counter.js

const state = {
  step: 1,
  count: 0,
};

const getters = {
  step: (state) => state.step,
  count: (state) => state.count,
};

const actions = {
  increment({ commit }) {
    commit('increment');
  },
};

const mutations = {
  increment(state) {
    state.count += state.step;
  },
};

export default {
  state,
  getters,
  actions,
  mutations,
};

my-appvue\src\components\CountValue.vue

<template>
  <div>
    <button @click="increment">increment {{ step }}</button>
    <span>total {{ count }}</span>
  </div>
</template>

<script>
export default {
  name: 'CountValue',
  computed: {
    step() {
      return this.$store.getters.step;
    },
    count() {
      return this.$store.getters.count;
    },
  },
  methods: {
    increment() {
      this.$store.dispatch('increment');
    },
  },
};
</script>

<style scoped></style>

Vue3

vue 3.1.1 vuex 4.0.1 vuex-persist 3.1.3

my-appvue\src\App.vue

<template>
  <div id="app">
    <CountValue />
  </div>
</template>

<script>
import CountValue from './components/CountValue.vue';

export default {
  name: 'app',
  components: {
    CountValue,
  },
};
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

my-appvue\src\main.js

import { createApp } from 'vue';
import App from './App.vue';
import store from './store';

const app = createApp(App).use(store);
app.mount('#app');

my-appvue\src\store.js

import { createStore } from 'vuex';
import VuexPersist from 'vuex-persist';
import counter from './store/modules/counter';

const vuexLocalStorage = new VuexPersist({
  key: 'sano-vuex', // The key to store the state on in the storage provider.
  storage: window.localStorage, // or window.sessionStorage or localForage
  // Function that passes the state and returns the state with only the objects you want to store.
  // reducer: state => state,
  // Function that passes a mutation and lets you decide if it should update the state in localStorage.
  //
});

const vueStore = createStore({
  strict: process.env.NODE_ENV !== 'production',
  modules: {
    counter,
  },
  state: {},
  mutations: {},
  actions: {},
  plugins: [vuexLocalStorage.plugin],
});
export default vueStore;

my-appvue\src\store\modules\counter.js

const state = {
  step: 1,
  count: 0,
};

const getters = {
  step: (state) => state.step,
  count: (state) => state.count,
};

const actions = {
  increment({ commit }) {
    commit('increment');
  },
};

const mutations = {
  increment(state) {
    state.count += state.step;
  },
};

export default {
  state,
  getters,
  actions,
  mutations,
};

my-appvue\src\components\CountValue.vue

<template>
  <div>
    <button @click="increment">increment {{ step }}</button>
    <span>total {{ count }}</span>
  </div>
</template>

<script>
export default {
  name: 'CountValue',
  computed: {
    step() {
      return this.$store.getters.step;
    },
    count() {
      return this.$store.getters.count;
    },
  },
  methods: {
    increment() {
      this.$store.dispatch('increment');
    },
  },
};
</script>