vuex之基础知识
1. 对Vuex 的认识
1.1 简介
- 对 vue 应用中 多个组件的 共享状态 进行 集中式的管理(读/写)
- state: 驱动应用的 数据源(data数据)
- view: 以声明方式将 state 映射到视图(template视图)
- actions: 响应在 view 上的用户输入导致的状态变化(包含 n 个更新状态的方法)
1.2 解决多组件共享状态的问题
- 多个视图依赖于同一状态
- 来自不同视图的行为需要变更同一状态
- 以前的解决办法
- 将数据以及操作数据的行为都定义在父组件
- 将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递)
- vuex 就是用来解决这个问题的
2. store 文件说明
- index.js:vuex 的核心管理对象 store 对象模块
- state.js:状态对象:驱动应用的数据源,主要是data数据
- mutations.js:直接更新state的多个方法 的对象
- actions.js:通过commit提交,对mutaions 间距更新state的多个方法 的对象
- getters.js:包含多个基于state的getter计算属性 的对象
- mutation-types.js:包含n个mutation的type的名称常量 (非必选)
2.1 状态的自管理应用
- state : 驱动应用的数据源
- view :以声明方式将state映射到视图
- actions : 响应在view上的用户输入导致的状态变化(包含n个更新状态的方法)
2.1.1 state
是vuex管理的状态对象,它是唯一的
// 驱动应用的数据源
const state={
myName:'may',
users:[
{
id:1,
name:"Amy"
},
{
id:2,
name:"Jack"
}
]
}
2.1.2 mutations
- 包含多个直接更新 state 的方法(回调函数)的 对象
- 谁来触发调用:由
action
中的commit('mutation 名称')
触发 - 只能包含同步的代码, 不能写异步请求
const mutations = {
reName (state, {newName}) {
//更新 state 的某个属性 传参是 对象 的方式
state.myName=newName
}
}
2.1.3 actions
- 包含多个事件回调函数的对象,可以执行异步数据请求
- 原理:通过
commit()
来触发mutation
的调用,进而间接更新 state - 谁来触发调用: 一般是 组件中:
this.$store.dispatch('updateName', newName)
const actions = {
updateName({commit, state}, newName) {
commit('reName', {newName})
}
}
actions和mutations的异同
- Action 提交的是 mutation,而不是直接变更状态
- Action 可以包含任意异步操作
- mutations只能同步执行 actions可以异步执行任何操作
2.1.4 getters
- 包含多个计算属性(get)的对象
- 谁来触发调用: 一般在组件中:
this.$store.getters.AAA
const getters = {
AAA (state) {return 'hello'}
}
3. Vuex使用步骤
下载安装
npm install --save-dev vuex
3.1 创建 index.js
是 vuex
的核心管理对象
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import users from './users' // 用户信息模块
// 注册声明使用vuex
Vue.use(Vuex)
export default new Vuex.Store({
state,
mutations,
actions,
getters,
modules: {
users,// users模块
}
})
3.2 创建 state.js
export default {
latitude: 31.1132571411, // 纬度
longitude: 121.3820552139, // 经度
address: {}, // 地址信息对象
foodtypes: [], // 商品分类
shoplist: [], //商家列表数组
}
3.3 创建 mutations.js
直接更新state的多个方法 的对象
注意接收的数据是 对象
不可以异步操作
import {
RECEIVE_ADDRESS
} from './mutation-types'
export default {
//根据经纬度获取当前位置信息 注意是对象
[RECEIVE_ADDRESS](state, {address}) {
state.address = address
}
}
3.4 创建 actions.js
通过commit提交,对mutaions 间接更新state的多个方法 的对象
import {
RECEIVE_ADDRESS
} from './mutation-types'
import {
//根据经纬度获取当前地址信息
reqAddress
} from '../api/index'
export default {
// 根据经纬度获取当前地址信息
// data 必须是对象
async getAddress({commit, state},data) {
// 发送异步ajax请求
const result = await reqAddress(state.latitude, state.longitude);
const address = result.data;
//提交mutation
commit(RECEIVE_ADDRESS, {address})
}
}
3.5 创建 getters.js
包含多个基于state的 getter计算属性 的对象
export default {
//获取购物车中食物的总数量
totalCount(state) {
return state.shopCartsList.reduce((preTotal, food) => {
return preTotal + food.count
}, 0)
},
//计算总价格
totalPrice(state) {
return state.shopCartsList.reduce((shopCartsList, food) => {
return shopCartsList + food.price * food.count
}, 0)
}
}
3.6 创建mutation-types.js 可选
包含n个mutation的type的名称常量
export const JIAN_FOOD_COUNT = 'jian_food_count' //减少count
export const JIA_FOOD_COUNT = 'jia_food_count' //增加count
export const CLEAT_CART_SHOP = 'cleat_cart_shop' //清空购物车
3.7 映射配置 store核心模块
-
一般是在
main.js
文件中 -
映射store对象完成以后,所有用 vuex 管理的组件中都多了一个属性 $store, 它就是一个 store 对象;它的属性如下:
state: 注册的 state 对象 getters: 注册的 getters 对象 方法:dispatch(actionName, data): 分发调用 action
main.js 中映射的代码如下:
import store from './store'
new Vue({
el: '#app',
render: h => h(App),
router,
store //映射store对象
})
3.8 在任意组件中使用
3.8.1 通过 $store
对象调用
备注:users 是模块名称
// 调用actions里面的方法
this.$store.dispatch('add')
// 如果是模块管理
this.$store.dispatch('users/add')
// 获取 state
this.$store.state.count
// 如果是模块管理
this.$store.state.users.count
// 获取getters
this.$store.getters.evenOdd
// 如果是模块管理
this.$store.getters["users/evenOdd"]
3.8.2 引入 mapState mapGetters mapActions 映射函数
引入
import {mapState,mapGetters,mapActions} from 'vuex'
调用方法
// 调用方法: 必须在methods中
methods:{
...mapActions(['getAddress', 'getFoodTypes']),
// 如果是模块管理
...mapActions('users',['getAddress', 'getFoodTypes']),
}
获取state,必须在 computed 中
computed: {
...mapState(['count', 'num']),
// 如果是模块管理
...mapState('users', {
count: state => state.count,
num: state => state.num,
}),
}
获取 getters,必须在 computed 中
computed: {
// 获取getters
...mapGetters(['evenorOdd'])
// 如果是模块管理
...mapGetters('users', ['evenOdd'])
}
3.8.2 调用actions中方法
在computed中声明注册mapState
或者mapGetters
// ...mapState(['address', 'foodtypes']) 等同于this.$store.state.address
// ...mapGetters(['evenorOdd']) 等同于this.$store.getters.evenorOdd
使用
mounted() {
// 2. 直接调用
//根据经纬度获取当前的的地址信息
this.getAddress();
//获取食物分类列表
this.getFoodTypes();
},