vuex 一文贯通_细_

https://vuex.vuejs.org/vuex.png
在这里插入图片描述

一、安装 vuex

npm i vuex@3

vue2 使用vuex3,vue3 使用 vuex4

二、搭建 vuex 环境

1. 项目根目录创建 store 文件夹,里面创建 index.js 文件
// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
// 引入 Vuex 
import Vuex from 'vuex'
// 使用 Vuex 插件
Vue.use(Vuex)

// 准备actions--用于响应组件中的动作
const actions  = {}
// 准备mutations--用于操作数据(state)
const mutations = {}
// 准备state--用于存储数据
const state = {}

// 创建并暴露 store
export default new Vuex.Store({
    actions,
    mutations,
    state,
})
2. main.js 做如下配置
import Vue from 'vue'
import App from './App.vue'
// 引入 store
import store from '../store'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  // 传入 store 配置项
  store,
}).$mount('#app')
3. 验证一下

在 Vue.vue组件中进行验证

mounted(){
        console.log(this);
    }

在这里插入图片描述
说明基本配置已经成功

三、vuex 案例

1. 拿值

在 state 先存数据 sum

// state--用于存储数据
const state = {
    sum: 0 // 当前的和
}

然后在 App.vue 组件里拿值

<h3>结果: {{$store.state.sum}}</h3>
2. 进行传参加法运算
// 准备actions--用于响应组件中的动作
const actions  = {
    add(context,value){
        context.commit('ADD',value)
    }
}
// 准备mutations--用于操作数据(state)
const mutations = {
    ADD(state,value){
        state.sum += value
    }
}
// 准备state--用于存储数据
const state = {
    sum: 0 // 当前的和
}

add(context,value){} 第一个参数表示上下文,可拿到你想要的值如 state 里的值等,第二个参数表示 传过来的参数
为了区分 actions 和 mutations ,mutations 最好使用大写

  • actions相当于服务员,mutations相当于后厨
  • actions可以做一些逻辑判断,相当于服务员要询问要不要辣,要不要香菜啥的
  • 然后再通过 mutations 对 state 里的数据进行相关的操作

在 App.vue 中

<template>
  <div>
    <h3>结果: {{$store.state.sum}}</h3>
    <button @click="add">+{{n}}</button>
  </div>
</template>

<script>
export default {
    data(){
        return{
            // 每次相加的数
            n: 1
        }
    },
    methods: {
        add(){
            this.$store.dispatch('add',this.n)
        }
    }
}
</script>

在这里插入图片描述
如果 actions 中的方法不需要做一些逻辑判断,可以直接 跳到 mutations,如上面进行加法的运算
在App.vue中更改如下

methods: {
        add(){
            this.$store.commit('ADD',this.n)
        }
    }

此时就不需要经过 actions 中的 add,而是直接使用 mutations 中的 ADD

一开始我在想,为啥不在actions中直接操作 state 呢,如果这样是不能在开发者工具(后面有说到)中看到此操作的,看本文章的第一张图就可以知道,只有mutations 中的操作才被会开发者工具查看到

3. 通过 actions 进行一些判断,只有奇数的时候才可以相加
addOdd(context,value){
        if(context.state.sum % 2 ){
            context.commit('ADD',value)
        }
    }

在 App.vue 中

<button @click="addOdd">奇数加一</button>
<script>
...
addOdd(){
   		this.$store.dispatch('addOdd',this.n)
    }
</script>

在这里插入图片描述

四、开发者工具的使用

vuex 也是 vue 做出来的,所以他们公用一个开发者工具 vue.js devtools
在这里插入图片描述

具体看尚硅谷vue的110集

五、getters 配置项

当需要对 state 中的数据进行一些很复杂的数据处理时,比如对一个数字又乘又除还要开根号也要实现复用等复杂的处理,就可以使用getters 配置项
简单举例:上面中的sum,我要变成十倍

// 用于将state中的数据进行加工
const getters = {
    bigSum(state){
        return state.sum*10
    }
}

// 创建并暴露 store
export default new Vuex.Store({
     ...
    getters,
})

state 可以理解为vue组件中的data
getters 可以理解为 vue组件中的 computed(计算属性)

在 App.vue 中

<h3>放大10倍: {{$store.getters.bigSum}}</h3>

在这里插入图片描述

六、mapState 与 mapGetters

假如 state 中有如下数据

// state--用于存储数据
const state = {
    name: '张三',
    sex: '男',
    age: 18,
}

那么 App.vue 取数据时,就会有点繁琐了

    <h3>姓名:{{$store.state.name}}</h3>
    <h3>姓别:{{$store.state.sex}}</h3>
    <h3>年龄:{{$store.state.age}}</h3>

在插值表达式中是不建议写这么长的,那我们可以使用计算属性

	<h3>姓名:{{xm}}</h3>
	<h3>姓别:{{xb}}</h3>
	<h3>年龄:{{nl}}</h3>
	<script>
	...
    computed:{
        xm(){
            return this.$store.state.name
        },
        xb(){
            return this.$store.state.sex
        },
        nl(){
            return this.$store.state.age
        },
    },
    </script>

可以发现这样写重复的内容非常多,所以 vuex 就有了mapState
使用 mapState

import { mapState } from "vuex"
export default {
computed: {
    // 借助mapState生成计算属性,从state中读取数据。(对象写法)
    ...mapState({xm: 'name', xb: 'sex', nl: 'age'})
  },
}

由于mapstate 是一个对象,所以要使用展开运算符

如果计算属性的名字和state中的命名一致时简写如下

 // 借助mapState生成计算属性,从state中读取数据。(数组写法)
 ...mapState(['name', 'sex', 'age'])

同理,getters 也有 mapGetters
举例:上面我们有一个getters 里面有一个 bigSum,App.vue 中我们可以改成如下:

import { mapState, mapGetters } from "vuex"
export default {
computed: {
	// 借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
    ...mapGetters(['bigSum'])
  },
}

七、mapActions和mapMutations

通过第六节学的mapState 与 mapGetters,大概也知道mapActions和mapMutations的作用了吧
前面我们对state中的sum加一时,使用的是

<button @click="add">+{{n}}</button>
<script>
   data() {
    return {
        // 每次相加的数
        n: 1
      };
  	},
   methods: {
    add() {
      this.$store.commit("ADD", this.n);
    },
 }
 </script>

使用mapMutations时:

<button @click="add(n)">+{{n}}</button>
<script>
import { mapState, mapGetters, mapMutations} from "vuex"
...
methods: {
  // 借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
  ...mapMutations({add: 'ADD'}),
 }
 </script>

如果方法名和mutations里面的一样也可以使用数组的方法,这里就不举例了

记得在方法里面进行传参

mapActions 你肯定也是会的啦,老样子看一下以前的写法

    <button @click="addOdd">奇数加一</button>
    ...
    addOdd() {
      this.$store.dispatch("addOdd", this.n);
    }

使用 mapActions

<button @click="addOdd(n)">奇数加一</button>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from "vuex"
...
methods: {
  // 借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法)
  ...mapActions(['addOdd'])
}
</script>

八、多组件数据共享

其实跟上面的第七没啥区别,下面简单演示一下在 HelloWord.vue 使用vuex

<template>
  <div>
    <h3>姓名:{{name}}</h3>
    <h3>姓别:{{sex}}</h3>
    <h3>年龄:{{age}}</h3>
    <h4>sum的值:{{sum}} 十倍:{{bigSum}}</h4>
    <button @click="addOdd(1)">奇数加一</button>
    <button @click="ADD(1)">加一</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
    computed:{
        ...mapState(['name','sex','age','sum']),
        ...mapGetters(['bigSum'])
    },
    methods:{
        ...mapActions(['addOdd']),
        ...mapMutations(['ADD'])
    }
}
</script>

九、vuex 模块化

假如我们做的系统比较大,功能很多,命名也容易冲突等,则不可能把全部代码都放到一个 .js 文件里面,应该进行分类的管理

1. 我们先在一个 .js 文件里面进行分类
// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
// 引入 Vuex 
import Vuex from 'vuex'
// 使用 Vuex 插件
Vue.use(Vuex)

// 计数相关的配置
const countOptions = {
    // 开启命名空间
    namespaced: true,
    actions: {
        add(context, value) {
            context.commit('ADD', value)
        },
        addOdd(context, value) {
            if (context.state.sum % 2) {
                context.commit('ADD', value)
            }
        }
    },
    mutations: {
        ADD(state, value) {
            state.sum += value
        }
    },
    state: {
        sum: 1,
    },
    getters: {
        bigSum(state) {
            return state.sum * 10
        }
    }
}

// 人员信息相关的配置
const personOptions = {
    // 开启命名空间
    namespaced: true,
    actions: {},
    mutations: {},
    state: {
        name: '张三',
    sex: '男',
    age: 18,
    },
    getters: {}
}

// 创建并暴露 store
export default new Vuex.Store({
    modules:{
        countAbout:countOptions,
        personAbout:personOptions
    }
})

使用上面第八的 HelloWord.vue 来进行演示

<template>
  <div>
    <h3>姓名:{{name}}</h3>
    <h3>姓别:{{sex}}</h3>
    <h3>年龄:{{age}}</h3>
    <h4>sum的值:{{sum}} 十倍:{{bigSum}}</h4>
    <button @click="addOdd(1)">奇数加一</button>
    <button @click="ADD(1)">加一</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
    computed:{
        ...mapState('countAbout',['sum']), // countAbout 为js开启的命名空间,指定是谁里面的配置
        ...mapState('personAbout',['name','sex','age']),
        ...mapGetters('countAbout',['bigSum'])
    },
    methods:{
        ...mapActions('countAbout',['addOdd']),
        ...mapMutations('countAbout',['ADD'])
    }
}
</script>
  • js 文件中每一个配置都开启命名空间,就是为了后面 .vue 组件中区分每一个配置进行使用
2. 下面我们把相关的配置放在一个独立文件里面

计算相关的放在 count.js 文件里

// 计数相关的配置
export default {
    // 开启命名空间
    namespaced: true,
    actions: {
        add(context, value) {
            context.commit('ADD', value)
        },
        addOdd(context, value) {
            if (context.state.sum % 2) {
                context.commit('ADD', value)
            }
        }
    },
    mutations: {
        ADD(state, value) {
            state.sum += value
        }
    },
    state: {
        sum: 1,
    },
    getters: {
        bigSum(state) {
            return state.sum * 10
        }
    }
}

人员信息相关的配置放在person.js里

// 人员信息相关的配置
export default {
    // 开启命名空间
    namespaced: true,
    actions: {},
    mutations: {},
    state: {
        name: '张三',
    	sex: '男',
    	age: 18,
    },
    getters: {}
}

index.js文件变成

// 该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
// 引入 Vuex 
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
// 使用 Vuex 插件
Vue.use(Vuex)

// 创建并暴露 store
export default new Vuex.Store({
    modules:{
        countAbout:countOptions,
        personAbout:personOptions
    }
})

这样根据功能分成不同的 .js 文件,结构清晰易懂
参考资料
在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值