1. vuex 理解
1.1. vuex 是什么
- github 站点: https://github.com/vuejs/vuex
- 在线文档: https://vuex.vuejs.org/zh-cn/
- 简单来说: 对vue 应用中多个组件的共享状态进行集中式的管理(读/写)
1.2. 状态自管理应用
- state: 驱动应用的数据源
- view: 以声明方式将state 映射到视图
- actions: 响应在view 上的用户输入导致的状态变化(包含n 个更新状态的方法)
1.3. 多组件共享状态的问题
- 多个视图依赖于同一状态
- 来自不同视图的行为需要变更同一状态
- 以前的解决办法
a. 将数据以及操作数据的行为都定义在父组件
b. 将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递) - vuex 就是用来解决这个问题的
2. vuex 核心概念和API
2.1. state
-
vuex 管理的状态对象
-
它应该是唯一的
const state = {
xxx: initValue
}
2.2. mutations
- 包含多个直接更新state 的方法(回调函数)的对象
- 谁来触发: action 中的commit(‘mutation 名称’)
- 只能包含同步的代码, 不能写异步代码
const mutations = {
yyy (state, {
data1}) {
// 更新state 的某个属性
}
}
2.3. actions
- 包含多个事件回调函数的对象
- 通过执行: commit()来触发mutation 的调用, 间接更新state
- 谁来触发: 组件中: $store.dispatch(‘action 名称’, data1) // ‘zzz’
- 可以包含异步代码(定时器, ajax)
const actions = {
zzz ({
commit, state}, data1) {
commit('yyy', {
data1})
}
}
2.4. getters
- 包含多个计算属性(get)的对象
- 谁来读取: 组件中: $store.getters.xxx
const getters = {
mmm (state) {
return ...
}
}
2.5. modules
- 包含多个module
- 一个module 是一个store 的配置对象
- 与一个组件(包含有共享数据)对应
2.6. 向外暴露store 对象
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
2.7. 组件中
import {
mapState, mapGetters, mapActions} from 'vuex'
export default {
computed: {
...mapState(['xxx']),
...mapGetters(['mmm']),
}
methods: mapActions(['zzz'])
}
{
{
xxx}} {
{
mmm}} @click="zzz(data)"
2.8. 映射store
import store from './store'
new Vue({
store
})
2.9. store 对象
- 所有用vuex 管理的组件中都多了一个属性$store, 它就是一个store 对象
- 属性:
state: 注册的state 对象
getters: 注册的getters 对象 - 方法:
dispatch(actionName, data)
: 分发调用action
3. demo1: 计数器
3.1. store.js
/**
* vuex 的store 对象模块
*/
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
/*
state 对象
类似于data
*/
const state = {
count: 0 // 初始化状态数据
}
/*
mutations 对象
包含个方法: 能直接更新state
一个方法就是一个mutation
mutation 只能包含更新state 的同步代码, 也不会有逻辑
mutation 由action 触发调用: commit('mutationName')
*/
const mutations = {
INCREMENT(state) {
state.count++
},
DECREMENT (state) {
// ctrl + shift + x
state.count--
}
}
/*
actions 对象
包含个方法: 触发mutation 调用, 间接更新state
一个方法就是一个action
action 中可以有逻辑代码和异步代码
action 由组件来触发调用: this.$store.dispatch('actionName')
*/
const actions = {
increment ({
commit}) {
commit('INCREMENT')
},
decrement ({
commit}) {
commit('DECREMENT')
},
incrementIfOdd ({
commit, state}) {
if(state.count%2===1) {
commit('INCREMENT')
}
},
incrementAsync ({
commit}) {
setTimeout(() => {
commit('INCREMENT')
}, 1000)
}
}
/*
getters 对象
包含多个get 计算计算属性方法
*/
const getters = {
oddOrEven (state) {
return state.count%2===0 ? '偶数' : '奇数'
},
count (state) {
return state.count
}
}
// 向外暴露store 实例对象
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
3.2. main.js
import Vue from 'vue'
import app from './app1.vue'
// import app from './app.vue'
import store from './store'
new Vue({
el: '#app',
render: h => h(app),
store // 所有组件都多个一个属性: $store
})
3.3. app.vue(未优化前)
<template>
<div>
<p>clicked: {
{$store.state.count}} times, count is {
{oddOrEven}}</p>
<button @click="increment">+</button