虽然在创建项目的时候我们可以用vue-cli来自动生成Vuex,但是我们不能忘记一些基础知识点,毕竟万丈高楼平地起嘛,
在你想了解一个东西的时候,首先去看官网。官网对于他的介绍这么说的
通俗易懂的解释一遍就是说我们在多个组件共享一条数据的时候,单向数据流的结构性很容易被破坏,Vuex他就好比一个仓库,我们把一些共享的数据放在这个仓库里面,直接从仓库中去取值,不用在各组件之间传来传去。
我们首先从安装开始介绍
第一步:安装
1.1 npm install vuex --save
1.2 创建一个单独的 Store 文件价 在创建一个 index.js文件
1.3 在index.js中创建vuex的实列对象
1.4 导出该对象
1.5 在main.js中引入该对象并且挂在到Vue.prototype的原型上
1.6 将引入的 Store 放在 vue 的实例上
还不会没关系,咱们还要图片教学 把馒头掰碎喂到你嘴巴去
State的使用: (State:驱动应用的数据源,可以理解为他是一个存储数据的一个空间集合,需要存放的数据都放在这里)
你可以直接使用$store.state.仓库中定义的数据名称拿到该属性值
Store 文件下的 index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state:{
// 定义一个 name
name:'孙悟空',
// 定义一个 number
number:13580
}
})
export default store;
拿到值store中state的值
<template>
<div>
<p>我的名字是:{{$store.state.name}}</p>
<p>金箍棒重量:{{$store.state.number}}</p>
</div>
</template>
运行结果:
mutations的使用: (mutations用来修改数据,但是他修改的是同步数据,异步数据的话不能直接在此操作)
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state:{
// 定义一个 name
name:'孙悟空',
// 定义一个 number
number:13580
},
mutations:{
// 定义一个修改数据的方法
changeNumber(state,payload){
state.number += payload
}
// 不传递载荷的情况下,第一个参数为必传参数(state)
changeNum(state){
state.number -= 1000
}
}
})
export default store;
修改App.vue
<template>
<div>
<p>我的名字是:{{$store.state.name}}</p>
<p>金箍棒重量:{{$store.state.number}}斤</p>
<button @click="Changebig(10000)">大大大</button>
<button @click="ChangeSmall">小小小</button>
</div>
</template>
<script>
export default {
name: 'DemoApp',
data() {
return {
};
},
created(){
},
mounted() {
},
methods: {
ChangeSmall(){
this.$store.commit('changeNum')
},
// 修改state中的值我们需要用store中的commit方法将修改的内容提交给mutation不能直接修改 commit 后面接连个参数('函数名',载荷)
Changebig(number){
this.$store.commit('changeNumber',number)
}
},
};
</script>
<style lang="scss" scoped>
</style>
这里说一条重要原则:Mutations里面的函数必须是同步操作,不能包含异步操作!
actions:所有的异步操作都在这里执行完成之后在由 commit 提交到 mutation中
const store = new Vuex.Store({
state:{
// 定义一个 name
name:'孙悟空',
// 定义一个 number
number:13580
},
mutations:{
// 定义一个修改数据的方法,接收两个参数 (state,载荷)
changeNumber(state,payload){
state.number += payload
},
// 不传递载荷的情况下
changeNum(state){
state.number -= 1000
}
},
actions:{
// 定义一个修改数据的异步操作需要传递两个参数(commit,payload)
setNumber(context,payload){
// 异步的操作首先由 dispatch 进行操作 然后通过 mutation 修改 State 中的数据
// 关于参数的定义 可以参考 mutations
setTimeout(()=>{
context.commit('changeNumber',payload)
},2000)
}
}
})
App.vue 修改数据
<template>
<div>
<p>我的名字是:{{$store.state.name}}</p>
<p>金箍棒重量:{{$store.state.number}}斤</p>
<button @click="TimeOver">修改值</button>
<button @click="Changebig(10000)">大大大</button>
<button @click="ChangeSmall">小小小</button>
</div>
</template>
<script>
export default {
name: 'DemoApp',
data() {
return {
};
},
created(){
},
mounted() {
},
methods: {
ChangeSmall(){
this.$store.commit('changeNum')
},
// number就是传递过去的载荷 通过commit来进行修改
Changebig(number){
this.$store.commit('changeNumber',number)
},
// 点击按钮触发 异步修改事件 'setNumber' 首先需要调用 store.dispatch 方法
TimeOver(){
this.$store.dispatch('setNumber', 10000)
}
},
};
</script>
<style lang="scss" scoped>
</style>
Getters:类似与计算属性(computed)它带有缓存,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
import Vue from 'vue'
import Vuex from 'vuex'
// import Cart from './modules/Cart.js'
// import details from './modules/details'
Vue.use(Vuex);
const store = new Vuex.Store({
state:{
// 定义一个 name
name:'孙悟空',
// 定义一个 number
number:13580,
+ todoList:[{id:1,done:true},{id:2,done:true},{id:3,done:false},{id:4,done:false}]
},
mutations:{
// 定义一个修改数据的方法,接收两个参数 (state,载荷)
changeNumber(state,payload){
state.number += payload
},
// 不传递载荷的情况下
changeNum(state){
state.number -= 1000
}
},
actions:{
// 定义一个修改数据的异步操作需要传递两个参数(commit,payload)
setNumber(context,payload){
setTimeout(()=>{
// 异步的操作首先由 dispatch 进行操作 然后通过 mutation 修改 State 中的数据
// 关于参数的定义 可以参考 mutations
context.commit('changeNumber',payload)
},2000)
}
},
+ getters:{
doneTodos:state=>{
// 直接筛选出 State.todoList里面 done属性为true的值
return state.todoList.filter(todo=>todo.done === true)
}
},
})
export default store;
获取属性值的方法
this.$store.getters.方法名称
Getters的作用就好比在特定的页面你需要用到 state 中的数据,但是 state 在多个页面中有用到,若你直接修改 state 则多个页面中的 值都会改变,这个时候你将 getters 函数的形式返回出来,用在需要改变的页面上。这样你 state 中的数据就不会呗污染啦。而且保留了原有的 state 数据。
运行结果
modules:它的主要作用就是对项目中的vuex进行模块化分配,当你的项目足够大的时候,需要用到该属性,中小型项目对该属性运用的需求不是特别高
index.js 文件
import Vue from 'vue'
import Vuex from 'vuex'
// 导入你需要用的模块 Cart.js
import Cart from './modules/Cart.js'
import details from './modules/details'
Vue.use(Vuex);
const store = new Vuex.Store({
// 利用 modules 把导入的模块放进去
modules:{
Cart,
details
}
})
export default store;
Cart.js 文件
const Cart = {
// 加上命名空间 (用来区分你的 modules 文件名称)
namespaced: true,
state:()=>({
// 定义一个 CartList 数据
CartList:[{id:1,name:'Jay'},{id:2,name:'Esony'},{id:3,name:'JJlin'}]
}),
mutations:{
// 定义一个 change 方法
change(state,payload){
state.CartList.forEach(item => {
item.id += payload
});
}
}
}
export default Cart
再调用的时候跟之前没模块化分配的时候差不多,主要是增加了一个命名空间的操作,获取 State 数据
App.vue
<template>
<div>
{{this.$store.state.Cart.CartList}}
</div>
</template>
<script>
export default {
name: 'DemoApp',
data() {
return {
};
},
created(){
},
mounted() {
},
methods: {
},
};
</script>
<style lang="scss" scoped>
</style>
运行结果:
调用 Mutations 方法
<template>
<div>
<button @click="change(10000)">大大大</button>
{{this.$store.state.Cart.CartList}}
</div>
</template>
<script>
export default {
name: 'DemoApp',
data() {
return {
};
},
created(){
},
mounted() {
},
methods: {
change(number){
this.$store.commit('Cart/change',number)
},
},
};
</script>
<style lang="scss" scoped>
</style>
运行结果
其实用法都一样,只需要注意在每个文件中加上 namespaced 调用的时候添加上对应的文件名称就行。
总结:
state : 用来储存数据
mutations:修改 state 中的数据,通过 $store.commit 去调用
Actions: 用来修改异步操作(切记切记),紧张直接去修改 state 中的数据,通过 $store.dispatch 去调用
getters: 类似与计算属性的作用,用来对 state 中的数据进行处理 通过 $store.getters
modules:对每一个vuex进行模块化分配,需要在主文件中先导入,然后引入进去
其实他们对应有各自的辅助函数,可以直接调用分别是 { mapState,mapActions,mapMutations,mapGetters }在vuex中引入,因为本人不太喜欢用辅助函数,所以就不标明啦,需要看的小伙伴可以从百度查找一下,要是各位觉得该文章还满意有帮助到你,可以点赞收藏一下,也可以在底下留言出一期 辅助函数的教学文章。🤭(●'◡'●)