注: Mutation事件使用commit触发, Actions事件使用dispatch触发
安装
npm install vuex
创建store文件/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let state = {
// 管理所有数据
name: 'default name'
}
let mutations = {
// 如需要修改state, 全部方法集中在这管理
change(state, name){
state.name = name
}
}
let actions = {
// 组件所有的 异步,同步事件在这里处理
change({commit}){
var name = 'ajanuw'
commit('change', name);// 需要修改state.name交更mutations处理
}
}
let getters = {
// 组件需要 state 数据全部在这里请求
getName(state){
return state.name
}
}
// 导出
export default new Vuex.Store({
actions,
getters,
mutations,
state
})
main.js 获取 store
import store from './store/store.js'
new Vue({
store
})
组件内部
<template>
<div id="app">
<p>{{ getName}}</p>
<button @click="change"> change name</button>
</div>
</template>
<script>
import {mapGetters, mapActions} from 'vuex'
export default {
computed: mapGetters([
'getName'
]),
methods: mapActions([
'change'
])
}
</script>
mapState
import {mapGetters, mapActions, mapState} from 'vuex'
computed: mapState({
age: 'age', // 映射 state.age
tody(){// 定义局部数据
return "好日子"
},
storeName(state){// this指向局部
return `${state.name} ${this.name}`
}
}),
render(h){
return (
<p>{ this.age }</p>
<p>{ this.tody }</p>
<p>{ this.storeName }</p>
);
}
dispatch
import {mapState, mapGetters, mapActions} from 'vuex'
export default {
data(){
return {
name: 'ajanuw'
}
},
computed:{
...mapState({
defaultname: 'name',
num: 'num'
})
},
methods:{
hello(msg){
return `hello ${msg}`
},
...mapActions({
// 映射store里面的 action.prop
decrease: 'decrease'
})
}
render(){
const store = this.$store;
return (
<div>
/*methods钩子的的函数*/
<p>{ this.hello('vue vuex jsx') }</p>
/*data钩子里的的state*/
<p>hello {this.name}</p>
/*映射store里面的state*/
<p>{this.defaultname}</p>
/*store.dispatch() 派发事件*/
<button onClick={ ()=>store.dispatch('addnum', 1) } >click延迟一秒+1 => {this.num}</button>
/* 使用mapActions() 映射store的action*/
<button onClick={ ()=> this.decrease(2) } >click延迟一秒-2 => {this.num}</button>
</div>
)
},
}
store
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
let state = {
name: 'default name',
num: 0
}
let mutations = {
addnum(state, n){
state.num += n;
},
decrease(state, n){
state.num -= n;
}
}
let actions = {
addnum(ctx, n){
setTimeout( ()=> ctx.commit('addnum', n), 1000);
},
decrease(ctx, n){
setTimeout( ()=> ctx.commit('decrease', n), 1000);
}
}
let getters = {
}
export default new Vuex.Store({
actions,
getters,
mutations,
state
});
module 模块化
创建模块化store
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
/*
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的
这样使得多个模块能够对同一 mutation 或 action 作出响应。
如果希望你的模块具有更高的封装度和复用性,
你可以通过添加 namespaced: true 的方式使其成为命名空间模块。
当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名
*/
const modelA = {
namespaced: true,
state: {
msg: 'this is modelA',
},
mutations: {},
actions: {
show(ctx){
console.log( ctx.state.msg );
}
},
getters: {}
}
const modelB = {
namespaced: true,
state: {
msg: 'this is modelB',
},
mutations: {},
actions: {
show(ctx){
console.log( ctx.state.msg );
}
},
getters: {}
}
const store = new Vuex.Store({
modules: {
modelA,
modelB
}
});
export default store;
使用
import {mapState, mapGetters, mapActions} from 'vuex';
export default {
data(){
return {}
},
created(){
// 动态注册一个model
this.$store.registerModule('modelC', {
namespaced: true,
state: {
msg: '动态modelC'
}
});
},
methods:{
...mapActions('modelA', {
show: 'show'
})
},
render(){
const store = this.$store;
return (
<div id="app">
<p>hello</p>
<p onClick={()=>store.dispatch('modelA/show')}>modelA => {store.state.modelA.msg}</p>
<p onClick={ ()=>store.dispatch('modelB/show') }>modelB => {store.state.modelB.msg}</p>
</div>
)
},
mounted(){
this.show();
console.log( this.$store.state.modelC.msg );
this.$store.unregisterModule(modelC);
// modelC 已经被卸载,下面的代码将会报错
console.error( this.$store.state.modelC.msg );
}
}