1 了解Vuex
- Vuex是一个专门为
Vue.js
应用程序开发的 全局状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规则保证状态以一种可预测的方式发生变化
为什么要使用Vuex
- vuex的出现就是为了解决多组件间的数据通讯
- 通过定义和隔离状态管理中的各种概念并通过强制规则 维持视图和状态间的独立性
2. 使用
2.1 步骤
-
创建一个
store
[一个应用中运行一个store] -
创建
state
数据交由store
来管理 -
将创建好的
store
注入到Vue
根实例里 -
在组件中使用
state
中的数据在任意组件中都可利用
this.$store.state.xxx
获取状态数据
// 创建store
const store = new Vuex.Store({
// 创建state
state:{
products:[
{name: '鼠标', price: 20},
{name: '键盘', price: 40},
{name: '耳机', price: 60},
{name: '显示屏', price: 80}
]
}
}
let app = new Vue({
el:'#app',
template:`<myapp/>`,
components:{ myapp },
// 注入store到vue实例
store
});
//在myapp组件中使用store
this.$store.state.products
2.2 Vuex的核心概念
2.2.1 state
(理解为组件中的 data
)
state
就是Vuex
中的公共的状态, 用于保存所有组件的公共数据
vuex和单纯的全局对象有以下两点不同:
-
vuex的状态存储是响应式的
-
不能直接改变store中的状态
-
组件获取state
this.$store.state.xxx
-
组件修改state
this.$store.commit(mutation)
state: {
products: [
{ id:1, name: '鼠标', price: 20 },
{ id:2, name: '键盘', price: 40 },
{ id:3, name: '耳机', price: 60 },
{ id:4, name: '显示屏', price: 80 }
],
city: '广州'
},
2.2.2 getters
(理解为组件中的 computed
)
类似于vue中的计算属性,getter的返回值会根据其依赖被缓存起来,且只有当它的依赖发生改变了才会被重新计算
- 组件获取getter
this.$store.getters.xxx
getters: {
saleProducts(state) {
return state.products.map(item => {
return {
price: item.price / 2,
name: item.name
}
});
}
},
2.2.3 mutations
(理解为组件中的 methods
)
是存放处理数据的方法的集合,负责更改
state
中的数据
-
mutations
内的函数的参数-
state
-
payload
触发函数时传入的参数
-
-
调用方式:
this.$store.commit(type, payload)
mutations: {
change(state, payload) {
state.products = state.products.map(item => {
return { ...item, ...payload };
});
}
}
// 调用
this.$store.commit('change', { price: 88 })
2.2.4 actions
(类似于 mutations
,负责做异步操作)
actions
用来操作mutations
,mutations
用来操作state
actions
中可以包含异步操作,mutations
中绝对不允许出现异步
-
actions
内的函数的参数-
context
:与store
实例具有相同属性和方法的对象 -
payload
触发函数时传入的参数
-
-
调用方式:
this.$store.dispatch(type,payload)
//添加actions
actions:{
minusPriceAsync(context, payload) {
setTimeout(_ => {
context.commit('change', payload); //context提交
}, 2000)
}
}
//调用
this.$store.dispatch('minusPriceAsync', { price: 100 })
2.3 store
模块化
-
由于使用单一状态
state
(即所有状态会集中到state
这个对象),当应用变得非常复杂时,store
对象就有可能变得相当臃肿。 -
为了解决以上问题,
Vuex
允许我们将store
分割成模块(module
)。每个模块拥有自己的state
、mutation
、action
、getter
等,这样好管理又容易维护
import Vue from 'vue';
import Vux from 'vuex';
// 引入其他store模块
import home from './home.js';
import top250 from './top250.js';
export default new Vuex.Store({
modules: {
home,
top250
}
});
2.4 映射 Vuex
使用
mapState
,mapGetters
,mapMutations
,mapActions
把state
,getters
,mutations
,actions
映射到组件中使用,主要用于简化操作
// 模块化开发中直接引入mapState使用
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
computed:{
// 数组形式
...mapState([
'products' //映射computed.produccts为this.$store.state.products
]),
// 对象形式
...mapState({
// products: 'products',
// products: state => state.products,
products(state) {
return state.products;
}
})
},
methods:{
// 数组形式
...mapMutations([
'change', // 映射this.change为this.$store.commit('change')
]),
// 对象形式
...mapMutations({
change2: 'change', // 映射this.change2为this.$store.commit('change')
// 函数形式:
change3: (commit,payload) => {
commit('change', payload);
}
}),
...mapActions({
modify: 'minusPriceAsync', // 映射this.modify()为this.$store.dispatch('minusPriceAsync'),
// 函数形式:自动传入dispatch,payload为调用,minus是传入的参数
minus(dispatch,payload) {
dispatch('minusPriceAsync', payload)
}
})
}