Vuex:模块化Module :VOA模式

news2025/1/12 18:54:49

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

这句话的意思是,如果把所有的状态都放在/src/store/index.js中,当项目变得越来越大的时候,Vuex会变得越来越难以维护

分成模块化后,每个人负责自己的那个模块开发,然后在/src/store.index.js中将这些模块进行汇总,这样可以避免多人开发的协调问题。

案列:

/src/router/index.js 路由器

import { createRouter, createWebHashHistory,createWebHistory } from "vue-router"; //导入vue-router路由模块,createWebHashHistor函数
//import Home from "../views/Home.vue" //异步加载的组件,这里不需要
//import List from "../views/List.vue" //异步加载的组件,这里不需要进行导入,所以要注释掉

const routes = [
    {
        path: "/",  //路径:        
        redirect: {
            name: "ListA" //重定向到路由名称为mylist的路由中,这样当浏览器输入的是:http://localhost:5173/ 则会重定向跳转到 http://localhost:5173/list
        }
    },
    {
        path: "/lista",  //路径
        //当路由被触发时,该组件才会被异步加载,举列:打开页面就不会加载所有的组件,而是根据当前页面需要的组件进行异步加载
        //这样可以减少初始加载时间,提升用户体验,同时也节省了不必要的资源消耗。
        name:"ListA",
        component: () => import("../views/ListA.vue")

    },
    {
        path: "/listb",  //路径
        //当路由被触发时,该组件才会被异步加载,举列:打开页面就不会加载所有的组件,而是根据当前页面需要的组件进行异步加载
        //这样可以减少初始加载时间,提升用户体验,同时也节省了不必要的资源消耗。
        name:"ListB",
        component: () => import("../views/ListB.vue")

    }  
]

//创建路由对象
const router = createRouter({
    //history:createWebHashHistory()   这种方式是按照hash路由模式来路由导航,这种路由模式的url地址会存在 /#/ 样式是:http://localhost:5173/#/list
    history: createWebHistory(),     //这种方式基于浏览器 history API 的路由模式,url的样式是:http://localhost:5173/list
    routes, //routes:routes的缩写

})

export default router //导出router路由对象//导出router路由对象

状态管理器:模块

/src/views/ListAModule.js  ListA.vue组件单独使用的状态管理器模块

//ListA.vue组件使用的vuex模块
import axios from 'axios'
const ListAModule = {
    namespaced: true, //开启命名空间:建议开启,开启的好处是可以vuex模块化开发中使用辅助函数,否则无法使用
    state() {
        return {
            name: "张三",
            datalist: []
        }
    },
    mutations: {
        changeName(state, strParams) {
            state.name = strParams
        },
        dataListInit(state, arrParams) {
            state.datalist = arrParams;
        }

    },
    actions: {
        async getDataList(store) {
            //异步
            const result = await axios({
                url: "https://m.maizuo.com/gateway?cityId=110100&pageNum=1&pageSize=10&type=1&k=7069698",
                headers: {
                    'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16992764191480200349024257"}',
                    'X-Host': 'mall.film-ticket.film.list'
                }
            })
            //同步:向mutations提交数据:触发dataListInit函数,并向函数传递了一个数组参数
            store.commit("dataListInit", result.data.data.films);
        }

    },
    getters: {
        filterDataList(state) {
            return (keyword) => {
                console.log(state.datalist);
                return state.datalist.filter(item => item.name.includes(keyword));
            }
        }

    }
}
export default ListAModule;

/src/views/ListBModule.js    ListB.vue组件单独使用的状态管理器模块

//ListB.vue组件使用的vuex模块
import axios from 'axios'
const ListBModule = {
    namespaced: true, //开启命名空间:建议开启,开启的好处是可以vuex模块化开发中使用辅助函数,否则无法使用
    state() {
        return {
            name: "李四",
            datalist: []
        }
    },
    mutations: {
        changeName(state, strParams) {
            state.name = strParams
        },
        dataListInit(state, arrParams) {
            state.datalist = arrParams;
        }

    },
    actions: {
        async getDataList(store) {
            //异步
            const result = await axios({
                url: "https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3777796",
                headers: {
                    'X-Client-Info': '{"a":"3000","ch":"1002","v":"5.2.1","e":"16992764191480200349024257","bc":"110100"}',
                    'X-Host': 'mall.film-ticket.cinema.list'
                }
            });
            console.log("获取数据")
            //同步:向mutations提交数据:触发dataListInit函数,并向函数传递了一个数组参数
            store.commit("dataListInit", result.data.data.cinemas);
        }

    },
    getters: {
        filterDataList(state) {
            return (intParams) => {
                return state.datalist.filter(item => item.eTicketFlag == intParams)
            }
        }

    }
}

export default ListBModule;

状态管理器:模块汇总

/src/store/index.js 状态管理器:汇总ListAModule与ListBModule模块

import axios, { Axios } from 'axios';
import { createStore } from 'vuex'

import ListAModule from '../views/ListAModule.js'
import ListBModule from '../views/ListBModule.js' //导入模块

const store = createStore({
    modules: {
        ListAModule,  //ListAModel:ListAModel简写  注册ListAModel模块
        ListBModule   //ListBModel:ListBModel简写  注册ListBModel模块
    }
});

export default store

注册路由器 和 状态管理器

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'


import router from "../src/router/index.js" //导入状态管理器js 
import store from "../src/store/index.js" //导入状态管理器js 


var app=createApp(App)

app.use(router);

app.use(store)  //注册vuex插件:状态管理器

app.mount("#app")

ListA.vue组件:电影列表

<template>
    <div>
        <div>
            姓名: {{ name }}
        </div>
        <input type="text" v-model.lazy="keyword"  placeholder="搜索">
        <ul>
            <li v-for="item in filterDataList(keyword)" :key="item.filmId">{{ item.name }}</li>
        </ul>
    </div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
    mounted() {
        if (this.datalist.length === 0) {
            this.getDataList();
        }
    },
    data() {
        return {
            keyword: "",
        }
    },
    methods: {
        ...mapMutations('ListAModule', ["changeName", "dataListInit"]),
        ...mapActions('ListAModule', ["getDataList"]),
    },
    computed: {
        ...mapState('ListAModule', ["name", "datalist"]),
        ...mapGetters('ListAModule', ["filterDataList"])
    }
}
</script>
<style scoped>
li {
    padding: 10px;
}
</style>

ListB.vue组件:影院列表

<template>
    <div>
        <!-- 采用辅助函数的方式从store中的state中取数 -->
        <div> 姓名:{{ name }}</div>
        <!-- 常规方式去store中的state中取数 -->
        <div> 姓名:{{ $store.state.ListAModule.name}}</div>
        <select v-model="type">
            <option :value="0">APP订票</option>
            <option :value="1">前台兑换</option>
        </select>
        <ul>
            <!-- 常规方式去store中的Getters(计算属性)中取数 -->
            <!-- <li v-for="item in $store.getters['ListBModule/filterDataList'](type)" :key="item.cinemaId"> {{ item.name }}</li> -->
            <!-- 采用辅助函数的方式从store中的state中取数 -->
            <li v-for="item in filterDataList(type)" :key="item.cinemaId"> {{ item.name }}</li>
        </ul>
    </div>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
    mounted() {       
        if (this.datalist.length === 0) {
            this.getDataList(); //采用辅助函数: ...mapActions('ListBModule', ["getDataList"]), 执行ListBModule模块中的getDataList方法

            //this.$store.dispatch("ListBModule/getDataList"); //采用常规方式执行ListBModule模块中的getDataList方法
        }      
    },
    data() {
        return {
            type:0

        }
    },
    methods: {
        ...mapMutations('ListBModule', ["changeName", "dataListInit"]), //将store中ListBModule模块的Mutations函数展开,在DOM中可以直接用:如changeName(),dataListInit() 在<script>中也可以直接用:如this.changeName(),this.dataListInit()
        ...mapActions('ListBModule', ["getDataList"]), //将store中ListBModule模块的Actions函数展开,在DOM中可以直接用:如getDataList() 在<script>中也可以直接用:如this.getDataList()
    },
    computed: {
        ...mapState('ListBModule', ["name", "datalist"]), //将store中的State数据展开,在DOM中可以直接用:如name 在<script>中也可以直接用:如this.name()
        ...mapGetters('ListBModule', ["filterDataList"])  //将store中ListBModule模块的Getters函数展开,在DOM中可以直接用:如filterDataList() 在<script>中也可以直接用:如this.filterDataList()
    }
}
</script>

效果图

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1198343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国际阿里云:无法访问ECS实例中的服务的排查方法!!!

操作场景 无法访问ECS实例中的服务可能有以下原因&#xff1a; 可能原因 排查方案 ECS实例的安全组未开放相应端口 检查ECS实例安全组规则 ECS实例中&#xff0c;该服务未启动/开启或服务对应端口未被监听 检查服务状态及端口监听状态 ECS实例内防火墙设置错误 检查ECS…

Dubbo从入门到上天系列第五篇:Dubbo3与JDK17不兼容问题展示

文章目录 一&#xff1a;JDK 与 Dubbo版本对应问题说明 1&#xff1a;问题1 2&#xff1a;问题2 二&#xff1a;Spring与JDK版本对应关系 1&#xff1a;对应关系详图 2&#xff1a;JDK与Major对应关系图 大神链接&#xff1a;作者有幸结识技术大神孙哥为好友&#xff0c…

SW如何显示样条曲线的控标

刚刚学习隔壁老王的sw画图时&#xff0c;怎么点都点不出样条曲线的控标&#xff0c;于是果断查询了一下解决方法&#xff0c;其实很简单&#xff0c;只不过是培训机构故意不说&#xff0c;叫你还解决不了&#xff0c;难受了就会花钱买他们的课了。毕竟如果学会了怎么解决问题了…

5G+智慧港口建设解决方案

一、智慧港口建设背景 智慧港口是随着时代进步发展起来的一种现代港口运输的新业态&#xff0c;它是以现代化基础设施为基础&#xff0c;促使大数据、云计算、物联网、移动互联网、智能控制等新一代信息技术与港口运输业务深度融合&#xff0c;以港口运输组织服务创新为动力&am…

【开源】基于Vue.js的生活废品回收系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目详细录屏 二、研究内容三、界面展示3.1 登录注册3.2 资源类型&资源品类模块3.3 回收机构模块3.4 资源求购/出售/交易单模块3.5 客服咨询模块 四、免责说明 一、摘要 1.1 项目介绍 生活废品回收系统是可持续发展的解决方案&#xff0c;旨…

高防IP是什么?有什么优势?

一.高防IP的概念 高防IP是指高防机房所提供的IP段&#xff0c;一种付费增值服务&#xff0c;主要是针对网络中的DDoS攻击进行保护。用户可以通过配置高防IP&#xff0c;把域名解析到高防IP上&#xff0c;引流攻击流量&#xff0c;确保源站的稳定可靠。 二.高防IP的原理 高防I…

Python异常处理:三种不同方法的探索与最佳实践

Python异常处理&#xff1a;三种不同方法的探索与最佳实践 前言 本文旨在探讨Python中三种不同的异常处理方法。通过深入理解各种异常处理策略&#xff0c;我们可以更好地应对不同的编程场景&#xff0c;选择最适合自己需求的方法。 异常处理在编程中扮演着至关重要的角色。合…

智慧城市数据中台建设方案:PPT全文51页,附下载

关键词&#xff1a;智慧城市解决方案&#xff0c;数据中台解决方案&#xff0c;智慧城市建设&#xff0c;数据中台技术架构&#xff0c;数据中台建设 一、智慧城市数据中台建设背景 智慧城市数据中台是在城市数字化转型和智能化升级的背景下提出的&#xff0c;旨在实现城市数…

ElasticSearch知识点

什么是ElasticSearch ElasticSearch: 智能搜索&#xff0c;分布式的搜索引擎&#xff0c;是ELK的一个非常完善的产品&#xff0c;ELK代表的是: E就是ElasticSearch&#xff0c;L就是Logstach&#xff0c;K就是kibana Elasticsearch是一个建立在全文搜索引擎 Apache Lucene基础…

腾讯云3年期轻量应用服务器优惠(薅羊毛教程)

腾讯云轻量应用服务器特价是有新用户限制的&#xff0c;所以阿腾云建议大家选择3年期轻量应用服务器&#xff0c;一劳永逸&#xff0c;免去续费困扰。腾讯云轻量应用服务器3年优惠可以选择2核2G4M和2核4G5M带宽&#xff0c;3年轻量2核2G4M服务器540元&#xff0c;2核4G5M轻量应…

封神教程:腾讯云3年轻量应用服务器老用户购买方法

腾讯云轻量应用服务器特价是有新用户限制的&#xff0c;所以阿腾云建议大家选择3年期轻量应用服务器&#xff0c;一劳永逸&#xff0c;免去续费困扰。腾讯云轻量应用服务器3年优惠可以选择2核2G4M和2核4G5M带宽&#xff0c;3年轻量2核2G4M服务器540元&#xff0c;2核4G5M轻量应…

vscode因为大文件而无限崩溃的问题,窗口意外终止(原因:“oom“,代码:“-536870904“

复制了一大堆的代码&#xff08;好几兆&#xff09;到一个文件里&#xff0c;然后就导致 vscode 卡死&#xff0c; 之后就算把该文件删掉了&#xff0c;打开vscode还是会默认打开该文件而卡死 解决办法&#xff1a; win R 输入 %appdata%/code/ 删除该文件夹下的 backups/ 文件…

【m98】webrtc vs2017构建带符号的debug库

调试有符号 调试 无符号 试试exe不输出到独立的文件? -】 直接输出到sln下面

在 Microsoft Word 中启用护眼模式

在 Microsoft Word 中启用护眼模式 在使用 Microsoft Word 365 或 Word 2019&#xff08;Windows&#xff09;版本时&#xff0c;启用护眼模式&#xff08;也称为“夜间模式”&#xff09;可以有效减轻屏幕亮度&#xff0c;有助于减少眼睛疲劳。以下是启用护眼模式的步骤&…

ChatGPT+Roblox,元宇宙的AI叙事逻辑#Leveling Up

MixCopilot 嗨&#xff0c;亲爱的听众朋友们&#xff01;欢迎收听我们的播客节目&#xff01;我是你们的主播&#xff1a;MixCopilot 混合副驾。今天我们要为大家带来的是我们的AI革命系列节目之一。这个系列节目聚焦于AI领域的一些最有影响力的建设者&#xff0c;他们将会讨论…

Leetcode -463.岛屿的周长 - 476.数字的补码

Leetcode Leetcode -463.岛屿的周长Leetcode - 476.数字的补码 Leetcode -463.岛屿的周长 题目&#xff1a;给定一个 row x col 的二维网格地图 grid &#xff0c;其中&#xff1a;grid[i][j] 1 表示陆地&#xff0c; grid[i][j] 0 表示水域。 网格中的格子 水平和垂直 方向…

数字化仪的超声波应用

超声波是频率大于人类听觉范围上限的声学声压&#xff08;声学&#xff09;波。超声波设备的工作频率为 20 kHz 至几千 MHz。表 1 总结了一些更常见的超声波应用的特征。每个应用中使用的频率范围都反映了实际情况下的平衡。提高工作频率可以通过提高分辨率来检测较小的伪影&am…

【刷题】力扣每日一题 : 381、2300、765

前言 本篇文章用于记录在做力扣每日一题的时候遇到的一些知识点以及自己的思路 381 题干 题目链接 我的思路及做题过程 思路1 我的想法是 记录每个字符串的字母出现个数 然后比较两个字符串是否有字母同时出现 class Solution { public:int judge(string s1, string s2…

RAG相关内容介绍

本文记录在查找RAG相关内容时所整合的一些资料与内容&#xff0c;还有一个组会报告的PPT 文章目录 定义LLM的知识更新难题 RAG是什么&#xff1f;-“开卷考试”RAG原理与技术RAG技术细节一、数据索引• 数据提取• 分块&#xff08;Chunking&#xff09;分块方式确定应用程序的…

本地编译安装 Minkowski Engine 报错 Cuda 版本 与 Pytorch 版本不匹配

编译 Cuda 版本 C 插件 Cuda 版本 与 Pytorch 版本不匹配解决方案 报错详情环境报错分析 报错详情 RuntimeError: The detected CUDA version (12.2) mismatches the version that was used to compile PyTorch (11.8). Please make sure to use the same CUDA versions.环境 …