Vuex整洁架构之道

简介: 如何保持Vuex架构的整洁和可维护,本文将探讨如何为Vuex创建整洁架构的技巧,这个架构的灵感来自于Vuex官方文档和互联网的其他vuex的学习资料。

如何保持Vuex架构的整洁和可维护,本文将探讨如何为Vuex创建整洁架构的技巧,这个架构的灵感来自于Vuex官方文档和互联网的其他vuex的学习资料。

本文中涉及的代码:github.com/QuintionTan…

image.png

之前也写过一遍关于VUE项目代码优化的文章《Vue 开发中可以使用的 ES6 新特征

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

为了简化起见,Vue是一个采用基于组件的体系结构的框架,因此每个组件都被设计成一小块Vue文件,并可在组件之间重用。正因为如此,它并不排除某些小组件需要一起工作或使用相同数据的可能性。这就是为什么需要Vuex来解决这个问题。Vuex就像一个全局变量和全局函数,拥有的每个组件都可以使用它。Vuex更集中地管理API调用和存储响应数据,统一API调用的入口,这样一个API调用和数据就可以在Vue项目的每个组件中使用。

image.png


如何注册和创建Vuex模块


本文将使用vuex构建一个简单的vue应用程序,来显示《星球大战》电影中的人物和行星列表。

image.png

首先,需要基于每个作用域创建一个新的store module。下面是创建store module的模板。每个store module都包含state, mutations, actionsgetters。确保添加了namescaped属性,避免store module之间名称冲突,当然这也意味着访问store module之前需要指定namescaped名称,这样可以使得 Vuex 更加整洁和可维护。

const state = {}
const mutations = {}
const actions = {}
const getters = {}
export default {
    namespaced: true,
    state,
    mutations,
    actions,
    getters,
};

创建完所需的store module后,将所有的store module 合并到一个vuex store中。

实际项目中,可以直接在下面的代码中创建一个store modulestategettersactions)。而无需创建诸如people模块或planets模块之类的单独模块。

为了达到架构清晰,建议不要那样做,最好创建几个小模块,并将其合并成一个vuex store中。

import Vue from "vue";
import Vuex from "vuex";
import people from "./modules/people";
import planets from "./modules/planets";
Vue.use(Vuex);
const store = new Vuex.Store({
    modules: {
        people: people, // 这种方式是可以重命名模块名称
        planets,
    },
});
export default store;

之后,将几个store module组合在一起,然后将其捆绑成一个module。下一步是创建Vue应用程序时注册它,以便Vue应用程序可以使用所有Vuex store moudle。


单个store module


在单独的store模块的其余部分中,仅关注people store module,因为在people与planets模块之间大部份是相似。

首先,从state开始,它就像一个包含数据的全局变量。在本文例子中,需要存储《星球大战》中的人物数据。因为有多个person数据,所以将其存储在一个数组中。在本例中,用空数组的默认值定义了一个people属性。其实state的设计有点像数据库的设计。

const state = {
  people: []
}

其次,在想要存储的全局变量之后,接下来需要创建一个mutations,以便能够修改状态值。因为它类似于一个全局变量,所以需要在不调用mutations的情况下保护要编辑的state,只有mutations才能更改state值。在本例中,在修改state值时使用了(...)展开操作符,在JavaScript中,如果只使用equals(=),则值只复制引用,而不是深入复制数组值。这很容易引起错误,以至于难以调试。因此,在改变新值时最好使用(...)展开操作符。对于对象,也要确保使用(...)展开操作符。

const mutations = {
    setPeople(state, payload) {
        state.people = [...payload];
    },
};

接下来就是actionsactions就像一个全局函数,可以在每个组件中调用。大多数情况下,actions用于处理API调用和更改state值。在actions中,通常是mutations来改变state的值。

在我看来,也是为了更整洁的构建。建议为API创建一个新的单独文件,本例中,将Axios的定义放在api文件夹中,接口方法放在services中(意思是与服务器对接的方法)。

import axios from "axios";
const apiClient = axios.create({
    baseURL: "https://swapi.dev/api/",
});
// interceptors 拦截器,统一处理接口的请求,如修改header等
apiClient.interceptors.request.use((request) => {
    return request;
});
// interceptors 拦截器,统一处理接口的响应和错误
apiClient.interceptors.response.use(
    (response) => {
        return response;
    },
    (error) => {
        console.error(error);
    }
);
export default apiClient;

那么在services中,就是处理单个的方法。

import apiClient from "@/api";
const getPeople = (success, fail) => {
    apiClient
        .get("people")
        .then((response) => success(response))
        .catch((response) => fail(response));
};
const getPlanets = (success, fail) => {
    apiClient
        .get("planets")
        .then((response) => success(response))
        .catch((response) => fail(response));
};
export { getPeople, getPlanets };

在完成并准备好所有API调用及相应的调用方法后,现在回到的store module中。将定义的API方法与store module结合起来。

import * as services from "@/services";
const state = {
    people: [],
};
const mutations = {
    setPeople(state, payload) {
        state.people = [...payload];
    },
};
const actions = {
    getPeople({ commit }, { success, fail } = {}) {
        services.getPeople(
            (response) => {
                commit("setPeople", response.data.results);
                success && success(response);
            },
            (response) => {
                fail && fail(response);
            }
        );
    },
};
const getters = {
    male(state) {
        return state.people.filter((person) => person.gender === "male") || [];
    },
    female(state) {
        return (
            state.people.filter((person) => person.gender === "female") || []
        );
    },
};
export default {
    namespaced: true,
    state,
    mutations,
    actions,
    getters,
};


视图或组件调用store


首先,让从state开始。要访问state,需要从Vuex导入mapState,并将其映射到一个computed值,如下面的示例代码所示。

import { mapActions, mapState, mapGetters } from "vuex";
export default {
    name: "People",
    created() {
        this.getPeople();
    },
    computed: {
        ...mapState("people", ["people"]),
        ...mapGetters("people", ["male", "female"]),
    },
};

接下来就是 actions,需要从Vuex导入mapActions并将其放置在方法中。

import { mapActions, mapState, mapGetters } from "vuex";
export default {
    name: "People",
    data() {
        return {
            loading: false,
        };
    },
    created() {
        this.loading = true;
        this.getPeopleAction();
    },
    computed: {
        ...mapState("people", ["people"]),
        ...mapGetters("people", ["male", "female"]),
    },
    methods: {
        ...mapActions("people", ["getPeople"]), // 如果需要是多个namespace的方法,在下面在写一行
        // ...mapActions("planets", ["getPlanets"]),  // 此处为行星模块
        handleSuccess() {
            this.loading = false;
            console.log("success fetch data");
        },
        handleFail() {
            this.loading = false;
            console.log("failed fetch data");
        },
        getPeopleAction() {
            this.getPeople({
                success: this.handleSuccess,
                fail: this.handleFail,
            });
            // 下面注释的代码为优化前的调用方式
            // this.$store.dispatch("people/getPeople", {
            //     success: this.handleSuccess,
            //     fail: this.handleFail,
            // });
        },
    },
};


总结


Vuex是状态管理,它存储Vue应用程序的所有数据逻辑。必须确保它的整洁,以助于团队协作。


相关文章
|
前端开发 Java 测试技术
使用整洁架构优化你的 Gradle Module
使用整洁架构优化你的 Gradle Module
259 0
|
存储 Go 数据处理
Go 语言整洁架构实践
Go 语言整洁架构实践
409 0
|
Java 网络架构 容器
面向整洁对象的分层架构COLA 4.0
COLA 是 Clean Object-Oriented and Layered Architecture的缩写,代表“面向整洁对象的分层架构”。 目前COLA已经发展到COLA 4.0。 COLA分为两个部分,COLA架构和COLA组件。
面向整洁对象的分层架构COLA 4.0
|
存储 搜索推荐 NoSQL
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构,CQRS的整合架构
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构,CQRS的整合架构
|
前端开发 测试技术 数据库
软件架构编年史:整洁架构
软件架构编年史:整洁架构
软件架构编年史:整洁架构
|
存储 JSON 自然语言处理
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合(下)
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合
|
存储 搜索推荐 NoSQL
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合(上)
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合
|
消息中间件 存储 缓存
一文读懂架构整洁之道
相信大家都非常清楚,如何编写可读性强的代码是一个合格程序员的必修课。 我在之前的文章《谈谈什么是好的代码》中谈了一些自己对整洁代码的感悟,代码并不是独立存在的,成百上千个类的系统在企业应用中非常常见,如何将代码进行有效的组织,保持高可读性,高可维护性,则是一个好的架构需要考虑的事情。本文从原则切入,聊聊组件的分层和解耦,浅谈下Bob大叔提出的整洁架构,感兴趣的同学也可以发表下自己的看法。
6966 0
一文读懂架构整洁之道
|
存储 Java 测试技术
阿里高级技术专家:整洁的应用架构“长”什么样?
作者 | 张建飞 作者张建飞是阿里巴巴高级技术专家,入司6年,他创建了COLA。希望可以探索一套切实可行的应用架构规范,这个规范不是高高在上的纸上谈兵,而是可以复制、可以理解、可以落地、可以控制复杂性的指导和约束。本文详述了他对COLA的升级迭代。
6673 0
阿里高级技术专家:整洁的应用架构“长”什么样?
架构整洁之道-07 设计原则-接口隔离原则SIP
接口隔离原则 Interface Segregation Principle,ISP - 客户端不应该依赖它不需要的接口 - 类间的依赖关系应该建立在最小的接口上
325 0