vuex
项目结构
Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:
- 应用层级的状态应该集中到单个 store 对象中。
- 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。
- 异步逻辑都应该封装到 action 里面。
只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。
对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:
├── index.html
├── main.js
├── api
│ └── ... # 抽取出API请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
└── modules
├── cinema.js # 电影模块
└── tabbar.js # 标题模块
核心概念
- state
- module
- action
- getter
- mutation
state
Vuex 使用单一状态树——用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
action
Action 类似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
getter
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
Getter 接受 state 作为其第一个参数:
mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
store/index
import Vue from "vue";
import Vuex from "vuex"
Vue.use(Vuex)
import cinema from "./module/cinema" //导入cinema模块
import tabbar from "./module/tabbar"
const store =new Vuex.Store({
modules:{
cinema,
tabbar
}
})
export default store
main.js
// 引入vuex
import store from "./store/index.js"
new Vue({
store, // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
render: h => h(App),
}).$mount('#app')
电影模块 cinema.js
import {instance} from "@/utils/http"
const cinema ={
namespaced: true,
state: {
cinemaList:[]
},
actions: {
//获取到接口数据
getcinemaList(context){
instance.get("/gateway?cityId=310100&ticketFlag=1&k=7247863",{
headers:{
'X-Host': 'mall.film-ticket.cinema.list'
}
}).then((res)=>{
// this.cinemaList=res.data.data.cinemas;
console.log(res.data.data)
context.commit("setcinemaList",res.data.data.cinemas)
})
}
},
getters: {
//当依赖值改变时,会重新进行计算
getCinemaListFive(state) {
return state.cinemaList.slice(0, 5);
}
},
mutations: {
//第一个参数为state,当数据改变时。缓存在state中
setcinemaList(state,data){
state.cinemaList=data
},
someMutation (state) {
api.callAsyncMethod(() => {
state.count++
})
}
}
}
export default cinema
在单页中调用vuex中的数据或方法
辅助函数
-
mapState
-
mapGetters
-
mapActions
-
mapMutations
// 引入vuex中的mapState,mapGetters
import {mapState,mapGetters,mapActions,mapMutations} from "vuex"
computed:{
// 获取state中的cinemaList数据:
...mapState("cinema",["cinemaList"]),
// 用来获取vuex中getters
...mapGetters("cinema",["getCinemaListFive"]),
// 用于调用actions中的方法
... mapActiones(("cinema",["getCinemaList"]),)
// 用于调用mutations中的方法
... mapActiones(("cinema",[" someMutation"]),)
}
使用的时候就在获取的数据前加this例如:
this.getCinemaList
this.cinemaList