// main.js
const app = createApp({
...App,
provide: { baseUrl: 'https://rickandmortyapi.com/api/' },
})
app.mount('#app')
// Home.vue
export default {
inject: ['baseUrl'],
data() {
return {
...
}
}
};
npm install vuex@next
## OR
yarn add vuex@next
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state() {
return {
items: [],
}
},
})
// main.js
import store from './store'
const app = createApp(App)
app.use(router)
app.use(store)
app.mount('#app')
// Home.vue
computed: {
searchResults() {
return this.$store.state.items
},
},
// Home.vue
import { mapState } from 'vuex'
export default {
computed: {
...mapState({
searchResults: (state) => state.items,
})
}
}
export default createStore({
state() {
return {
items: [],
}
},
mutations: {
fetchResults(state) {
state.items = [
{
id: '1',
name: 'Test',
description: 'Test description',
liked: false,
},
]
},
},
})
// Home.vue
created() {
this.$store.commit('fetchResults')
},
mutations: {
FETCH_RESULTS(state) {
...
},
},
// store/mutationTypes.js
export const FETCH_RESULTS = 'FETCH_RESULTS'
// store/index.js
import * as types from './mutationTypes';
export default createStore({
state() {
return {
items: [],
}
},
mutations: {
[types.FETCH_RESULTS](state) {
/*...*/
},
},
})
// store/index.js
import * as types from './mutationTypes';
export default new Vuex.Store({
state: {
...
},
mutations: {
...
},
actions: {
async fetchResults({ commit }, searchTerm) {
// axios request to fetch the results
commit(types.FETCH_RESULTS, results)
},
},
});
// Home.vue
created() {
this.$store.dispatch('fetchResults', this.searchTerm)
},
// Home.vue
import { mapActions } from 'vuex';
export default {
methods: {
...mapActions(['fetchResults']),
},
created() {
this.fetchResults(this.searchTerm);
},
};
// store/index.js
mutations: {
[types.REQUEST_RESULTS](state) {
state.loading = true
state.error = null
},
[types.RECEIVE_RESULTS_SUCCESS](state, payload) {
state.loading = false
state.items = payload
state.error = false
},
[types.RECEIVE_RESULTS_ERROR](state) {
state.loading = false
state.items = []
state.error = true
},
},
// store/index.js
actions: {
async fetchResults({ commit }, searchTerm) {
const endpoint = searchTerm.length ? '/breeds/search' : '/breeds'
commit(types.REQUEST_RESULTS)
try {
/* Logic for fetching results */
commit(types.RECEIVE_RESULTS_SUCCESS, results)
} catch {
commit(types.RECEIVE_RESULTS_ERROR)
}
},
},
fetch<Entity> action
REQUEST_<Entity> mutation
RECEIVE_<Entity>_SUCCESS mutation
RECEIVE_<Entity>_ERROR
mutation
// store/index.js
getters: {
numberOfLiked(state) {
return state.items.filter((item) => item.liked).length
},
},
// store/index.js
getters: {
getItems(state) {
return state.items // This is bad, use mapState instead!
}
},
// store/index.js
const items = {
namespaced: true,
state: () => ({...}),
mutations: {...},
actions: {...},
getters: {...},
};
export default createStore({
modules: {
items,
},
...
})
// Characters.vue
computed: {
...mapState('items', {
items: (state) => state.items,
loading: (state) => state.loading,
}),
},
// store/index.js
const store = createStore({ /* options */ })
store.registerModule('items', {
// ...
})
// main.js
import store from './store'
const router = createRouter({
routes,
history: createWebHistory(),
})
router.beforeEach((to, from, next) => {
if(!store.state.isAuthenticated) next({name: 'login'})
else next()
})