1、vuex 是什么
实现数据共享
是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。
概念:在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
不使用Vuex和使用Vuex: 使用Vuex统一管理状态的好处: ①能够在 vuex中集中管理共享的数据,易于开发和后期维护 ②能够高效地实现组件之间的数据共享, 提高开发效率 ③存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步
2、vuex 工作原理图
3、搭建vuex环境
npm i vuex
main.js
import store from './store'
new Vue({
el: '#app',
render: h => h(App),
store,
})
vuex 放在项目的 store文件夹中
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const actions = {}
const mutations = {}
const state = {}
export default new Vuex.Store({
actions,
mutations,
state,
})
注意:需要在 store/index.js 应用Vuex,不然在main.js 中应用Vuex,但 import store from './store' 会先解析,会出错。
在文件中,import … from … 无论放任何位置,都会先被解析。
4、关于 actions、mutations、state
state
actions
- 值为一个对象,包含多个响应用户动作的回调函数
- 通过 commit( )来触发 mutation 中函数的调用, 间接更新 state
- 如何触发 actions 中的回调?
在组件中使用: $store.dispatch(‘对应的 action 回调名’) 触发
mutations
- 值是一个对象,包含多个直接更新 state 的方法
- 谁能调用 mutations 中的方法?如何调用? 在 action 中使用:commit(‘对应的 mutations 方法名’) 触发
- mutations 中方法的特点:不能写异步代码、只能单纯的操作 state
案例:
Count.vue
<template>
<div>
<h1>当前数值为:{{ $store.state.sum }}</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="myclick">+</button>
<button @click="Waitclick">1s后+</button>
data() {
return {
n: 1,
}
},
methods: {
myclick() {
this.$store.commit('JIA',this.n)
}
Waitclick() {
this.$store.dispatch('waitjia',this.n)
}
}
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const actions = {
waitjia(context, value) {
setTimeout(() => {
context.commit('JIA', value)
}, 1000)
}
}
const mutations = {
JIA(state, value) {
state.sum += value
}
}
const state = {
sum: 0
}
export default new Vuex.Store({
actions,
mutations,
state,
})
若actions 中要处理很多业务逻辑,
则可以用到 context 中的 dispatch(),相当于用很多服务员。
const actions = {
waitjia(context, value) {
console.log('处理了一些事情')
context.dispatch('demo1', value)
},
demo1(context, value) {
console.log('我又哈哈哈处理了一些事情')
context.dispatch('demo2', value)
}
demo2(context, value) {
setTimeout(() => {
context.commit('JIA', value)
}, 1000)
}
}
为什么逻辑要写在actions中呢,因为如果很多组件都要这个逻辑,就会每个组件都要在methods中写逻辑,很麻烦,逻辑写在actions中,就可所有组件用,方便省事。
5、getters配置项
-
值为一个对象,包含多个用于返回数据的函数 -
如何使用?—— $store.getters.xxx
getters 用于将state中的数据进行加工
const getters = {
bigSum(state) {
return state.sum*10
}
}
使用:
<h1>数字放大10倍为:{{ $store.getters.bigSum }} </h1>
6、mapState与mapGetters
<h1>当前数值为:{{ $store.state.sum }} </h1>
<h1>数字放大10倍为:{{ $store.getters.bigSum }} </h1>
这样写很麻烦,总是有$store.state. 和 $store.getters.
所以这样:
<h1>当前数值为:{{ aa }} </h1>
<h1>学校:{{ bb }} </h1>
<h1>数字放大10倍为:{{ cc }} </h1>
computed: {
aa() {
return this.$store.state.sum
},
bb() {
return this.$store.state.school
},
cc() {
return this.$store.getters.bigSum
}
可是这样也很麻烦,需要在computed 中写很多$store.state. 和 $store.getters. 。
所以用到了mapState 与 mapGetters
Count.vue
import { mapState, mapGetters } from 'vuex'
computed: {
...mapState(['sum','school']),
...mapGetters(['bigSum']),
}
x对象中放y对象,y前需要加 ... 就相当于将y展开放入x
7、mapActions与mapMutations
methods: {
myclick() {
this.$store.commit('JIA',this.n)
},
sheclick() {
this.$store.commit('JIAN',this.n)
}
Waitclick() {
this.$store.dispatch('waitjia',this.n)
}
}
有 this.$store.commit 若写很多也很麻烦,所以为了省略写this.$store.commit
用到了mapActions与mapMutations
import { mapActions, mapMutations } from 'vuex'
methods: {
...mapMutations({myclick: 'JIA', sheclick: 'JIAN'}),
...mapActions({Waitclick: 'waitjia'}),
但是需要传值
<button @click = "myclick(n)">+</button>
<button @click="Waitclick(n)">1s后+</button>
8、多组件共享数据
9、vuex模块化
看下面例子 index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import home from './home'
import detail from './detail'
export default new Vuex.Store({
modules: {
home,
detail,
}
})
detail.js
import {
reqGoodsInfo
} from "@/api"
const state = {
goodInfo: {},
}
const mutations = {
GETGOODINFO(state, goodInfo) {
state.goodInfo = goodInfo
},
}
const actions = {
async getGoodInfo({
commit
}, skuId) {
let result = await reqGoodsInfo(skuId)
if (result.code == 200) {
commit("GETGOODINFO", result.data)
}
}
}
const getters = {
categoryView(state) {
return state.goodInfo.categoryView || {};
},
skuInfo(state) {
return state.goodInfo.skuInfo || {};
},
}
export default {
state,
mutations,
actions,
getters,
}
main.js
import store from "@/store"
Dedail/index.vue
......
......
import { mapGetters } from "vuex";
export default {
name: "Detail",
data() {
return {
skuNum: 1,
};
},
mounted() {
this.$store.dispatch("getGoodInfo", this.$route.params.skuid);
},
computed: {
...mapGetters(["categoryView", "skuInfo"]),
|