一、介绍
(npm install vuex --save // 安装)
vuex 是vue 配套的数据管理工具,我们可以将组件共享数据保存到vuex 中,方便整个程序中得任何组件都可以获取和修改 vuex 中保存得公共数据
二、使用
一定要记得将创建的实例挂载到全局实例中,才能在不同页面中访问到
//第一步: 引入vuex
import Vuex from 'vuex'
Vue.use(Vuex)
//第二步:创建store实例对象
const store = new Vuex.Store({
? state: { //存放全局数据
? ? count: 0,
? ? nameArr: [
? ? ? { name: "胡歌" },
? ? ? { name: "彭于晏" }
? ? ]
? },
? mutations: { // 同步修改state中的数据的,里面存放修改state数据的方法
? ? add(state) { // ++
? ? ? state.count++
? ? }
? }
})
console.log(100, store);
new Vue({
? router,
? store, //将store 挂载到根实例上,这样的话,每个组件都能访问
? render: h => h(App),
}).$mount('#app')
三、vuex模块
a.state
概念: 提供全局唯一得公共数据源,所有的共享数据都要放在store 中得state 进行存储。 可以理解相当于 组件中的data
组件中访问state 中值的两种方法:this.$store.state.数据名称 && 使用mapState 辅助函数
<template>
? <div>
? ? 分类
? ? <p>count:{{ $store.state.count }}</p> //不使用计算属性的渲染方式
? ? <p>count:{{count}}</p> //计算属性不需要count()调用,直接{{count}}便可在全局中渲染
? ? <ul>
? ? ? <li v-for='(item,index) in nameArr' :key="index">{{item.name}}</li>
? ? </ul>
? </div>
</template>
<script>
import {mapState} from 'vuex' // 从vuex 中按需导入
export default {
? data() {
? ? return {};
? },
? computed:{
? ? ...mapState(['count','nameArr']), // 将该组件需要的vuex中得全局数据映射到该组件计算属性中
? }
b.mutations
同步修改state中的数据, 通过mutations 修改数据虽然繁琐一些,但是可以集中监控所有数据得变化
注意: 只能通过mutations 修改store中得数据,不能直接修改store得数据
home.vue文件
<template>
? <div>
? ? 首页
? ? <p>{{ msg }}</p>
? ? <hr />
? ? <p>vuex-count:{{ $store.state.count }}</p>
? ? <p><button @click="add1">+1</button></p>
? ? <button @click="addStep">+10传参</button>
? </div>
</template>
<script>
export default {
? data() {
? ? return {
? ? ? msg: "安志杰",
? ? };
? },
? created() {
? ? //获取store中的全局数据count
? ? console.log(this.$store.state.count);
? },
? methods: {
? ? add1() {
? ? ? // 调用vuex中mutation 中的add 方法,只能通过mutation 中定义的方法修改state中的数据
? ? ? this.$store.commit("add");//不传参,第一个参数永远是state
? ? },
? ? addStep(){
? ? ? this.$store.commit('addStep',10)//传参,第一个参数永远是state
? ? }
? },
};
</script>
main.js文件
? mutations: { //2. 存放修改state中的数据的方法集合,注意:mutations 里只能放同步方法
? ? add(state) { //定义了count++方法 不传参
? ? ? // state 就是 上面store 中的state,这个参数是固定的
? ? ? state.count++
? ? },
? ? addStep(state, step) { // 传参 参数为step
? ? ? state.count += step
? ? }
? },
运行结果:
c.action
概念:异步修改state 中得数据
注意: action 不能直接修改state中的数据,需要间接通过触发mutation中得方法修改数据。
home.vue文件
<template>
? <div>
? ? 首页
? ? <p>{{ msg }}</p>
? ? <hr />
? ? <p>vuex-count:{{ $store.state.count }}</p>
? ? <p><button @click="add1">+1</button></p>
? ? <button @click="addStep">+10传参</button>
? ? <button @click="addAsync">+1异步</button>
? ? <button @click="addAsyncStep(20)">+20异步 传参</button>
? </div>
</template>
<script>
export default {
? data() {
? ? return {
? ? ? msg: "安志杰",
? ? };
? },
? created() {
? ? //获取store中的全局数据count
? ? console.log(this.$store.state.count);
? },
? methods: {
? ? add1() {
? ? ? // 调用vuex中mutation 中的add 方法,只能通过mutation 中定义的方法修改state中的数据
? ? ? this.$store.commit("add");
? ? },
? ? addStep(){
? ? ? this.$store.commit('addStep',10)
? ? },
? ? addAsync(){
// 调用actions 中的异步方法
? ? ? this.$store.dispatch('addAsync')
? ? },
? ? addAsyncStep(step){
? ? ? this.$store.dispatch('addAsyncStep',step )
? ? }
? },
};
</script>
main.js文件
actions: { ?//3.存放修改state中的数据的方法集合,注意:该方法都是异步方法
? ? // 注意:actions中的方法不能直接修改state数据,还得靠mutations中的方法修改,在这个只不过是异步调用mutions方法
? ? addAsync(context) {
? ? ? setTimeout(() => {
? ? ? ? context.commit('add') // 异步调用mutions中的add 方法
? ? ? }, 2000)
? ? },
? ? addAsyncStep(context, step) {
? ? ? // 异步调用mutions方法中的addStep这个同步方法
? ? ? setTimeout(() => {
? ? ? ? context.commit('addStep', step) // 异步调用mutions中的addStep 方法
? ? ? }, 2000)
? ? }
? },
运行结果:
d.getters
概念:用于对store中得数据进行加工处理成新的数据。类似与vue 得计算属性
注意:store中得数据发生变化时,则getter 中对应的数据也发生变化。getter不会修改store 中得数据,只是包装
main.js文件
//home.vue文件中渲染方式
?<p>getters处理过的count:{{$store.getters.countFormat}}</p>
//main.js文件
getters:{
? ? countFormat(state){
? ? ? // 相当于vuex中的computed,该方法不能修改数据,只是对state 中的数据进行包装处理
? ? ? return state.count + '处理过的count'
? ? }
? }
使用mapGetters辅助函数
// 借助辅助函数
import { mapState, mapMutations, mapActions, mapGetters } from "vuex";
export default {
? data() {
? ? return {
? ? ? username: "",
? ? ? pwd: "",
? ? };
? },
? computed: {
? ? // 映射state
? ? ...mapState({
? ? ? num: (state) => {
? ? ? ? return state.moduleA.num;
? ? ? },
? ? ? // 映射getters
? ? ? ...mapGetters("moduleA", ["fiveNumTimes"]),
? ? }),
? },
? methods: {
? ? // 映射muations
? ? ...mapMutations("moduleA", ["addNum", "addNumStep"]),
? ? // ?映射actions
? ? ...mapActions("moduleA", ["addNumAsync", "addNumStepAsync"]),
? ? login() {
? ? ? if (this.username && this.pwd) {
? ? ? ? localStorage.setItem("username", this.username);
? ? ? }
? ? },
? },
};
e.module
vuex 允许我们将 store 分割成多个模块(module)。每个模块拥有自己的 state、mutation、action、getter
注意: 分模块开发时,必须给每个模块设置命名空间 namespaced:true,
moduleA.js
export default {
? namespaced: true,
? state: {
? ? ? num: 100
? },
? mutations: {
? ? ? addNum(state) {
? ? ? ? ? state.num++
? ? ? },
? ? ? addNumStep(state, step) {
? ? ? ? ? state.num += step
? ? ? }
? },
? actions: {
? ? ? addNumAsync(context) {
? ? ? ? ? context.commit('addNum')
? ? ? },
? ? ? addNumStepAsync(context, step) {
? ? ? ? ? context.commit('addNumStep', step)
? ? ? }
? },
? getters: {
? ? ? fiveNumTimes(state) {
? ? ? ? ? return state.num * 5
? ? ? }
? }
}
vue文件
<template>
? <div>
? ? 购物车
? ? <!-- 使用普通方法操作modules 中的数据 -->
? ? <p>moduleA-num:{{ $store.state.moduleA.num }}</p>
? ? <p>getters处理过的num::{{ $store.getters["moduleA/fiveNumTimes"] }}</p>
? ? <hr />
? ? <button @click="add">+1</button>
? ? <button @click="addStep(10)">+10 传参</button>
? ? <button @click="addAsync">+1 异步</button>
? ? <button @click="addAsyncStep(20)">+20 异步传参</button>
? </div>
</template>
<script>
export default {
? data() {
? ? return {};
? },
? created() {
? ? console.log(this.$store.state.moduleA.num);
? ? console.log(this.$store.getters["moduleA/fiveNumTimes"]);
? },
? methods: {
? ? add() {
? ? ? this.$store.commit("moduleA/addNum");
? ? },
? ? addStep(m) {
? ? ? this.$store.commit("moduleA/addNumStep", m);
? ? },
? ? addAsync() {
? ? ? this.$store.dispatch("moduleA/addNumAsync");
? ? },
? ? addAsyncStep(m) {
? ? ? this.$store.dispatch("moduleA/addNumStepAsync", m);
? ? },
? },
};
</script>
|