Vue 3 cdn example with vuex 4, but how do I access the store inside main.js?

523 Views Asked by At

My app structure:

> public 
>   scripts
>     - cdn
>       - vue.js
>       - vuex.js
>     main.js
>     store.js
>     index.html

Inside the head tag I have:

<script src="./scripts/cdn/vue.js"></script>
<script src="./scripts/cdn/vuex.js"></script>
<script src="./scripts/main.js" type="module"></script>

And in the body I have-

<div id="app"> <div v-for="item in items" >{{item.text}}</div> </div>

store.js

console.log('test in store.js', store.state)
const store = new Vuex.createStore({
  state: {
    items: [{
      text: 'ahhh STORE 1'
    }, {
      text: 'ahhh STORE 2'
    }],
  },
  mutations: {

  },
  actions: {
    test({
      state
    }) {
      console.log(state.items)
    }
  },
  modules: {

  }
})

main.js

import * as store from "./store.js";
const {
  onMounted,
  onUpdated,
  onUnmounted,
  ref,
  reactive,
  getCurrentInstance
} = Vue; //here define only what you need
//Define Vue app
const App = {
  state: store,
  // store, //using either store or state: store does not work

  data() {
    return {};
  },
  methods: {},
  setup(props, context) {
    onMounted(() => {
      console.info("App mounted!");
      console.log('mounted state', store.state)
    });
    onUpdated(() => {
      console.info("App updated!");
    });
    onUnmounted(() => {
      console.info("App unmounted!");
    });
  }
};
// Create new Vue app
const app = Vue.createApp(App);
app.use(store)
app.mount("#app");

So when the app runs, in the console it shows

test in store.js Proxy { <target>: {…}, <handler>: {…} }

But in onMounted it returns store.state as undefined. It can work by using createStore inside main.js but I would like to keep this separated.

What am I missing and how do I make the store accessible in the main?

2

There are 2 best solutions below

0
Hasibul Alam Rahi On BEST ANSWER

I also faced the similar problems while integrating Vuex 4 with Vue CDN Look at my folder structure

>Components
-HelloWorld.js
>store
-index.js
app.js
index.html

in the index.html file include the vuex 4 CDN link then in for the index.js file inside store folder include the store like this

const  store = new Vuex.Store ({
state: {
  //states
},
mutations: {
  //mutations
},
actions: {
  //actions
},
getters: {
  //getters
},

});

export default store` Inside the app.js root folder include the store as

import store from './Store/index.js'
app.use(store);

Access the store from the component level without importing like the following

this.$store.//store function
9
Mikalai Parakhnevich On

app.use(store) - you have already added the store to the vue instance.

Then you can access this storage from any component, for example using:

   import { mapState} from 'vuex';
   ...
   computed: {
    ...mapState({
      items: state => state.items
    }),
  },

or in setup:

import { useStore } from 'vuex';
...
setup(){    
  const store = useStore();
  const state = store.state; // <-- state from vuex
}

Your working example:

const store = new Vuex.createStore({
  state: {
    items: [{
      text: 'ahhh STORE 1'
    }, {
      text: 'ahhh STORE 2'
    }],
  },
  mutations: {

  },
  actions: {
    test({
      state
    }) {
      console.log(state.items)
    }
  },
  modules: {

  }
})

const {
  onMounted,
  onUpdated,
  onUnmounted,
  ref,
  reactive,
} = Vue; //here define only what you need



//Define Vue app
const App = {
  data() {
    return {};
  },
  methods: {},
  computed: {
    ...Vuex.mapState({
      items: state => state.items
    }),
  },
  setup(props, context) {
    const store = Vuex.useStore()
    onMounted(() => {
      console.info("App mounted!");
      console.log('mounted state', store.state)
    });
    onUpdated(() => {
      console.info("App updated!");
    });
    onUnmounted(() => {
      console.info("App unmounted!");
    });
  }
};
// Create new Vue app
const app = Vue.createApp(App);
app.use(store)
app.mount("#app");
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.global.js"></script>

<div id="app">
  <div v-for="item in items">{{item.text}}</div>
</div>