1. vuex作用:
1.1 是一个专为 vue.js 应用程序开发的状态管理模式,集中式存储管理应用的所有组件的状态,以此实现非父子甚至不同组件之间的高效通信
1.2 缓存后端数据,提高用户体验
2. 什么时候vuex比较适用?
如果构建一个中大型单页应用,考虑到如何更好地在组件外部管理状态,vuex 就成为了自然而然的选择。但是如果您的应用够简单,不打算开发大型单页应用的话,最好还是不要使用 vuex,因为这时候使用 vuex 可能是繁琐冗余的。
3. vuex原理:
vuex的状态管理分为同步状态和异步状态,都是在单向数据流理念下通过vue 的官方调试工具 devtools extension进行状态管理,所以最好严格遵循数据流向:
同步状态:Mutation====>State
异步状态:Actions====>Mutation====>State
4、vuex的几种常见安装及使用步骤:
4.1 安装vuex:
npm:
npm i vuex --save
yarn:
yarn add vuex
cdn直接引入:
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
4.2检查项目下的main.js是否引入了store:
项目生成时就有的,但是最好检查一下:
import store from './store'
//默认指向store/index.js
4.3 开始编译项目下src/store/index.js:
5、vuex的五大核心用法:
(1) state:单一状态树 ,每个应用将仅仅包含一个 store 实例,存放需要公共管理的状态(变量名)
(2) getters:可以从store 中的 state 中派生出一些状态,getters的返回值会根据 它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算,类似于vue的计算属性
(3) actions:异步状态管理下的开始,存方法
(4) mutations:同步状态下的开始以及异步状态下的中转,存方法。更改 vuex 的 store 中的状态的唯一方法是提交 mutation。
(5) modules :管理模块,当多人合作开发时,避免每个人在同一个index.js文件修改,可把index.js中的state、mutations、getters、actions分为几个模块,在自己的模块文件中编译,最后将所有的模块名引入在Module中。(分为几个子模块后状态共享的用法也会不同,下面会详细介绍)
注意:只是分为几个模块,但是一个项目中store里始终只能有唯一的index.js
以下是本人开发过程中的index.js,其中注释部分有详细介绍数据流中传参相关语法:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from '@/util/http'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
isTabbarShow: true,
cinemaList: [],
cityName: "北京",
cityId: "110100"
},
// 处理同步状态+异步状态下的中转
mutations: {
show(state) {
state.isTabbarShow = true
},
hide(state) {
state.isTabbarShow = false
},
//第一个参数默认为state,第二个参数是Action传过来的参数
setCinemaList(state, data) {
//把数据传到state
state.cinemaList = data;
},
setCityName(state, data) {
state.cityName = data
},
setCityId(state, data) {
state.cityId = data
}
},
// 处理异步请求
actions: {
//store是形参名,vuex会自动传实参:store实例对象,第二个参数为组件中共享状态时传的参数
getCinemaAction(store, id) {
axios.request({
url: `/gateway?cityId=${id}&ticketFlag=1&k=9719361`,
headers: {
'X-Host': 'mall.film-ticket.cinema.list'
}
}).then(res => {
console.log(res.data)
//提交中转到mutations
store.commit("setCinemaList", res.data.data.cinemas)
})
},
},
//对上面全局状态进行数据处理,类似于vue的计算属性
getters: {
defaultList(state) {
return state.cinemaList.slice(0, 5)
}
},
modules: {}
})
6、在任意组件中实现状态共享的常见的一些语法用法(与上面相对应):
共享state/getters中的状态:this.$store.state/getters+在state中的状态名
this.$store.state.cinemaList
this.$store.getters.defaultList
共享actions中的状态: this.$store.dispatch(‘xxx’,需要传的参数)
this.$store.dispatch("getCinemaAction",this.cityId)
共享mutations中的状态: this.$store.commit(‘xxx’,需要传的参数)
this.$store.commit("hide")//调用mutations中的hide()
7、辅助函数mapState、mapActions、mapMutation、mapGetters用法:
上面组件中共享状态用法是不是觉得很麻烦????这四个辅助函数很高兴为您做简化服务>>>>>>>>
7.1 在组件中引入辅助函数:
import { mapState,mapGetters} from 'vuex'//需要哪个里面的状态就引入哪个
7.2 用展开运算符引入所需的状态名并开始简化使用,简化用法:不管是state、mutations还是其他两个里面的,直接this.状态名
computed: {
...mapState(["cinemaList"]),
...mapGetters(["defaultList"]),
SdefaultList(){
return this.defaultList
}
},
methods: {
...mapMutations(["show","hide","setCinemaList"]),
handleCity(){
this.setCinemaList([]);
this.hide()
}
},
不知道智慧的大噶有没有发现展开的位置有要求呢????
好吧,我等不及了,现在揭晓:
⬇
⬇
⬇
⬇
⬇
⬇
⬇
⬇
⬇
⬇
⬇
⬇
⬇
⬇
注意!!!!!!!!!!!!!!!!!!!!!!!
一定要记得:根据他们中存的是状态(变量)还是方法
mapState、mapGetters一般在计算属性中展开
mapActions、mapMutation在methods中展开
8、index.js模块化:
当多人合作开发时,避免每个人在同一个index.js文件修改,可把index.js中的state、mutations、getters、actions分为几个模块,在自己的模块文件中编译,最后将所有的模块名引入在Module中。一般按组件分:
8.1 在store下建立modules文件夹,添加所需的js文件(所需的模块)
8.2 在对应的模块下编译需要共享的状态:
import http from '@/util/http'
const module = {
namespaced: true, //开通命名空间
state: {
},
actions: {
},
mutations: {
},
getters: {
}
export default module
8.3 在index.js文件的modules下引入所有模块:
import Vue from 'vue'
import Vuex from 'vuex'
//引入模块
import cinema from './module/cinemaModule'
import tabbar from './module/tabbarshowModule'
import city from './module/cityModule'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
},
mutations:{
},
actions:{
},
getters:{
},
modules:{
//添加模块名
cinema,
tabbar,
city
}
})
export default store
8.4 在组件中使用:
需要哪个模块的状态就前面加上模块名
computed: {
//只有这里有改变
...mapState("cinema",["cinemaList"]),
...mapState("city",["cityName","cityId"]),
SdefaultList(){
return this.defaultList
}
},
methods: {
...mapMutations(["show","hide","setCinemaList"]),
handleCity(){
this.setCinemaList([]);
this.hide()
}
},
9、Vuex缓存数据永久化:
vuex每次从后台获取的缓存数据虽然能够减少数据加载次数,但是每次刷新就清空了,但我们实际开发中是需要它永久保存的,所以
9.1 安装
//nmp
npm install --save vuex-persistedstate
//yarn
yarn add vuex-persistedstate
//cdn引入
<script src="https://unpkg.com/vuex-persistedstate/dist/vuex-persistedstate.umd.js"></script>
9.2 index.js中添加import和plugins
//引入vuex-persistedstate
import createPersistedState from "vuex-persistedstate";
const store = new Vuex.Store({
//添加
plugins: [createPersistedState({
reducer(data){
return {
city:data.city//需要永久化的模块,默认为全部永久化
}
}
})],
state: {
},
mutations:{
},
actions:{
},
getters:{
},
modules:{
cinema,
tabbar,
city
}
})
export default store