vuex是一套相对独立的代码,因此可以抽象出到单独的文件夹里,那么比较好的代码结构是啥样的?
话不多说,以下是vuex比较好的代码结构
├── index.html
├── main.js
├── api
│ └── ... # 抽取出API请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 我们组装模块并导出 store 的地方
├── getter.js # 根级别的 getter
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
├── mutation-type.js # 将mutation名常量集中
└── modules
└── myModule.js # 单独模块
由此可以看出vuex的每个功能模块为一个单独的js文件
下面分别说明每个js文件内容
1.index.js
index.js主要是导出vuex的,以及将全局的state声明在其中,示例代码如下
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import actions from './actions'
import getters from './getters'
import mutations from './mutations'
import stock from './module/stock'
let state = {
user_info: //用户信息
JSON.parse(localStorage.getItem('user_info')),
address_list: //用户常用地址
JSON.parse(localStorage.getItem('address_list'))
}
export default new Vuex.Store({
state,
actions,
getters,
mutations,
modules:{
stock
},
})
以上可以看出,所有模块均在index中引入,state内声明了两个状态,以及将new 的vuex导出,这样便可以在main.js内引入了
为什么状态从localStorage中取值?
假如初始值user_info = ‘’;在某个时间单纯给user_info赋值,如果不刷新页面这个值会一直存在,那么当你点击刷新按钮刷新当前页面时,user_info就回到初始值空值了,为什么?因为vuex中的状态值时放在内存当中的,当你刷新页面时这些值被释放掉了,就找不到了,因此存在本地(方法之一)即使刷新也不会导致状态丢失
2.mutations.js
import {SET_ADDRESS,UPDATE_USERINFO} from './mutation-types'
export default {
//更新仓库地址
[UPDATE_ADDRESS] (state, newVal){
state.address_list = newVal;
localStorage.setItem('address_list',JSON.stringify(newVal));
},
//更新仓库用户信息
[UPDATE_USERINFO] (state, newVal) {
state.user_info = newVal;
localStorage.setItem('user_info',JSON.stringify(newVal));
},
}
这里的是若干的函数,用来提交仓库的更新,因为不能直接对仓库状态更新,函数名统一声明在mutation-type.js内
export const UPDATE_ADDRESS = "UPDATE_ADDRESS";
export const UPDATE_USERINFO = "UPDATE_USERINFO";
//------------------------------------------------myModule------------------------------------//
export const MY_MODULE_FUNC = "MY_MODULE_FUNC";
为什么要单独声明呢,首先官方建议是这么做的,其次这样也的确适合大型项目的统一管理,好处在你达到一定规模自然会体现出来
3.getters.js
export default{
user_name(state) {
return state.user_info.user_name + 'Hello!';
}
}
getters.js主要是筛选仓库状态的封装,相当于一个组件内的computed,对仓库内的状态进一步加工
4.actions.js
export default {
updateUserInfo ({commit, newVal}) {
axios('http://xxxxx',{
user_info: newVal
}).then((res) => {
commit("SET_SHOPLIST",data.data.shop_list);
}).catch((err) => {
console.log(err);
})
}
}
actions.js主要是进行一些异步操作,以及对mutation的提交更新,由于在mutation内不能进行异步操作(官方建议最好是不要),因此有了actions
5.module(myModule.js)
模块就是相对单独的一个vuex,内部有单独享有的状态state,mutations等等
import {MY_MODULE_FUNC} from './../mutation-types'
export default {
namespaced: true,
state: {
count: 0
},
mutations: {
[MY_MODULE_FUNC] (state,newVal) {
state.count = newVal;
}
}
}
6.在main.js内引入到全局
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
7.在组件中使用vuex
vuex的文件目录以及十分清晰了,那么如何使用这些呢,一下在组件中使用的方式
<template>
<span>Hello World!</span>
</template>
<script>
import {mapState,mapMutations,mapGetters,mapActions} from 'vuex'
export default {
name: 'Hello',
props: ['name'],
mounted() {
console.log(this.count);
console.log(this.user_info);
let address = [{add1: 'xxx', add2: 'xxx'}];
this.UPDATE_ADDRESS(address);
},
computed: {
//模块内的独立仓库
...mapState('myModule',[
"count"
]),
// 公共区域的仓库
...mapState([
'user_info',
'address_list'
]),
// getter
...mapGetters([
'user_name'
])
},
methods: {
// 模块内的独立mutations
...mapMutations('myModule',[
'MY_MODULE_FUNC'
]),
...mapMutations([
'UPDATE_ADDRESS',
'UPDATE_USERINFO'
])
//异步操作提交mutation的action
...mapActions([
'updateUserInfo'
])
}
}
</script>
其实引入方式有很多种,官网都有介绍,但是通过通过vuex的各个分发函数以及ES6的展开运算符能够更加简便的使用,分发在组件中之后就如同在组件中声明的变量及函数,可以通过当前对象this访问到,但是要注意一点,在computed中已经映射的状态,不能再在data里重复声明同名变量,函数类似
OK,以上是完整的vuex项目结构及引用