vuex优点:(1)数据的存取一步到位,不需层层传递;(2)数据的流动非常清晰;(3)存储在Vuex中的数据是响应式的。用大白话说就是可以实现大范围数据共享,尤其是对于非父子关系的组件是非常友好的。
1.下载vuex包(下载时候一定要看自己是vue2还是3,根据自己的版本下载最新的,如果是Vue2,推荐使用vuex@3.6.2)
2.搭建环境
(1)在src目录下新建store文件夹,在里面新建index.js文件
(2)在index.js中进行操作:
//1.导入vuex
import Vuex from 'vuex'
import Vue from 'vue'
//2.安装插件
Vue.use(Vuex)
//3.创建store对象
const store = new Vuex.Store({
})
//4.导出store对象
export default store
(3)在main.js中做以下操作
import Vue from 'vue'
import App from './App.vue'
import '@/assets/css/bootstrap.css'
//1.引入store对象
import store from './store'
Vue.config.productionTip = false
//2.挂到Vue对象上
new Vue({
render: h => h(App),
store
}).$mount('#app')
3.各个vuex核心成员介绍及使用
(1)state(state本质是一个对象,用来存储全局共享的数据,有两种访问方式)
const store = new Vuex.Store({
state: {
count: 0
}
})
访问方式一:通过“this.$store.state.全局数据名称”来访问,如果是插值表达式,建议不加this,如下所示:
<p>count 值:{{ $store.state.count }}</p>
访问方式二:通过vuex提供的mapState辅助函数,可以方便的把Store中指定的数据,映射为当前组件的计算属性
<script>
//目标1:通过vuex的辅助函数mapState访问
//1.按需导入mapState
import { mapState } from "vuex";
export default {
name: "Left",
computed: {
//2.利用展开运算符...来实现将数据导入
...mapState(["count"]),
},
};
</script>
<p>count 值:{{ count }}</p>
(2)Mutation(本质是JS函数,用于修改state中的数据。组件中其实也可以修改state中的数据,但是不推荐,会导致修改来源不明确等问题,不利于后期调试和维护。借助mutation修改可以保证修改数据来源的唯一性,在timeline中可以进行调试以及监听数据的变化,前提必须是同步数据,异步的无法追踪)
访问方法一:通过“this.$store.commit('方法名')”来调用mutation方法
const store = new Vuex.Store({
state: {
count: 0
},
//定义mutation方法,因为state是不好获取的,所以官方提供了state参数,
//第二个参数是载荷(payload)(就是参数,且只有一个,多的不会接收,如果有多个数据时可以考虑对象或者数组)
mutations: {
add(state, payload) {
state.count += payload
}
}
})
<button class="btn btn-primary" @click="$store.commit('add', 1)">+1</button>
访问方法二:通过辅助函数mapMutations把store中指定的方法映射为当前组件的methods方法
methods: {
//把store中指定的方法映射为当前组件的methods方法
...mapMutations(["add"]),
},
<button class="btn btn-primary" @click="add(10)">+10</button>
(3)Action(本质是JS函数,用来处理vuex中的异步操作,默认第一个参数为ctx)
访问方法一:通过this.$store.dispatch('actions中的方法名')即可触发指定名称的Actions方法
//定义actions方法来处理vuex中的异步操作
actions: {
//ctx(context)是当前new出来的store实例对象
addAsync(ctx) {
//执行异步操作
setTimeout(() => {
ctx.commit('add', 5)
}, 1000)
}
}
<button class="btn btn-primary" @click="$store.dispatch('addAsync')">+5</button>
访问方法二:通过辅助函数mapActions,先按需导入,映射为当前组件methods中的方法
<script>
//目标1:通过vuex的辅助函数mapState访问
//1.按需导入mapState
import { mapState, mapMutations, mapActions } from "vuex";
export default {
name: "Left",
computed: {
//2.利用展开运算符...来实现将数据导入
...mapState(["count"]),
},
methods: {
//把store中指定的方法映射为当前组件的methods方法
...mapMutations(["add"]),
...mapActions(["addAsync"]),
},
};
</script>
<button class="btn btn-primary" @click="addAsync">+5</button>
(4)Getter(本质是JS函数,是vuex中的计算属性,当store中的数据源发生变化时,getter的返回值会自动更新)
访问方法一:通过this.$store.getters.计算属性名,第一个参数永远是state,且必须要有返回值
//定义geeters,本质是js函数,是vuex的计算属性,第一个形参永远是state,getter必须返回一个结果
getters: {
isAllDone(state) {
return state.list.every(item => item.isDone)
}
}
<p>{{ $store.getters.isAllDone }}</p>
访问方法二:通过辅助函数mapGetters,将其映射为当前组件的计算属性
<script>
//目标1:通过vuex的辅助函数mapState访问
//1.按需导入mapState
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
export default {
name: "Left",
computed: {
//2.利用展开运算符...来实现将数据导入
...mapState(["count"]),
...mapGetters(["isAllDone"]),
},
methods: {
//把store中指定的方法映射为当前组件的methods方法
...mapMutations(["add"]),
...mapActions(["addAsync"]),
},
};
</script>
<p>{{ isAllDone }}</p>
(5)module(表示模块化开发,把不同的数据和方法封装在一起,按照彼此的关联关系进行封装,每个模块都是独立的,都可以拥有自己的state,mutation,action和getter节点。在定义模块时最好开启命名空间,可以解决不同模块之间命名冲突的问题,启用命名空间后,需要通过模块注册名才可以访问的到)
1)先定义一个count模块并导出
export default {
//开启命名空间
namespaced: true,
state: () => ({}),
mutations: {
test() {
console.log('我是count模块')
}
},
actions: {},
getters: {}
}
2)在store对象中注册模块
//1.导入模块
import moduleCount from './count'
const store = new Vuex.Store({
//2.注册模块
modules: {
//3.模块的注册名称:模块对象
count: moduleCount
},
})
3)访问模块下成员的的时候需要添加注册的模块名称,否则会报错
<button @click="handler">测试</button>
export default {
methods: {
handler() {
this.$store.commit("count/test");
},
},
}
4)要是访问命名空间下的state数据、mutation、action和getter时,建议使用辅助函数来简化访问过程,且和之前访问类似,只是在展开那里多了一个模块注册名称的参数
...mapState("count", ["count"]),//参数一:模块的注册名称,参数二:要映射的数据项
<p>count 值:{{ count }}</p>
vuex图解: