Vuex是全局状态,数据管理系统。在兄弟组件多页面用到一个数组,在多个组件中数据来回传递会非常复杂且难以维护。所以就有了Vuex (所有文字及代码纯手打,如果单词错了。。。大概是值得原谅的吧......)
Vuex一个可分为五个模块
state 是仓库模块,所有的数据都在这个模块中存放。
mutations 操作state的唯一的合法方法。虽然操作繁琐,但是每次操作都会得最新数据。这个数据是实时更新的。
actions 准许异步操作state的值。但是操作方法还是通过调用mutations中的方法再去操作state中的值
getter 相当于是state的专属计算属性
modules 所有的数据都放在state中会显得很乱,不易读。现在允许你把数据分成模块使用(登陆,用户信息之类的)
state的使用方法
可以在computed中进行监听使用用函数直接return出想要使用的值,但是vuex提供了更方便的辅助函数。
//通过函数进行return 使用。在HTML结构中 {{getData}} 就可以啦
computed:{
getData(){
return return this.$store.state.data
}
}
//通过辅助函数 把需要的数据放到数组中实现监听,在页面中直接使用 {{msg}}
import {mapState} from "vuex"
computed:{
...mapState(['msg','data','flag'])
}
//也可以在HTML中直接使用
// <p>{{$store.state.msg}}</p> 这是不需要引入的直接在页面中获取即可哦
mutations的使用方法
在其他页面调用mutations中的语法是 this.$store.commit('changeAge',10) vuex也提供了方便的辅助函数,mutations中修改数据也需要遵循Vue中的响应规则(数组,对象修改后不更新的问题),在mutations中不要写异步操作。这是规则
//需要定义触发函数以methods中举例
methods:{
getAge(){//触发getAge方法以后就可以执行mutations中的changgeAge方法了
this.$store.commit('changeAge',10)
}
}
//辅助函数需要从vuex中引入模块 mapMutations
import { mapMutations } from "vuex"
methods:{
...mapMutations(['changeName','changeAge']),//取出mutations中需要用到的方法
getAge(){
this.changeAge(10)//这里传入参数10
this.changeAge({num:10})//也可以传入对象哦
}
}
//在store中mutations对象
mutations:{
changeAge(state,{num}){
state.state.age=num
}
}
actions 用来操作mutations的,可以异步操作
//在页面中直接调用
this.$store.dispatch("actions中的函数名",参数)
//使用辅助函数 mapActions
import { mapActions } from "vuex"
methods:{
...mapActions(["addCity"])
upCity(){
this.addCity({'火星'})
}
}
//在store.js的actions对象
actions:{
addCity(context,{city}){
setTimeout(()=>{//这里模拟网络请求
context.commit("mutations中的方法",参数)//这个调用就跟其他的一样了
},1000)
}
}
getter 使用的方法跟其他的差不多。都有直接使用和辅助函数。
//store.js定义getter对象,在对象中定义方法
getter:{
getterData(state){//默认接收到state对象获取所有的数据
return state.msg+'你好'
}
}
//在其他页面中使用 {{ $store.getter.getterData }}
//用辅助函数 mapGetter
import { mapGetter } from "vuex"
computed:{
...mapGetter(["getterData"])//直接在页面中使用即可{{getterData}}
}
modules 模块化 把你想归为一类的数据放在一个JS文件内。这个相当于是一个小的store。如果你需要也可以把公共的actions,mutations,getters提出去。再导入。替换原来的位置即可
//单独创建一个文件来承载不同分区的数据
const city={
//加上这个会让这个对象形成私有化,如果不加会默认和其他的模块编译在一起
namespaced:true,
state:{
name:"火星"
},
mutations:{
setName(state,name){
state.name=name
}
},
actions:{//在这里可以异步操作,但是还是操作mutations老修改state中的值
asyncSetName(context,name){
context.commit('setName',name)
}
}
}
export default city //最后把这个对象倒出
在store.js中引入这个模块,放到modules中就可以正常使用了
//store.js
import Vue from "vue"
import Vuex from "vuex"
import city from "./city"
Vue.use(Vuex)
export default new Vuex.Store({
state:{},
gettes:{}
mutations:{},
actions:{},
modules:{
//这是引入的模块,也可以直接在这里面写。但是都分模块了。还在modules里面写的话就有点蛋疼了
city,
},
})
接下来看下在其他页面的用法吧
//辅助函数搞起来
import {mapState,mapMutations,mapActions,mapGetter} from "vuex"
methods:{
...mapMutations('city',['setName']),//在这里提取仓库,然后数组内提取该仓库的函数
...mapActions('city',['asyncSetName'])
myClick(){
//这是直接调用不通过辅助函数,因为加了‘namespaced:true’所以会形成私有的。在打印
//this.$store._mutations这个对象中可以看到函数名,就是加了仓库名的前缀
this.$store.commit('city/setName','水星')
//这是通过辅助函数来调用
this.setName('水星')
//上面两个调用是同步的,下面来看看异步的吧
//这是不通过辅助函数调用,跟同步的基本相同
this.$store.dispatch('city/asyncSetName','金星')
//下面通过辅助函数来调用,超简单
this.asyncSetName('金星')
}
},
copmuted:{
//通过辅助函数获取后可以直接在页面中使用“name”这个变量名就可以了
...mapState('city',['name'])
//辅助函数获取指定模块中的gettet属性
...mapGetter('city',['名字'])
}
在HTML中的使用
<!-- 在HTML结构中使用仓库中的数据 -->
<!-- 这是指定city模块中的gettet属性取数据因为加了斜线所以需要用中括号处理 -->
<p>{{$store.getter['city/name']}}</p>
<!--这里是通过辅助函数获取的-->
<p>{{$store.getter['city/name'}}</p>
操作某一模块内的actions和mutations也遵循了就近查找的原则,但是他不会向上查找需要配置才会向上查找。那么现在就看看怎么去直接操作全局的actions和mutations吧
//这里我写一个city组件中怎么写
const city={
stete:{
name:'北京'
},
mutations:{
changeName(state,name){
state.name=name
}
},
actions:{
setName(context,str){
//这里调用的时候加上第三个参数{root:true},就会默认去全局查找。
不会在自己这里找这个方法了
context.commit('changeName',str,{root:true})
//如果第二个参数没有就传null
}
//调用actions方法还是正常的调用,只是访问方法的时候去全局访问了
}
}
export defaule city
//现在看下store主文件怎么写
import Vue from "vue"
import Vuex from "vuex"
import city from "./city"
Vue.use(Vuex)
export default new Vuex.Store({
state:{
name:'Aaron'
},
mutations:{
changeName(state,name){//这里是全局的changheName方法
state.name=name
}
}
})
严格模式:当你开启后如果操作state的方式不是通过mutations提交的就会抛出错误,有幸能浪费。在开发环境开启。上线关闭就好啦 strict:process.env.NODE_ENV !== 'PRODUCTION'配上这个默认在开发环境开启,上线后就是关闭。不小心忘了也没关系
开发环境:development
发布环境:production
export defaule new Vuex.Store({
staict:true //只需要在配置store的时候加上它就会开启严格模式。
//但是他是耗费性能的。如果大家都遵守mutations操作state数据是不需要开启的
})
如果是表单中需要用到双向数据绑定的话,就无法遵守只通过mutations操作state中的值了。我们的游大神也想到了
第一种:先用v-bian进行数据获取,再给标签添加input事件,在事件中调用mutations中的函数就可以了,这种是自己写的。游大神提供的方法在下面
第二种:
//有标签中的v-model来执行message里面的方法
computed:{
...maoState(['msg'])
message:{
get(){
return this.msg
},
set(val){//检测message如果是修改值就调用set方法
return this.changeMsg(val)//这是是辅助函数取出的mutations中的方法
}
}
}
好吧暂时这么多了。学到更多再回来补充