vuex和单纯的全局对象有两点不同:
- vuex的状态存储是响应式的:store中的状态发生变化响应的组件也会发生变化。
- 不能直接改变store中的状态:只能通过commit mutation 改变。
vuex的使用
- 安装
npm install vuex --save
- 使用:确保全局下载过Vue,并且引用,
import vuex from 'vuex'
Vue.use(vuex)
- 创建第一个store
let store = new store({
state:{
count:0
},
mutation:{
increment(state){
state.count++
}
}
})
4.在页面上显示数据,state(辅助函数mapState),mutation(辅助函数mapMutation),getters(辅助函数mapGetters)
第一步,创建store.js
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
let store = new vuex.Store({
state:{
count:0,
todos:[
{id:1,text:'第一条todo',done:true},
{id:2,text:'第二条todo',done:false},
]
},
getters:{
todoDone(state){
return state.todo.filter(todo =>todo.done)
}
},
mutations:{
increment (state,payload) {
state.count += payload.amount
},
decrement(state,payload){
state.count -= payload.amount
}
},
actions:{
increment(context,payload){
debugger
console.log(context,payload);
context.commit('increment',payload)
},
//还可以以解构赋值的方式来显示参数,直接拿到commit方法,不用context.commit
decrement({commit},payload){
commit('decrement',payload)
}
}
});
export default store;
第二步,将store挂载到vue中,这样vue根实例及其每个子组件都可以直接使用store
import store from './store.js'
new Vue({
el: '#app',
store,
render: h => h(App)
})
第三步,在App.vue文件中显示,并且加减数据。
<template>
<div id="app">
{{$store.state.count}}-{{count1}}
<!--这里两种方法都可以显示出来-->
<button @click="submit">增加</button>
<button @click="reduce">减少</button>
<hr/>
<ul>
<li v-for='item in todo' :key="item.id">
<span>{{item.id}}</span>
<span>{{item.text}}</span>
<span>{{item.done}}</span>
</li>
</ul>
</div>
</template>
<script>
import {mapState,mapGetters} from 'vuex'
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App',
}
},
computed:{
...mapState({
count1:'count'
}),
...mapGetters({
todo:'doneTodos'
})
},
methods:{
submit(){
//写法1:可以直接数字10,然后store.js中直接加数字10就可以
//写法2:可以传一个对象{amount:10},然后调用对象的amount就行。
this.$store.commit('increment',{amount:10});
},
reduce(){
this.$store.commit('decrement',{amount:10})
},
//actions第一种:不用辅助函数mapActions
/*actionAdd(){
//以载荷形式分发
this.$store.dispatch('increment',{amount:10});
},
actionReduce(){
//以对象形式分发
this.$store.dispatch({
type:'decrement',
amount:20
})
},*/
//actions第二种,使用辅助函数mapActions,重命名,调用的时候在template中的@click传参数
...mapActions({
actionAdd : 'increment',
actionReduce : 'decrement'
}),
}
}
</script>
- module使用方法:当store对象变得非常大,非常臃肿的时候,这时候可以使用modules来分割成模块,方便管理与维护
- 第一种:直接在一个store.js文件中写入好几个对象,然后在modules中注册。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
- 第二种方法:没个模块可以写在一个js文件中,然后倒入到store.js中
首先moduleA.js文件:
export let moduleA = {
state:{
numA:10
},
mutations:{},
actions:{},
getters:{}
}
其次moduleB.js文件中:
let moduleB = {
state:{
numB:10
},
mutations:{},
actions:{},
getters:{}
}
export default moduleB;
然后在store.js中统一导入就可以使用了:
import {moduleA as a}from './moduleA.js'
import moduleB from './moduleB.js'
console.log(a)
let store = new vuex.Store({
...
modules:{
a:a,
b:moduleB
}
})
这里稍微简单总结一下:export和export default的使用区别
- export 可以倒出一赋值语句,如:
export let moduleA = {}
,但是在导入的时候变量名得用{}包起来,如:import {moduleA as a}from './moduleA.js'
,也可以重命名。 - export default 一个对象的时候可以先定义对象
let moduleB = {}
,然后export default moduleB;
;或者export default {}
就行,然后导入的时候命名import moduleB from './moduleB.js'
网友评论