一、组件内的状态管理流程
二、什么是Vuex
- Vuex 是专门为 Vue.js 设计的状态管理库
- 它采用集中式的方式存储需要共享的数据
- 从使用角度,它就是一个 JavaScript 库
- 它的作用是进行状态管理,解决复杂组件通信,数据共享
三、Vuex工作流程图
四、基本代码结构
五、state
<template>
<div id="app">
<h1>Vuex - Demo</h1>
<!--直接获取store里的state-->
<!--count:{{ $store.state.count }} <br>
msg: {{ $store.state.msg }}-->
<!--通过mapState方法获取-->
<!--count:{{ count }} <br>
msg: {{ msg }} -->
count:{{ num }} <br>
msg: {{ message }}
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
computed: {
// count: state => state.count
// ...mapState(['count', 'msg'])
...mapState({ num: 'count', message: 'msg' }), // 也可用用对象 属性名的形式
}
}
</script>
六、Getter
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production',
state: {
count: 0,
msg: 'Hello Vuex'
},
getters: {
reverseMsg (state) { // 数字反转
return state.msg.split('').reverse().join('')
}
},
mutations: {
},
actions: {
},
modules: {
}
})
<h2>Getter</h2>
reverseMsg: {{ $store.getters.reverseMsg }}
还可以用mapGetters方法
<h2>Getter</h2>
<!-- reverseMsg: {{ $store.getters.reverseMsg }} -->
reverseMsg: {{ reverseMsg }}
export default {
computed: {
...mapGetters(['reverseMsg'])
},
}
七、Mutation
<h2>Mutation</h2>
<button @click="$store.commit('increate', 2)">Mutation</button>
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production',
state: {
count: 0,
msg: 'Hello Vuex'
},
getters: {
},
mutations: {
increate (state, payload) {
state.count += payload
}
},
actions: {
},
modules: {
}
})
还可以使用mapMutations
<button @click="increate(3)">Mutation</button>
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
},
methods: {
...mapMutations(['increate']),
}
}
</script>
八、Action
<h2>Action</h2>
<button @click="$store.dispatch('increateAsync', 5)">Action</button>
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production',
state: {
count: 0,
msg: 'Hello Vuex'
},
getters: {},
mutations: {
increate (state, payload) {
state.count += payload
}
},
actions: {
increateAsync (context, payload) {
setTimeout(() => {
context.commit('increate', payload)
}, 2000)
}
},
modules: {}
})
也可以使用mapActions
<button @click="increateAsync(6)">Action</button>
import { mapActions } from 'vuex'
export default {
computed: {
},
methods: {
...mapActions(['increate']),
}
}
九、Module
<h2>Module</h2>
<!-- products: {{ $store.state.products.products }} <br>
<button @click="$store.commit('setProducts', [])">Mutation</button> -->
products: {{ products }} <br>
<button @click="setProducts([])">Mutation</button> <!--变成空数组-->
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
},
methods: {
...mapMutations('products', ['setProducts']) // 第一个参数是文件名,第二个参数是调用方法
}
}
</script>
products.js
const state = {
products: [
{ id: 1, title: 'iPhone 11', price: 8000 },
{ id: 2, title: 'iPhone 12', price: 10000 }
]
}
const getters = {}
const mutations = {
setProducts (state, payload) {
state.products = payload
}
}
const actions = {}
export default {
namespaced: true, // vuex中的store分模块管理,需要在store的index.js中引入各个模块,
//为了解决不同模块命名冲突的问题,将不同模块的namespaced:true,之后在不同页面中引入getter、actions、mutations时,
//需要加上所属的模块名 this.$store.commit("userInfo/setUserInfo",userInfo)
state,
getters,
mutations,
actions
}
十、严格模式
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production', // 生产模式的时候关掉
state: {
count: 0,
msg: 'Hello Vuex'
},
getters: {},
mutations: {
increate (state, payload) {
state.count += payload
}
},
actions: {
increateAsync (context, payload) {
setTimeout(() => {
context.commit('increate', payload)
}, 2000)
}
},
modules: {}
})
直接修改msg,虽然能够修改,但会抛出错误
<h2>strict</h2>
<button @click="$store.state.msg = 'Lagou'">strict</button>
十二、模拟Vuex-Store类
let _Vue = null
class Store {
constructor (options) {
const {
state = {},
getters = {},
mutations = {},
actions = {}
} = options
this.state = _Vue.observable(state)
this.getters = Object.create(null)
Object.keys(getters).forEach(key => {
Object.defineProperty(this.getters, key, {
get: () => getters[key](state)
})
})
this._mutations = mutations
this._actions = actions
}
commit (type, payload) {
this._mutations[type](this.state, payload)
}
dispatch (type, payload) {
this._actions[type](this, payload)
}
}
function install (Vue) {
_Vue = Vue
_Vue.mixin({
beforeCreate () {
if (this.$options.store) {
_Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install
}