自学内容网 自学内容网

Vuex的使用教程

一、理解Vuex 

vuex是什么 

什么时候使用Vuex 

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态 

求和案例-纯Vue版

option的value引号里面的东西会被当成字符串进行拼串操作,无法正常进行加减操作。 

在value前面加上冒号就可以解决这个问题

方法一:加冒号 

其实就是v-bind的一个运用,加上冒号之后,引号里面的内容都当成js表达式去解析 

方法二:加修饰符

收集到的东西强制转换成number类型 

vuex工作原理


vuex有三个组成部分:

Actions、Mutations、State,这三个都是对象类型。这三个对象经由store仓库管理

调用的dispatch和commit都是store提供的

  • Actions:写业务逻辑,比如奇数时再加,等一等再加
  • Mutations:真正的修改操作


这里的Actions看似有点多余,其实不然。

当调用了dispatch,只给了'jia'参数,要加的那个数需要发送ajax请求(异步请求)才能获取的时候,就需要在Actions里面发送请求

在动作类型和动作值都具备的情况下,Vue允许在组件VC直接调用commit和Mutations进行对话,只是图上没有体现 

Devtools:vuex官方出的开发者调试工具

 

二、搭建Vuex环境

1. installing 

因为现在vue默认为vue3版本,对应的vuex默认也更新为vuex4。但我们使用的是vue2,下载时必须指定安装vuex3版本,否则会报错 

npm i vuex@3

2. 使用插件
在main.js中引入并使用插件

import 'Vuex' from 'vuex'
Vue.use(Vuex)

在Vue.use了Vuex之后,创建vm的时候就可以传入store这个配置项了 

(因为这时所有的vc和vm都可以看到store) 

3. 让vc和vm可以看见store
创建一个名为store的文件夹,里面包含了index.js文件

//该文件用于创建Vuex中最为核心的store
//对象值的key和保存对应值的变量重名了可以触发对象的简写形式

//引入Vuex
import Vuex from 'vuex'
//准备actions——用于响应组件中的动作
const actions = {};
//准备mutations——用于操作数据(state)
const mutations = {};
//准备state——用于存储数据
const state = {};


export default new Vue.Store({
  actions,
  mutations,
  state,
})

这样写的非常齐全的store浏览器依旧会报错,这是因为main.js中import顺序的问题

 

要求先调用Vue.use(),再创建store实例

但其实修改了顺序之后控制台依旧报错,这是脚手架解析import语句的问题 

在脚手架里面写import,不管两个import之间写了什么代码,它会扫描整个文件的import语句,把所有import语句,按照编写的顺序全部汇总到最上方。

所以调整代码顺序也没有用

解决方案:

在index.js文件创建store之前引入并使用Vuex 

求和案例-vuex版 

store的index.js文件

1.  响应组件中的动作 

//该文件用于创建Vuex中最为核心的store
//对象值的key和保存对应值的变量重名了可以触发对象的简写形式

//引入Vue
import Vue from 'vue';
//引入Vuex
import Vuex from 'vuex'
//使用Vuex插件
Vue.use(Vuex)
//准备actions——用于响应组件中的动作
const actions = {
  jia(context, value) {
    context.commit('JIA', value);
  }
};
//准备mutations——用于操作数据(state)
const mutations = {
  JIA(state, value) {
    state.sum += value;
  }
};
//准备state——用于存储数据
const state = {
  sum: 0
};


export default new Vuex.Store({
  actions,
  mutations,
  state,
})

 actions对象中的jia函数接收两个参数:

  1. context类似于miniStore,是一个上下文环境,让我们可以在actions里面调用commit接口
  2. 第二个参数就是操作值

在开发中,一般用大小写来区分是哪个对象里面的函数:

  • 小写是actions里面的
  • 大写是mutations里面的

mutations对象中的JIA函数接受两个参数:

  1.  state对象(里面多了getter和setter,目的就是为了检测数据的变化)
  2. 操作值

 2. 显示store里面的数据

 {{$store.state.sum}}

注意:模板里面不用写this,模板里面可以看见vc里面的所有东西

 

 我们现在把业务逻辑都写在actions里面

//引入Vue
import Vue from 'vue';
//引入Vuex
import Vuex from 'vuex'
//使用Vuex插件
Vue.use(Vuex)
//准备actions——用于响应组件中的动作
const actions = {
  jia(context, value) {
    context.commit('JIA', value);
  },
  jian(context, value) {
    context.commit('JIAN', value);
  },
  jiaOdd(context, value) {
    if (context.state.sum % 2) {
      context.commit('JIA', value);
    }
  },
  jiaWait(context, value) {
    setTimeout(() => {
      context.commit('JIA', value);
    }, 500);
  }
};
//准备mutations——用于操作数据(state)
const mutations = {
  JIA(state, value) {
    state.sum += value;
  },
  JIAN(state, value) {
    state.sum -= value;
  }
};
//准备state——用于存储数据
const state = {
  sum: 0
};


export default new Vuex.Store({
  actions,
  mutations,
  state,
})

现在我们来对代码进行优化,actions对象中的jia函数和jian函数并没有什么动作,我们可以直接让其和mutations沟通

在组件中就不使用dispatch了,而是直接调用commit联系mutations,注意JIA要大写哦!! 

vuex的基本使用 

 

 

 

三、store配置项
 

getters 

用于将state中的数据进行加工 

我们希望增添一行显示sum计算过后的一个值(比如放大十倍),可以直接用插值语法+js表达式来实现。

但是逻辑运算复杂时就不能这样了(比如*10 + 9 - 2 / 100 再开方),此时可以用计算属性来解决。 

但是计算属性只有自己这个组件才能复用,跨组件不能用。此时可以用store的getters配置项来解决

const getters = {
  bigSum(state) {
    return state.sum * 10;
  }
}
  • 可以拿到state参数
  • 跟计算属性很像,需要靠return来返回计算的值 

state ——> data

getters ——> computed

 

 

mapSate和mapGetters

为优化$store.state类似代码的重复编写,我们将其写成以下计算属性的形式 

但是写好之后我们发现,还是非常冗余而且有很多代码的重复。

我们希望实现一个函数,传入两个参数(我们想要的名称,在store.state里面的名称)就可以自动帮我们生成上段代码获取到数据

——引入mapState,它就能实现以上功能

借助mapState生成计算属性,从state中读取数据

import {mapState} from 'vuex'

1. 对象写法 

因为mapState的返回值是一个对象,不能在对象里面写对象,所以这里运用扩展运算符

2. 数组写法

computed: {
  //自己写computed属性
  // sum() {
  //   return this.$store.state.sum
  // },
  // school() {
  //   return this.$store.store.school
  // },
  // subject() {
  //   return this.$store.store.subject
  // },
  // bigSum() {
  //   return this.$store.getters.bigSum
  // }
  //借助mapState生成计算属性,从state中读取数据(对象写法)
  // ...mapState({ he: 'sum', xuexiao: 'school', xueke: 'subject' })
  //借助mapState生成计算属性,从state中读取数据(数组写法)
  ...mapState({sum:'sum',school:'school',subject:'subject'})
},    

易错: 

这里可不可以简写成

 
不可以,只有 sum : sum(后面是变量名)的时候才能这样简写,此时我们的键值是字符串,如果这样写是无法成功解析成我们想要的键值对的

正确简写方式:

...mapState(['sum','school','subject'])

mapGetters的用法如上,不再赘述

mapMutations和mapActions 

优化methods里面的代码

——引入mapMutations

借助mapMutations生成对应的方法,方法中会调用commit去联系mutations

1. 对象写法 

 以下是我们希望它帮我们生成的代码

但它实际帮我们生成的

 这样会报错,我们来分析一下

 不写小括号也会传参(event),当你点击时event就是鼠标事件,如下。于是乎就乱套了

 解决方法:

其实还有一种nt写法

 

2. 数组写法

同样的,必须键值对值一样才可以这样写

注意:要写mutations里面的那个名称 

mapActions:

 借用mapActions生成对应的方法,方法中会调用dispatch去联系actions

总结 

 

四、Vuex模块化 

问题:

当项目变得庞大,组件数量变多时,这个mutations就会变得难以维护

并且所有程序员都操作这一个mutations会造成git版本控制的冲突 

所以我们的目标是把不同分类的mutation放在不同的位置 

将其暴露出去

 获取数据

方式一:

方式二: 

通过第一个参数去指定分类,获取后面的数据

但是,此时出现了报错

原因: 

当你想通过第一个参数去指定分类,获取后面的数据的时候

你在配置Vuex的时候,在每一个配置里面都加上一个特殊的配置项——

namespaced: true

写上这个配置项之后,a、b两个分类名才能mapState认识 

 通知调用mutations和actions里面的函数时也要记得写上分类名

没有用到map方法时如何调用模块化

特别注意分类名是在state后面的!!! 

 

我们再来看一个情景,在getters里面对state中的数据进行加工,通过getters获取到name的first Name,如下写法(错误)

这是因为getters里面的分类和state里面的分类有所不同 

 

所以getters里面压根就没有'personAbout'这个属性名,只有personAbout/firstPersonName

 但是以上写法仍然是错误的,因为读取对象属性使用点语法时,不能有斜杠

读取对象属性的另一种方法:

方括号里面写字符串 

 

总结

 

 


原文地址:https://blog.csdn.net/ixxoic/article/details/144352182

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!