vuex详情
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
类似一个大管家,而且还是响应式的。
安装vueX插件
npm install vuex --save
新建如图目录,避免代码都写到main.js里面
vuex与路由引入方式一样
index.js
import Vue from 'vue'
import Vuex from 'vuex'
//安装插件
Vue.use(Vuex)
//创建对象 Vuex里面有一个Store的属性,这里的Store首字母大写,里面放的东西固定
const store = new Vuex.Store({
//保存状态用的,其他页面就可以共享这个状态了
state: {
counter: 10000
},
//定义一些方法
mutations: {
//默认有个参数state
increament(state) {
state.counter++
},
decrement(state) {
state.counter--
}
},
actions: {
},
getters: {
},
modules: {
}
})
//导出store对象
export default store
注意
使用方法与router差不多,挂载到main.js里面,并且要在new Vue中引入,不引入会报如下错,
此时我们就可以在多个组件中拿到我们想要的公共内容了
通过这句话拿到我们想要的值
<h2>{{$store.state.counter}}</h2>
mutations的使用
他的作用是对state的数据改变,是响应式的,改变了数值,多个页面都会变化,
使用mutations修改state的值的方法
1.普通用法
首先在index.js文件中
//定义一些方法
//状态更新的唯一方法
mutations: {
//默认有个参数state
increament(state) {
state.counter++
},
}
在APP.vue中使用
首先
methods: {
addition(){
this.$store.commit('increament')
},
然后
<div>{{$store.state.counter}}</div>
<button @click="addition">+</button>
这样最简单的方法就完事了。
2.传参使用
App.vue中,首先
methods: {
addition(){
this.$store.commit('increament')
},
subtraction(){
this.$store.commit('decrement')
},
addCount(count){
//payload:负载
//通过mutation更新数据的时候,有可能我们希望携带一些额外的参数,
//参数被称为是mutation的载荷(Payload)
//如果我们需要传递很多参数,我们通常会以对象的形式传递,也就是说payload是一个对象
//-------------------
//普通的一种提交风格
this.$store.commit('incrementCount',count)
//特殊的一种提交风格
this.$store.commit({
//事件类型
type:'incrementCount',
payload
})
},
//点击添加学生
addStudent(){
const stu ={id:118,name:'yyyy',age:44}
this.$store.commit('addStudent',stu)
},
//点击修改信息
updataInfo(){
this.$store.commit('updataInfo')
}
}
}
然后
<div id="app">
<h2>------App内容:info对象的内容是否为响应式的------</h2>
<h2>{{$store.state.info}}</h2>
<button @click="updataInfo">修改信息</button>
<h2>--传参数的情况-------</h2>
<h2>{{$store.getters.moreAgeStu(40)}}</h2>
<h2>------APP内容 state与mutations用法--------</h2>
<h2>{{message}}</h2>
<div>{{$store.state.counter}}</div>
<button @click="addition">+</button>
<button @click="subtraction">-</button>
<button @click="addCount(5)">+5</button>
<button @click="addCount(10)">+10</button>
<button @click="addStudent">添加学生</button>
index.js文件中
mutations: {
//默认有个参数state
increament(state) {
state.counter++
},
decrement(state) {
state.counter--
},
incrementCount(state, count) {
//第一种提交方式 只打印数字
console.log(count);
state.counter += count
//第二种提交方式,打印一个对象,将上列第二个参数改为payload
state.counter += payload.count
},
//点击添加学生
addStudent(state, stu) {
state.students.push(stu)
},
//点击修改信息
updataInfo(state) {
state.info.name = 'coderwhy',
//当我们想加属性时,是不行的,不会在页面加入
// state.info['address']='洛杉矶'
//但这样就是响应式了,界面会发生相应变化。通过数组索引修改,不是响应式的
Vue.set(state.info, "address", '洛杉矶')
//delete 删属性也不是响应式的
//delete state.info.age
//下面这种方式就是响应式的了
Vue.delete(state.info, 'age')
}
},
官方在文档中推荐mutations变量名同意(APP.vue中与index.js中)
经常在store文件夹下定义一个mutations.type.js文件
mutations.type.js
export const INCREMENT = 'increment'
//只有export default 的导出方式才能用import方式导入
//普通导入只能使用import {INCREMENT}的方式导入
index.js文件中
import {
INCREMENT
} from './mutations-types'
[INCREMENT](state) {
state.counter++
},
App.js中
addition(){
this.$store.commit('INCREMENT')
},
Devtools就和油猴差不多,是个插件,可以监测vue的改变
如果直接修改State,则监听不到devtools
App.vue
<template>
<div id="app">
<h2>------APP内容--------</h2>
<h2>{{message}}</h2>
<div>{{$store.state.counter}}</div>
<button @click="addition">+</button>
<button @click="subtraction">-</button>
<h2>--------组件内容----------</h2>
<Hello-vuex :counter="counter"/>
</div>
</template>
<script>
import HelloVuex from '@/components/hellowvuex.vue'
export default {
name: 'App',
components: {
HelloVuex
},
data () {
return {
message:'我是App组件',
counter:0
}
},
//定义方法,这里的内容注意怎么写
methods: {
addition(){
this.$store.commit('increament')
},
subtraction(){
this.$store.commit('decrement')
}
}
}
</script>
<style>
</style>
Getters的基本使用
有时候,我们需要从store中获取一些state变异后的状态。(只会对数据经行加工,不会改变stare原始数据)
vuex-actions的用法
通常情况下,Vuex要求我们Mutations中的方法必须是同步方法。
主要的原因是我们使用Devtools时,可以devtools可以帮助我们捕捉mutation的快照。
但是如果操作是异步的,那么devtool将不能很好的追踪这个操作什么时候被完成。
如果异步写在mutations里面
我们就得借助action来完成异步操作
APP.vue
<h2>------App内容:modules里面的内容用法------</h2>
<h2>{{$store.state.a.name}}</h2>
<button @click="Updatename">修改名字</button>
<h2>{{$store.getters.fullName}}</h2>
<h2>{{$store.getters.fullName2}}</h2>
<h2>{{$store.getters.fullName3}}</h2>
<button @click="asyncUpdataName">异步修改名字</button>
APP.vue里的methods
updataInfo(){
//
//this.$store.commit('updataInfo')
//调用actions里面的方法,通过dispatch
// this.$store.dispatch('aUpdataInfo',{
// message:"我是携带的信息",
// success:()=>{
// console.log('里面的已经完成了');
// }
// })
//可以这样写,代码更好看
this.$store.dispatch('aUpdataInfo',"我是携带的信息")
.then(res=>{
console.log('里面完成了提交');
console.log(res);
})
},
Updatename(){
this.$store.commit('updateName','lisi')
},
asyncUpdataName(){
this.$store.dispatch('aUpdataName')
}
moduleA.js
export default {
state: {
name: "hanxiaolei"
},
mutations: {
updateName(state, payload) {
state.name = payload
}
},
actions: {
aUpdataName(context) {
console.log(context);
setTimeout(() => {
context.commit('updateName', 'wangwu')
}, 1000);
}
},
getters: {
fullName(state) {
return state.name += '11111'
},
fullName2(state, getters) {
return getters.fullName + "222222"
},
fullName3(state, getters, rootState) {
return getters.fullName2 + rootState.counter
}
}
actions.js文件
export default {
//context的意思是上下文的意思,相当于store
// aUpdataInfo(context, payload) {
// console.log(payload.message);
// payload.success()
// setTimeout(() => {
// context.commit('updataInfo')
// }, 1000)
// }
//这样写,代码更好看
aUpdataInfo(context, payload) {
return new Promise((resolve, reject) => {
setTimeout(() => {
context.commit('updataInfo')
console.log(payload);
resolve("11111111")
}, 1000)
})
},
}
将store分成模块
我们可以把vuex里面的五个属性按目录分开写,方便管理