Vuex 状态管理模式
采用集中式存储管理应用所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
多个组件共享的变量全部存储在一个对象里面
放在顶层的Vue实例中,其他组件可以使用
管理什么状态
用户的登录状态、用户的名称、用户的头像、地理位置
商品的收藏、购物车的物品
单界面状态管理
state: 就是状态,(可以当做data中的属性)
View : 视图层,可以针对State 的变化,显示不同的信息
Actions: 这里面是用户的个中操作,点击,出入等,会导致状态的改变
<template>
<div id="app">
<h2>{{message}}</h2>
<div>当前计数:{{counter}}</div>
<button @click="counter++">+1</button>
<button @click="counter--">-1</button>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
message: '你好我是APP组件',
counter: 0
}
}
}
</script>
<style>
</style>
多界面管理
多页面管理图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i3J5LbuB-1606716314227)(C:\Users\ZR\Desktop\VUE\image-20201125103528504.png)]
vuex 挂载
在src目录下创建store /index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
counter: 1000
},
mutations: {
inc(state){
state.counter++;
},
dec(state){
state.counter--;
}
}
})
export default store;
在组件中使用
<template>
<div id="app">
<h2>{{message}}</h2>
<div>当前计数:{{$store.state.counter}}</div> // 使用公共的Vuex中属性
<button @click="add">+1</button>
<button @click="sub">-1</button>
<hello-vux></hello-vux>
</div>
</template>
<script>
import HelloVux from "./components/helloVux";
export default {
name: 'App',
components: {HelloVux},
data(){
return{
message: '你好我是APP组件',
counter: 0
}
},
methods: {
add(){
this.$store.commit('inc') //提交,使用commit 传入VUex 中注册的方法
},
sub(){
this.$store.commit('dec')
}
}
}
</script>
<style>
</style>
Vuex 核心
State 单一状态树
单一store管理应用层级的所有状态
Getters
类似于计算属性
经过变化后在反馈
getter 中可以传入store的 state和getter ,但是外部传入参数的时候,可以返回一个函数,在函数中设置参数
getters:{
getStudent(state){
return state.students.filter(s=>s.age>20)
},
getStudentlength(state,getters){
return getters.getStudent.length
},
moreAgestu(state){
return function (age) {
return state.students.filter(s => s.age>age);
}
}
},
组件中带参调用的方法
<h2>{{$store.getters.moreAgestu(20)}}</h2>
Mutation
事件类型(type)
回调函数
通过mutation 更新数据的时候,可以携带一些参数
参数称为mutation的载荷(payload)
<button @click="add1(5)">+5</button>
<button @click="addstu">添加学生</button>
add1(count){
this.$store.commit('inc1',count)
},
addstu(){
const stu = {id: 12, name:'wee',age: 56};
this.$store.commit('addstu',stu);
}
inc1(state,count){
state.counter += count;
},
addstu(state,stu){
state.students.push(stu);
}
提交风格
通过type 这种风格提交,在vuex 中接收的时候是以载荷(payload),是一个对象
add1(count){
// this.$store.commit('inc1',count)
this.$store.commit({
type: 'inc1',
count
})
},
inc1(state,payload){
state.counter += payload.count;
},
响应规则
提前在state中定义,这些属性都会被加入到响应系统中,响应式系统会监听属性的变化,当属性变化时候回通知所有用到该属性所在的页面
splice 和vue.set()是响应式的
在mutation里面使用异步操作,devtools无法监听
Vue.set(state.students, 'saddress','洛杉矶' )
Vue.delect(statue.students,'age')
Action
类似Mutation 但是是用来替换Mutation进行异步操作的
还可以传递参数, Active还能返回消息
upd(){
this.$store.dispatch('aupdateInfo')
}
upd(){
// this.$store.dispatch('aupdateInfo')
this.$store
.dispatch('aupdateInfo','我是从参数')
.then(res => {
console.log('里面完成了');
console.log(res);
})
}
actions: {
aupdateInfo(context, payload){
// setTimeout(() => {
// context.commit('update')
// console.log(payload);
// },1000)
return new Promise(((resolve, reject) => {
setTimeout(() => {
context.commit('update')
console.log(payload);
resolve('我执行完了')
},1000)
}))
}
}
modules
模块,应用复杂的时候store对象就可能变得臃肿,Vuex 允许store分割成模块Modules ,每个模块可以由自己的state.
<h2>------------模块-------</h2>
<h6>{{$store.state.a.name}}</h6>
<h6>{{$store.getters.fullname}}</h6>
<h6>{{$store.getters.fullname1}}</h6>
<h6>{{$store.getters.fullname2}}</h6>
<h6>{{$store.getters.fullname3}}</h6>
<button @click="updateA">修改</button>
<button @click="asyupdateA">修改</button>
updateA(){
this.$store.commit('updateA','list');
},
asyupdateA(){
this.$store.dispatch('ayUpdateA')
}
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const moduleA = {
state:{name: '张三'},
mutations: {
updateA(state, payload){
state.name = payload;
}
},
getters: {
fullname(state){
return state.name + '212121';
},
fullname1(state,getters){
return getters.fullname+ '212121';
},
fullname2(state,getters,rootState){
return getters.fullname+ rootState.counter
},
fullname3(state,getters,rootState,rootGetter){
return getters.fullname+ rootState.counter+ rootGetter.getStudent
}
},
actions: {
ayUpdateA(context){
setTimeout((resolve,reject) => {
context.commit('updateA','list')
},1000)
}
}
}
const store = new Vuex.Store({
state: {
counter: 1000,
students:[
{id: 12,name: 'ze',age: 12},
{id: 12,name: 'ze',age: 49},
{id: 12,name: 'ze',age: 14}
],
info: {
name: 'zz',
age: 12
}
},
getters:{
getStudent(state){
return state.students.filter(s=>s.age>10)
},
getStudentlength(state,getters){
return getters.getStudent.length
},
moreAgestu(state){
return function (age) {
return state.students.filter(s => s.age>age);
}
}
},
mutations: {
inc(state){
state.counter++;
},
dec(state){
state.counter--;
},
// inc1(state,count){
// state.counter += count;
// },
inc1(state,payload){
state.counter += payload.count;
},
addstu(state,stu){
state.students.push(stu);
},
update(state){
state.info.name = 'zzzzz';
}
},
actions: {
aupdateInfo(context, payload){
// setTimeout(() => {
// context.commit('update')
// console.log(payload);
// },1000)
return new Promise(((resolve, reject) => {
setTimeout(() => {
context.commit('update')
console.log(payload);
resolve('我执行完了')
},1000)
}))
}
},
modules: {
a: moduleA
}
})
export default store;
fo(context, payload){
// setTimeout(() => {
// context.commit(‘update’)
// console.log(payload);
// },1000)
return new Promise(((resolve, reject) => {
setTimeout(() => {
context.commit(‘update’)
console.log(payload);
resolve(‘我执行完了’)
},1000)
}))
}
},
modules: {
a: moduleA
}
})
export default store;