Skip to content

Vuex

跟全局事件总线做差不多的事情,但是与全局事件总线不同的是它是把所有的数据全部由自己(vuex)统一管理,当某一组件修改期中的数据时其他的组件也会同步更新。而全局事件总线本质上来说就是把参数传来传去,并没有让数据真正意义上进行共享

安装

使用的vuex版面要比当前的vue版本要高一级

V2使用vuex3:npm i vuex@3

V3使用vuex4:npm i vuex@4

创建目录(vuex)和js文件(store.js)并暴露出去

javascript
import Vue from "vue";
import Vuex from "vuex";

// 引入模块
Vue.use(Vuex);

// 创建核心对象
const actions = {};
const mutations = {};
const state = {};
const getters = {};

// 创建对象
const store = new Vuex.Store({
    actions: actions,
    mutations: mutations,
    state: state,
    getters: getters
});

// 导出
export default store;

然后在Main文件中关联一下

javascript
import store from "@/vuex/store";
...
new Vue({
    store: store,
...

使用

当以上内容配置完成之后,会在每个 vc 和 vm 对象中存在一个 $store 可以通过调用这个对象完成需求

javascript
// actions 回调函数
// 专门用来处理业务和发送AJAX请求
const actions = {
    // context:vuex的上下问
    // value:通过API传递过来的参数
    fun1(context, value) {
        // ...
        
        // 通过以下内容去调用 mutations 回调函数更新数据
        context.commit("fun1", 传去的参数);
    }
};

// mutations 回调函数
// 专门用来更新 state
const mutations = {
    // state:状态对象
    // value:传过来的参数
    fun1(state, value) {
        // ...
    }
};
// 相当于 vue 中的 data 只不过这里叫做状态
const state = {};

// 相当于计算属性
const getters = {
    // 会自动接收一个 state 属性
    xxx(state) {
        return xxx;
    }
};

actions 回调函数是通过 stort 自己的API去进行自动调用(在actions里面也是一样使用context调用)

API:this.$store.dispatch("回调函数名", 传去的参数);

计算属性优化

在使用 state 中的数据时需要编写很长的表达式($store.state.xxx)在这其中一部分数据时可以省略的

javascript
// 对象形式写法
computed: {
  ...mapState({xxx1: "xxx1", xxx2: "xxx2"})
}

// 数组形式写法
computed: {
  ...mapState([xxx1, xxx2])
}

可以使用以上表达式让 vuex 自动生成 ... 是ES6的表达式

xxx1:是手动调用时的内容

"xxx1":是state中的内容

只有键名和值名相同就可以写成数组形式

getters 也是如此

方法优化

与上面计算属性优化同理,也是用来进行简写内容的,也有对象和数组两种形式写法

javascript
// 数组形式写法
methods: {
  ...mapActions({xxx1: "xxx1"})
}

xxx1:调用的方法名

"xxx1":是actions中的方法

在调用者中传递参数,如:<button @click="xxx1(1)">按钮</button>

模块化开发

在上面的写法中会把所有的内容写在一个里面,这会导致多个模块的内容混杂,可以进行模块分隔

javascript
...

// 模块 a
const a = {
    // 开启命名空间
    namespaced: true,
    actions: {},
    mutations: {},
    state: {},
    getters: {}
}

...

const store = new Vuex.Store({
    // 使用 modules 注册模块
    modules: {
        a: a
    }
});

命名空间:如果在没有开启命名空间的时候,如果A模块和B模块有相同的方法,那么当调用某个方法的时候,这两个方法都会被执行。命名空间开启后进行调用时加上模块名:this.$store.dispatch("模块名/方法名", 参数)

单 js 文件

一个模块一个 js 文件,创建一个 js 文件模块

javascript
export default {
    namespaced: true,
    actions: {},
    mutations: {},
    state: {},
    getters: {}
}

然后在 store.js 进行导入然后正常注册

map优化

在上面有计算属性和方法的优化,在模块化开发中优化只需要在前面加上模块名即可

javascript
// 数组形式写法
methods: {
  ...mapActions("模块化开发",["xxx1"])
}