一、 概念:
1. 为什么要用vuex?
传统:
①. 每个页面都要去重新请求后台得到
②. 将数据存到session、cookie中
2. 作用:
①. 专门为vue.js设计的集中式状态管理架构.
②. 数据仓库,主要管理状态(共用的属性或数据).
③. 把数据进行共享,每个页面想用,都可以来调用.
3. 五种基本的对象:
①. state:存储状态对象(变量)
②. getters:getters计算过滤操作.对数据获取之前的再次编译,可以理解为state的计算属性.在组件中使用$sotre.getters.fun()
③. mutations:Mutations修改state状态,并且是同步的.在组件中使用$store.commit('', params).类似组件中的自定义事件.
④. actions:action异步修改状态.在组件中使用是$store.dispath('')
⑤. modules:store的子模块,大型项目方便状态管理而使用的.
二. 实战:
1. 安装:
npm install vuex --save
2. demo:
(1). src/vuex/store.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// state:状态对象,就是SPA(单页应用程序)中的共享值.
const state = {
count: 1
}
// 要改变state的数值,必须写在mutations中
// mutations是改变state的方法
const mutations = {
add(state, n) {
state.count += n
}
reduce(state) {
state.count--
}
}
export default new Vuex.Store({
state,
mutations
})
注:
修改state状态时传值,在mutations方法中再加上一个参数,并在commit的时候传递即可.
(2). Count.vue:
{{ $store.state.count }}
// Vuex提供了commit方法来修改状态
@click="$store.commit('add', 10)" // 带参数
@click="$store.commit(reduce)"
import store from '@/vuex/store'
export default {
name: 'Count',
store
}
3. 状态对象赋值给内部对象:
最原始的访问state状态对象方式:$store.state.count
如何把stroe.js中的state值,赋值给模板里data中的值?
三种赋值方式:
(1). 通过computed的计算属性直接赋值:
computed属性可以在输出前,对data中的值进行改变.
computed:{
count() {
return this.$store.state.count;
}
}
(2). 通过mapState的对象来赋值:
import { mapState } from 'vuex';
computed: mapState({
count: state => state.count // ES6的箭头函数来给count赋值
})
(3). 通过mapState的数组来赋值:
import {mapState} from 'vuex'
computed:mapState(["count"])
(4). 改进Count.vue:
{{ $store.state.count }} - {{ count }}
// Vuex提供了commit方法来修改状态
@click="$store.commit('add', 10)" // 带参数
@click="$store.commit(reduce)"
import store from '@/vuex/store'
import { mapState } from 'vuex'
export default {
name: 'Count',
computed: mapState(['count']),
store
}
4. 调用模板里的方法获取Mutations方法:
(1). 不想使用$store.commit(),想调用模板里的方法@click="reduce"一样调用.
import { mapMutations } from 'vuex'
methods:mapMutations(['add','reduce'])
(2). 改进Count.vue:
{{ $store.state.count }} - {{ count }}
@click="add(10)" // 带参数
@click="reduce"
import store from '@/vuex/store'
import { mapState, mapMutations } from 'vuex'
export default {
name: 'Count',
computed: mapState(['count']),
methods: mapMutations(['add', 'reduce']),
store
}
注:
①. state和mutations都有map的引用方法把模板中的编码进行简化.
5. getters计算过滤操作:
5.1 作用:
①. getters表面意思是获得
②. 可以把它看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工.
③. 类似store.js的计算属性.
5.3 改进:
(1). src/vuex/store.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
count: 1
}
const mutations = {
add(state, n) {
state.count += n
}
reduce(state) {
state.count--
}
}
// 声明getters属性,相当于计算属性的写法
const getters = {
// 对count进行一个计算属性的操作,在输出前,给它加上100.
count: state => state.count += 100
}
export default new Vuex.Store({
state,
mutations,
getters
})
(2). Count.vue:
{{ $store.state.count }} - {{ count }}
@click="add(10)" // 带参数
@click="reduce"
import store from '@/vuex/store'
import { mapState, mapMutations } from 'vuex'
export default {
name: 'Count',
computed: {
...mapState(['count']),
count() {
return this.$store.getters.count
}
},
methods: mapMutations(['add', 'reduce']),
store
}
注:
①. 最开始初始化是103,因为原始值是3,getters相当于计算属性加了100.
②. add每一次是加110,因为getters有100,传参有10.
③. reduce第一次是减101,因为getters有100,每次--(相当于减1).
④. 在vue的构造器中只能有一个computed属性,写多个只有最后一个computed属性可用,后面会覆盖前面.可以使用ES6中的展开运算符.
5.4 用mapGetters简化模板写法:
import { mapState, mapGetters } from 'vuex'
export default {
// 在computed属性中加入mapGetters
computed: {
...mapState(['count']),
...mapGetters(['count'])
}
}
6. actions异步修改状态:
①. actions和Mutations功能基本一样.
②. actions是异步的改变state状态,而Mutations是同步改变状态.
③. actions中可以使用commit调用Mutations里的方法.
@click="addAction"
@click="reduceAction"
import { mapState, mapGetters, mapActions } from 'vuex'
methods:{
...mapMutations([
'add', 'reduce'
]),
...mapActions(['addAction','reduceAction'])
}