一 初识Vuex
Vuex是vue官方推出的一款插件,采用“集中式存储“管理所有组件的状态(其实就是使数据共享)
1. vuex安装
npm install vuex
1. State单一状态树
单一状态树是指Vuex将所有的状态(数据)都放在一个store中,便于管理和维护,而不是把不同的数据放在不同的store中,容易让人混淆
二 vuex 模块
- /src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
//存放一些数据(状态)
state: {
//在state中定义的数据是响应式的,数据改变页面会马上改变
counter: 1000,
stu: [
{id:11,age:30},
{id:17,age:50},
{id:14,age:20}
],
info: {
name: 'kobe',
age: 50
}
},
//存放改变数据的方法,官方推荐改变数据时用mutations中的方法来实现,而不是直接修改数据
//同步操作
mutations: {
increment(state){
state.counter++
},
decrement(state){
state.counter--
},
//参数被称作mutations的载荷,多参数可以传一个对象
incrementCount(state,payload){
//普通的提交
//state.counter += payload
//特殊的提交
state.counter += payload.count
},
addStudent(state,stu){
state.stu.push(stu)
},
updateInfo(state){
//state.info.name = 'woshishui' //数据在state中,响应式改变
//state.info['address'] = 'china' //数据不在state中,不会响应式改变
//Vue.set(state.info, 'address', 'china')//用的set 响应式改变
//delete state.info.age //非响应式
Vue.delete(state.info, 'age') //响应式
}
},
//异步操作 修改数据还是得调用mutations中的方法
actions: {
/* aUpdateInfo(context,payload){
setTimeout(()=>{
context.commit('updateInfo')
console.log(payload)
},1000)
}*/
aUpdateInfo(context,payload) {
return new Promise((resolve,reject) => {
setTimeout(() => {
context.commit('updateInfo')
console.log(payload)
resolve('111')
},1000)
})
}
},
//数据筛选和数据变换
getters: {
doubleCn(state){
return state.counter * state.counter;
},
stuFilter(state){
return state.stu.filter(s=> s.age>=30)
},
//第一个参数一定是state 第二个参数一定是getters
len(state,get){
return get.stuFilter.length;
},
//传参写法
studentFilter(state){
/*return function(age){
return state.stu.filter(s=>s.age>=age)
}*/
//箭头函数写法
return age => {return state.stu.filter(s => s.age >= age)}
}
},
//模块,用于把一些数据分离出来,使结构更清晰,
//编译时会将modules中的内容加载到state中
modules: {
a: {
state: {
name: 'zan'
},
mutations: {
updateName(state, payload){
state.name = payload
}
},
//modules中的action只能对modules中的mutations进行调用
actions:{},
getters:{
fullName(state){
return state.name + '1111'
},
fullName2(state, getters){
return getters.fullName + '222'
},
//获得跟内的数据
fullName3(state, getters, rootState){
return getters.fullName2 + rootState.counter
}
}
}
}
})
export default store
- src/main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
- src/App.vue
<template>
<div>
<h1>全局变量{{$store.state.counter}}</h1>
<button @click="incre">+</button>
<button @click="decre">-</button>
<h1>getters double {{$store.getters.doubleCn}}</h1>
<h1>getters filter {{$store.getters.stuFilter}}</h1>
<h1>getters length {{$store.getters.len}}</h1>
<h1>getters params {{$store.getters.studentFilter(50)}}</h1>
<button @click="addCount(10)">addCount</button>
<button @click="addStudent()">添加数据</button>
<button @click="updateInfo">{{$store.state.info}}</button>
<h1>=============modules=================</h1>
<h2>{{$store.state.a.name}}</h2>
<button @click="updateName">修改名字</button>
<!--modules中getters调用和平常的一样-->
<h2>{{$store.getters.fullName}}</h2>
<h2>{{$store.getters.fullName2}}</h2>
<h2>{{$store.getters.fullName3}}</h2>
</div>
</template>
<!---->
<script>
export default {
name: 'App',
//封装mutations中的方法
methods: {
incre(){
this.$store.commit('increment')
},
decre(){
this.$store.commit('decrement')
},
addCount(count){
//1. 普通的提交封装,传回去的是普通数据类型
//this.$store.commit('incrementCount',count)
//2. 特殊的提交封装,传回去的是对象
this.$store.commit({
type: 'incrementCount',
count
})
},
addStudent(){
const stu={id:4454,age:100}
this.$store.commit('addStudent',stu)
},
updateInfo(){
//同步操作
//this.$store.commit('updateInfo')
//异步操作
this.$store.dispatch('aUpdateInfo', 'payload')
.then(res => {
console.log('里面完成了提交');
console.log(res);
})
},
updateName(){
this.$store.commit('updateName','newName')
}
}
}
</script>
<style>
</style>
三 vuex 模块分布式写法
- /src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import moduleA from './modules/moduleA'
Vue.use(Vuex)
const state ={
count:100,
students:[
{id:100,name:'kobe',age:30},
{id:200,name:'james',age:32},
{id:300,name:'curry',age:31},
],
info:{
name:'kobe',
age:19
}
}
const store = new Vuex.Store({
state,
mutations,
actions,
getters,
modules:{
a:moduleA
},
})
export default store
- /src/store/mutations.js
export default {
increment(state){
state.count++
},
decrement(state){
state.count--
},
//普通提交的封装 传入的是具体数字
/* incrementCount(state,count){
state.count += count
},*/
//特殊提交的封装 传入的是对象
incrementCount(state,payload){
state.count +=payload.count
},
addStudent(state, data){
state.students.push(data)
},
updateInfo(state){
//state.info.name = 'james' 修改已有的数据是响应式的
//state.info['address'] = 'LA' 添加未有的数据不是响应式的
//Vue.set(state.info,'address','LA') //响应式
//delete state.info.age 非响应式
Vue.delete(state.info, 'age') //响应式
//或者用响应式方法 push pop shift unshift splice 等
}
}
- /src/store/getters.js
export default{
powerCount(state){
return state.count * state.count
},
more20stu(state){
return state.students.filter(s => s.age >20)
},
len(state,getters){//可以有第二个参数拿其他getters
return getters.more20stu.length
},
moreAge(state){//getters里的方法只能有两个参数,不接收第三个参数
return age => {return state.students.filter(s => s.age >age)}
},
fullName1(state){
return state.a.name + 'root中的name'
},
}
- /src/store/actions.js
export default {
aUpdateInfo(context, payload){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
context.commit('updateInfo')
console.log(payload);
resolve('里面异步操作')
},1000)
})
}
}
- /src/store/modules/moduleA.js
export default {
state:{
name:'wo'
},
mutations:{
updateName(state,payload){
state.name = payload
}
},
getters:{
fullName(state,getters){
return getters.fullName1 + '模块里的name'
},//可以调用root中的getters
fullName3(state,getters,rootState){
//模块中的getters方法可以有第三个参数
return getters.fullName + rootState.count
}
},
actions:{
//模块actions中context指向本模块 其中封装有getters rootGetters
//rootState state
aUpdateName(context) {
setTimeout(()=>{
context.commit('updateName','wangwu')
},1000)
}
}
}