I'm not sure why there's no mutation when I check it under Vuex extension when I'm on "127.0.0.1:8000/products/create". No idea what other files are needed in order to solve this. Please, let me know. I'll then add them ASAP.
Thank you very much in advance for looking into this
I'm following this tutorial:
https://www.youtube.com/watch?v=bdvaBsuqDAM&list=PLVIT7EMonV3dWOIjbQxQ2jxhywnjFb7Hy&index=18
No mutation - no good
With mutation - very good
resources > js > components > products > ProductAdd.vue
<script>
import { store } from "../../store"
import * as actions from "../../store/action-types"
export default {
mounted() {
// Get categories
store.dispatch(actions.GET_CATEGORIES)
}
}
</script>
resources > js > store > modules > categories > index.js
import actions from "./actions";
import getters from "./getters";
import mutations from "./mutations";
const state = {
categories: {},
};
export default {
state,
actions,
getters,
mutations,
};
resources > js > store > modules > categories > actions.js
import * as actions from "../../action-types";
import * as mutations from "../../mutation-types";
import axios from "axios";
export default {
[actions.GET_CATEGORIES]({ commit }) {
axios
.get("/api/categories")
.then((res) => {
if (res.data.success == true) {
commit(mutations.SET_CATEGORIES, res.data.data);
}
})
.catch((err) => {
console.log(err.response);
});
},
};
resources > js > store > action-types.js
// Categories
export const GET_CATEGORIES = "GET_CATEGORIES";
resources > js > store > modules > categories > mutations.js
import * as mutations from "../../mutation-types";
export default {
[mutations.SET_CATEGORIES](state, payload) {
state.categories = payload;
},
};
resources > js > store > mutation-types.js
// Categories
export const SET_CATEGORIES = "SET_CATEGORIES";
app > Http > Controllers > CategoriesController.php
// HANDLE AJAX REQUEST
public function getCategoriesJson() {
$categories = Category::all();
return response()->json([
'success' => true,
'data' => $categories
], Response::HTTP_OK);
}
resources > js > store > index.js
import { createStore } from "vuex";
// Modules
import categories from "./modules/categories";
// Create a new store instance.
export const store = createStore({
modules: {
categories,
},
});
resources > js > app.js
require("./bootstrap");
import { createApp } from "vue";
import { store } from "./store";
import ProductAdd from "./components/products/ProductAdd.vue";
const app = createApp({});
app.component("product-add", ProductAdd);
app.use(store);
app.mount("#app");
Related
I got a vuex store like this:
const state = {
status: '',
};
const getters = {
//...
};
const actions = {
// ...
};
const mutations = {
// ...
};
export default {
namespaced: true,
state,
getters,
actions,
mutations,
}
Now I'd like to access app.config.globalProperties.$notify
In Vue.js2 I was using something like Vue.prototype.$notify, but this is not working anymore.
$notify is also provided like this:
app.use(routes)
.provide('notify', app.config.globalProperties.$notify)
.mount('#app')
Unfortunately I did not find any information about this in the docs yet.
So my question: How can I either inject $notify or access app.config.globalProperties within this store?
From your store and its modules, you could return a store factory -- a function that receives the application instance from createApp and returns a store:
// store/modules/my-module.js
const createStore = app => {
const mutations = {
test (state, { committedItem }) {
app.config.globalProperties.$notify('commited item: ' + committedItem)
}
}
return {
namespaced: true,
//...
mutations,
}
}
export default app => createStore(app)
// store/index.js
import { createStore } from 'vuex'
import myModule from './modules/my-module'
export default app =>
createStore({
modules: {
myModule: myModule(app)
}
})
Then use the store factory like this:
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import createStore from './store'
const app = createApp(App)
app.use(createStore(app)).mount('#app')
demo
I want to use PersistedState https://github.com/robinvdvleuten/vuex-persistedstate with vuex but i can't get to setup correctly.
I have this module inside the store directory
export const auth = {
namespaced: true,
state: {
},
getters: {
countLinks: state => {
return state.links.length
}
},
mutations: {
SET_LINKS: (state, links) => {
state.links = links;
},
//Synchronous
ADD_LINK: (state, link) => {
state.links.push(link)
},
REMOVE_LINK: (state, link) => {
state.links.splice(link, 1)
},
REMOVE_ALL: (state) => {
state.links = []
}
},
actions: {
//Asynchronous
removeLink: (context, link) => {
context.commit("REMOVE_LINK", link)
},
removeAll ({commit}) {
return new Promise((resolve) => {
setTimeout(() => {
commit('REMOVE_ALL')
resolve()
}, 1500)
})
}
}
}
I have named this àuth.js
This is my index.js file also inside store directory
import { createStore } from 'vuex'
import createPersistedState from "vuex-persistedstate"
import { auth } from './auth'
const dataState = createPersistedState({
paths: ['data']
})
const store = createStore({
modules: {
auth
},
plugins: [dataState]
})
I have a total of 7 modules i would like to load and use in various places in my application. To kick things off i just want to load auth module and use it in my home.vue page
This is the script section of my home.vue
import Footer from '#/components/Footer.vue'
import Header from '#/components/Header.vue'
import { mapGetters} from 'vuex'
import store from '../store';
export default {
name: 'Home',
components: {
Footer,Header
},
mounted () {
var links = ['http://google.com','http://coursetro.com','http://youtube.com'];
store.commit('SET_LINKS', links);
},
computed: {
...mapGetters([
'countLinks'
]),
}
}
This is my main.js file
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import i18n from './i18n'
import FlagIcon from 'vue-flag-icon'
import {store} from './store';
createApp(App).use(i18n).use(FlagIcon).use(store).use(router).mount('#app')
When i npm run serve, i get the error
10:7 error 'store' is assigned a value but never used
no-unused-vars
How should i correct this to be able to use auth.js module anywhere in my application?
I want to apply mutations through actions to a variable in my vuejs application. But I get this error saying [vuex] unknown local mutation type: updateValue, global type: app/updateValue
Here is my store folder structure:
-store
-modules
-app
-actions.js
-getters.js
-mutations.js
-state.js
-index.js
-actions.js
-getters.js
-mutations.js
-state.js
-index.js
This is my ./store/index.js file:
import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import getters from './getters'
import modules from './modules'
import mutations from './mutations'
import state from './state'
Vue.use(Vuex)
const store = new Vuex.Store({
namespaced: true,
actions,
getters,
modules,
mutations,
state
})
export default store
This is my ./store/modules/index.js:
const requireModule = require.context('.', true, /\.js$/)
const modules = {}
requireModule.keys().forEach(fileName => {
if (fileName === './index.js') return
// Replace ./ and .js
const path = fileName.replace(/(\.\/|\.js)/g, '')
const [moduleName, imported] = path.split('/')
if (!modules[moduleName]) {
modules[moduleName] = {
namespaced: true
}
}
modules[moduleName][imported] = requireModule(fileName).default
})
export default modules
This is my ./store/modules/app/actions.js:
export const updateValue = ({commit}, payload) => {
commit('updateValue', payload)
}
This is my ./store/modules/app/getters.js:
export const value = state => {
return state.wruValue;
}
This is my ./store/modules/app/mutations.js:
import { set, toggle } from '#/utils/vuex'
export default {
setDrawer: set('drawer'),
setImage: set('image'),
setColor: set('color'),
toggleDrawer: toggle('drawer')
}
export const updateValue = (state, payload) => {
state.wruValue = payload * 12;
}
This is my ./store/modules/app/state.js:
export default {
drawer: null,
color: 'green',
wruValues:1,
wruValue: 1,
}
and finally this is my vue component:
<v-btn #click="updateValue(10)">
SHOW
</v-btn>
import { mapActions } from 'vuex';
...mapActions ('app',[
'updateValue'
]),
So when I click on the button I expect to see the wruValue to change (I print the value somewhere else for testing purposes) but instead I get the error mentioned above. What's wrong with my code?
commit('updateValue', payload, {root: true})
But I find your use of namespacing odd. For my projects, I don't separate out files for getters, actions, etc, I separate out tasks, projects, companies, etc. But if it works for you, that's fine. It doesn't seem like the issue. If you still get an error, you might need to change "updateValue" to "mutations/updateValue" or something.
You should use this project structure:
src/store/modules/app.js
export const state = {
drawer: null,
color: 'green',
wruValues: 1,
wruValue: 1
}
export const mutations = {
UPDATE_VALUE: (state, payload) => {
state.wruValue = payload * 12
}
}
export const actions = {
updateValue: ({ commit }, payload) => {
commit('UPDATE_VALUE', payload)
}
}
export const getters = {
getWruValue: (state) => state.wruValue
}
src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const requireContext = require.context('./modules', true, /.*\.js$/)
const modules = requireContext.keys()
.map(file =>
[file.replace(/(^.\/)|(\.js$)/g, ''), requireContext(file)]
)
.reduce((modules, [name, module]) => {
if (module.namespaced === undefined) {
module.namespaced = true
}
return { ...modules, [name]: module }
}, {})
export default new Vuex.Store({
modules
})
src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store/'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
src/App.vue
<template>
<div id="app">
<button #click="updateValue(10)">
SHOW
</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions('app', ['updateValue'])
}
}
</script>
Then if you want to add a new store namespace, u need to put it inside of src/modules folder.
I'm currently using Nuxt and I would like to do unit testing in my vuex modules.
I'm using vuex modules and here's my index.js
store/index.js
import Vuex from 'vuex';
import * as user from "~/store/modules/users";
const createStore = () => {
return new Vuex.Store({
state: {},
mutations: {},
modules: {
user
}
});
};
export default createStore;
and here's the vuex for users (I made it very simple by mutating the count only but I'm doing api requests here)
store/modules/user.js
export const state = {
count: 0
}
export const mutations = {
INCREMENT(state, user) {
state.count += 1;
}
}
export const actions = {
incrementCount({commit}) {
commit('INCREMENT');
}
}
export const getters = {
count(state) {
return state.count;
}
}
I would like to use Mocha and Chai, for testing state, actions, mutations, and getters for each vuex modules.
Can anyone give a sample for doing a unit test for this?
I've been going in circles trying to set up Vuex modules for a project. I've tried following a tweaked example of Chris Fritz example of registering components in a more productive way as seen here: https://www.youtube.com/watch?v=7lpemgMhi0k, but when I try to use ...mapActions, I get issues that the namespace can't be found, if I try to register the modules manually, I get the error that the getter.default expected an action, but returned {}
I'll try keep this clean - the first lot of info is my module setup, the next section is what produces the first issue and the code, the second is the second attempt which produces the getter issue.
My Module setup...
./store/modules/ModuleName:
./store/modules/ModuleName/index.js
import * as actions from './actions'
import * as getters from './getters'
import * as mutations from './mutations'
const namespaced = true
export default {
namespaced,
state () {
return {
foo: 'bar'
}
},
actions,
getters,
mutations
}
./store/modules/ModuleName/actions.js
import types from './types'
const myFunction = ({ commit, state }) => {
commit(types.FOO, bar)
}
export default {
myFunction
}
./store/modules/ModuleName/getters.js
const Foo = (state) => {
return state.foo
}
export default {
Foo
}
./store/modules/ModuleName/mutations.js
import types from './types'
const mutateFoo = (state, payload) => {
state.Foo = payload
}
export default {
[types.FOO]: mutateFoo
}
./store/modules/ModuleName/types.js
export default {
FOO: 'foo'
}
Version one
This is the preferred way I'd like to do it:
Error: [vuex] module namespace not found in mapActions(): myModule/
./store/modules.js
const requireModule = require.context('../store/modules/', true, /\.js$/)
const modules = {}
requireModule.keys().forEach(fileName => {
// Use index to prevent duplicates of the same module folder...
if (fileName.includes('index')) {
// now I just want the folder name for the module registration
const moduleName = fileName.replace(/(\.\/|\/.+\.js)/g, '')
modules[moduleName] = requireModule(fileName)
}
})
export default modules
./store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules'
Vue.use(Vuex)
export default new Vuex.Store({
modules
})
.Vue component:
<template>
...
</template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState('ModuleName', { title: state => state.foo })
},
methods: {
...mapActions('ModuleName, ['myFunction'])
}
}
</script>
Version Two
Error:
Uncaught Error: [vuex] getters should be function but
"getters.default" in module "Harvest" is {}.
./store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import Harvest from './modules/myModule'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
myModule
}
})
.Vue component:
<template>
...
</template>
<script>
export default {
computed: {
title () { return this.$store.getters.myModule }
}
}
</script>
What am I missing? Can someone help shed a bit of light to get this working?
For your Version two, because you export default, your import state should be:
import actions from './actions'
import getters from './getters'
import mutations from './mutations'
const namespaced = true
export default {
namespaced,
state () {
return {
foo: 'bar'
}
},
actions,
getters,
mutations
}
For version 1, first you should change import statement as above, then change
if (fileName.includes('index')) {
// now I just want the folder name for the module registration
const moduleName = fileName.replace(/(\.\/|\/.+\.js)/g, '')
modules[moduleName] = requireModule(fileName).default
}
Hope it can help!