【富文本编辑器实战】03 Vuex 的配置编写

Vuex 的配置编写

目录

  • Vuex 的配置编写
    • Vuex 是什么?
    • 什么是“状态管理模式”?
    • 什么情况下我应该使用 Vuex?
    • 安装 Vuex
    • 开始使用 Vuex
      • Action 文件
      • Mutations-types 文件
      • Mutation 文件
      • Index

Vuex 是什么?

这里我们来看看官方网站是如何介绍 Vuex 的:

提示

这是与 Vue 3 匹配的 Vuex 4 的文档。如果您在找与 Vue 2 匹配的 Vuex 3 的文档,请在这里查看。

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

什么是“状态管理模式”?

让我们从一个简单的 Vue 计数应用开始:

const Counter = {// 状态data () {return {count: 0}},// 视图template: `<div>{{ count }}</div>`,// 操作methods: {increment () {this.count++}}
}createApp(Counter).mount('#app')

这个状态自管理应用包含以下几个部分:

  • 状态,驱动应用的数据源;
  • 视图,以声明方式将状态映射到视图;
  • 操作,响应在视图上的用户输入导致的状态变化。

以下是一个表示“单向数据流”理念的简单示意:

在这里插入图片描述

但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

  • 多个视图依赖于同一状态。
  • 来自不同视图的行为需要变更同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!

通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。

这就是 Vuex 背后的基本思想,借鉴了 Flux、Redux 和 The Elm Architecture。与其他模式不同的是,Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。

如果你想交互式地学习 Vuex,可以看这个 Scrimba 上的 Vuex 课程,它将录屏和代码试验场混合在了一起,你可以随时暂停并尝试。

在这里插入图片描述

什么情况下我应该使用 Vuex?

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。引用 Redux 的作者 Dan Abramov 的话说就是:

Flux 架构就像眼镜:您自会知道什么时候需要它。

安装 Vuex

我们可以使用下面的方式来安装 Vuex:

使用 npm 包管理器安装:

npm install vuex@next --save

使用 Yarn 包管理器安装:

yarn add vuex@next --save

在这里我们选择 npm 安装:

在这里插入图片描述

开始使用 Vuex

安装完成之后,就可以开始使用 vuex 了。我们先在 /src 中创建 /store 文件夹,并创建 js 文件 action.js , index.js , mutations-types.js , mutations.js。如下图所示:

在这里插入图片描述

新建目录结构如上图。从文件名可以看出其对应的作用,下面我们来编写对应的代码。

Action 文件

即图中的 action.js 文件。里面存放着各个 action,每个 action 都对应一个 mutation,下面是 action.js 文件的完整代码:

export default {// 展示下拉框showDropList({ commit }, data) {commit("SHOW_DROP_LIST", data);},// 更新编辑区内容updateContent({ commit }, data) {commit("UPDATE_CONTENT", data);},// 更新选择的值updateSelectValue({ commit }, data) {commit("UPDATE_SELECTED_VALUE", data);},// 更新菜单状态updateMenuStatus({ commit }, data) {commit("UPDATE_MENU_STATUS", data);},// 执行命令execCommand({ commit }, data) {commit("EXEC_COMMAND", data);},// 获取节点位置getNodePosition({ commit }, data) {commit("NODE_POSITION", data);},// 切换视图changeView({ commit }, data) {commit("CHANGE_VIEW", data);},
};

Mutations-types 文件

为了让整个项目的 mutation 可以很方便的查看和管理,我们将全部的 Mutation 事件类型的名字使用常量来代替,并将它们单独存放在一个文件中,对外提供导出接口。

mutations-types.js 代码内容如下:

export const SHOW_DROP_LIST = "SHOW_DROP_LIST";
export const UPDATE_CONTENT = "UPDATE_CONTENT";
export const UPDATE_SELECTED_VALUE = "UPDATE_SELECTED_VALUE";
export const UPDATE_MENU_STATUS = "UPDATE_MENU_STATUS";
export const EXEC_COMMAND = "EXEC_COMMAND";
export const CHANGE_VIEW = "CHANGE_VIEW";
export const NODE_POSITION = "NODE_POSITION";

在 action 中提交的 mutation 的名字,和这里的名字是保持一致的。

Mutation 文件

在这个文件中,定义了很多 mutation 用于改变 store 中的数据。在 action 中提交的 mutation 都将在这里真正生效。

首先,我们需要从mutations-types 中导入 mutation 的事件名称。这里使用对象结构的方式操作:

mutations.js 代码内容如下:

// 导入事件类型
import {// 下拉框事件类型SHOW_DROP_LIST,// 更新编辑区内容事件类型UPDATE_CONTENT,// 更新选择的值事件类型UPDATE_SELECTED_VALUE,// 更新菜单状态事件类型UPDATE_MENU_STATUS,// 执行命令事件类型EXEC_COMMAND,// 获取节点位置事件类型NODE_POSITION,// 切换视图事件类型CHANGE_VIEW,
} from "./mutations-types";// 定义处理各个事件类型的回调函数
export default {[SHOW_DROP_LIST]({ menuBar }, data) {// 下拉框事件类型对回调函数for (let menu in menuBar) {if (menuBar[menu].showDropList !== undefined) {if (data && data.name === menu) {menuBar[menu].showDropList = data.display;} else {menuBar[menu].showDropList = false;}}}},[UPDATE_CONTENT](state, data) {// 更新编辑区内容事件类型state.content = data;},[UPDATE_MENU_STATUS]({ menuBar }, data) {// 更新菜单状态事件类型if ("all" in data) {for (let menu in menuBar) {menuBar[menu].status = data.all;}return;}for (let name in data) {if (menuBar[name].showStatus) {menuBar[name].status = data[name];} else {menuBar[name].status = "default";}}},[UPDATE_SELECTED_VALUE]({ menuBar }, data) {// 更新选择的值事件类型menuBar[data.name].value = data.value;},[EXEC_COMMAND](state, data) {// 执行命令事件类型state.command = data;},[CHANGE_VIEW](state, data) {// 切换视图事件类型state.sourceView = data;},[NODE_POSITION](state, data) {// 获取节点位置事件类型state.position = {top: data.top,right: data.right,bottom: data.bottom + document.body.scrollTop,left: data.left,};},
};

Index

这个文件是保存数据的地方,状态数据的改变最终都会作用到里面的数据。 store 对象的实例也由这个文件导出。

index.js 的代码内容如下:

import { createStore } from "vuex";
// 导入一些依赖模块
import mutations from "./mutations";
import action from "./action";
import Menu from "@/config/menu";
import Config from "@/config/index";let menuBar = {}; // 菜单栏对象
let menu = Menu.getMenu(); // 获取全部菜单项配置信息
let config = Config.getConfig(); // 获取全部配置项
let viewMenu = config.viewMenu; // 获取可见的菜单项viewMenu.forEach(function (name) {menuBar[name] = {};// 是否有下拉框if (menu[name].dropList) {menuBar[name].value = "";menuBar[name].showDropList = false;} else {// 是否展示状态if (menu[name].showStatus) {menuBar[name].showStatus = true;}menuBar[name].status = "default";}
});export default createStore({state: {// 编辑区域内容content: config.container.content,// 菜单栏对象,包含菜单项状态数据menuBar,// 是否源码视图sourceView: false,//执行的命令command: {name: "",value: "",},//存放位置信息position: {top: 0,right: 0,bottom: 0,left: 0,},},getters: {},mutations: mutations,actions: action,modules: {},
});

以上所有操作完成之后,我们的 vuex 就配置完成了。不过目前还不能在组件中使用,因为还没将它注入到组件中去。在组件中使用 vuex 的方式有两种,一种是在每个单独的组件中都实例化一个 store 对象,然后对 store 实例对象进行操作。另外一种方式是通过在根组件处注入 store 实例,其他所有子组件可通过 this.$store 来访问到 store 实例对象,并进行操作。推荐使用第二种方式,更加简单方便。

我们修改一下入口文件 src/main.js,注册 Vuex 实列 srore 对象:

import { createApp } from 'vue'
import App from './App.vue'
import store from './store';createApp(App).use(store).mount('#app')

ok,这样我们的项目就引入了 Vuex 了。

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

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

相关文章

《游戏-02_2D-开发》

基于《游戏-01_2D-开发》&#xff0c; 继续制作游戏&#xff1a; 首先给人物添加一个2D重力效果 在编辑的项目设置中&#xff0c; 可以看出unity默认给的2D重力数值是-9.81&#xff0c;模拟现实社会中的重力效果 下方可以设置帧率 而Gravity Scale代表 这个数值会 * 重力 还…

// doesn‘t exist

- // doesnt exist 13.3 赋给派生类引用,将发生什么情况呢?派生类引用能够为基对象调用派生类方法,这样做将出现问题。例 如,将RatedPlayer :: Rating()方法用于TableTennisPlayer对象是没有意义的,因为TableTennisPlayer对象没 有rating成员。 如果基类引用和指针可以指向…

webpack 中的loader 和plugin的区别

Loader: 作用&#xff1a; Loader 用于在模块加载时对文件进行转换。它是一个转换器&#xff0c;将文件从一种形式转换为另一种形式&#xff0c;例如&#xff0c;将 ES6 语法的 JavaScript 文件转换为能够在浏览器中运行的普通 JavaScript。使用场景&#xff1a; Loader通常被配…

Addressables(2) ResourceLocation和AssetReference

IResourceLocation var op Addressables.LoadResourceLocationsAsync(key); var result op.WaitForCompletion(); 把加载的Key塞进去&#xff0c;不难看出&#xff0c;IResourceLocation可以用来获得资源的详细信息 很适合用于更新分析&#xff0c;或者一些检查工具 AssetR…

Eureka使用详解

介绍主要特点主要功能与常用服务注册中心的比较Eureka与Zookeeper的区别和联系Eureka与Nacos的区别与联系Eureka与Consul的区别与联系 安装部署Eureka与CAP理论Eureka实现实时上下线Eureka常用注解Eureka架构模式 介绍 Eureka是一个基于REST的服务&#xff0c;主要用于AWS云中…

logstack 日志技术栈-05-windows10 安装 Elasticsearch elasticsearch-8.11.1 实战笔记

安装 Elasticsearch elasticsearch-8.11.1 下载 访问 Elasticsearch 下载页面 解压下载的压缩文件到你选择的目录。 运行 进入 Elasticsearch 目录&#xff0c;运行 bin/elasticsearch.bat 启动 Elasticsearch。 验证 elaasticsearch的默认访问路径是localhost:9200&…

HTTP 认证方式

目录 1.HTTP认证方式2.Python中 HTTP 认证方式的使用 本文主要介绍HTTP 认证方式有哪些及在Python中的基本使用方式。 1.HTTP认证方式 HTTP认证方式主要有以下几种&#xff1a; 基本认证&#xff08;Basic Authentication&#xff09;&#xff1a;客户端将用户名和密码进行B…

一文读懂「RAG,Retrieval-Augmented Generation」检索增强生成

Retrieval-Augmented Generation&#xff08;RAG&#xff09;作为机器学习和自然语言处理领域的一大创新&#xff0c;不仅代表了技术的进步&#xff0c;更在实际应用中展示了其惊人的潜力。 RAG结合了检索&#xff08;Retrieval&#xff09;和生成&#xff08;Generation&#…

Flutter 页面嵌入 Android原生 View

前言 文章主要讲解Flutter页面如何使用Android原生View&#xff0c;但用到了Flutter 和 Android原生 相互通信知识&#xff0c;建议先看完这篇讲解通信的文章 Flutter 与 Android原生 相互通信&#xff1a;BasicMessageChannel、MethodChannel、EventChannel-CSDN博客 数据观…

pdf拆分成各个小pdf的方法

背景:由于某些缘故,一个大的pdf需要拆分成页数少的pdf,或者pdf需要去掉指定页,那么就有必要对pdf进行重新编辑,这里需要用到一个库,直接进行操作即可。 当使用Python时,可以使用PyMuPDF库来拆分PDF文件。以下是一个示例代码, import fitz # PyMuPDF def split_pdf(i…

禅道的安装及使用流程

目录 一.安装 1.下载禅道安装包​http://www.zentao.net/ 2.选择禅道开源版 3.选择需要下载的安装包&#xff08;注意&#xff1a;下载的安装包必须放在根目录&#xff0c;不能移动&#xff09; 4.将下载的安装包双击进行解压&#xff1b;解压后的文件为d:\xampp&#xff1b…

sfml使用opengl着色器实现2d水面波浪

SFML中使用GLSL着色器来绘制水波。 效果 代码 #include <SFML/Graphics.hpp> #include <iostream>int main() {const int WIDTH = 800;

(南京观海微电子)——TCON介绍

TCON板详细介绍 TCON又称&#xff1a;逻辑板&#xff0c;控制板&#xff0c;在液晶电视里的作用和CRT中的视放板相当&#xff0c;但有本质的区别&#xff0c;逻辑板不是一个纯粹的信号放大器&#xff0c;它输入是LVDS格式信号&#xff0c;而不是RGB。逻辑板的作用是把数字板送来…

python进程间通信——命名管道(Named Pipe、FIFO)

文章目录 Python中的命名管道&#xff1a;深入理解进程间通信1. 命名管道简介2. 创建和删除命名管道3. 写入命名管道4. 读取命名管道5. 示例&#xff1a;进程间通信write_to_pipe.pyread_from_pipe.py测试运行 6. 注意事项和限制命名管道的半双工机制命名管道读写任意一方未打开…

记录一次QT乱码问题

问题描述 在敲陆文周的书《QT5开发及实例》的示例代码时&#xff0c;出现乱码&#xff0c;如下图所示 具体代码如下 Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ui->treeWidget->clear();int groupSize 2;int ite…

Pyro —— Velocity Voxel Scale

Velocity Voxel Scale是H19.5引入的新参数&#xff0c;该参数可单独定义volume和速度体素&#xff1b;根据参数设置&#xff0c;可观察到模拟时间的显著变化&#xff1b; Velocity Voxel Scale对DOP和SOP均可用&#xff1b;对DOP设置&#xff0c;该参数在Smoke Object&#xf…

js 小数精确计算 (mathjs / decimal.js)

mathjs import { all, create } from "mathjs";let mathjs create(all, {precision: 14,number: "BigNumber", });/**加法 */ export function jia(left: any, right: any) {return mathjs.floor(Number(mathjs.add(mathjs.bignumber(left), mathjs.bign…

Docker(四)操作容器

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; 操作 Docker 容器 容器是 Docker 又一核心概念。 简单的说&#xff0c;容器是独立运行的一个或一组应用&#xff0c;以及它们的运行态环境…

FreeType和HarfBuzz入门示例

最近在了解字体渲染的一些东西&#xff0c;其中不可避免的需要到这两个库。现在写个入门示例记录一下。 一、FreeType和HarfBuzz介绍 1.1 FreeType FreeType 是一个开源的字体引擎&#xff0c;它提供了一套用于渲染字体的 API。FreeType 支持多种字体格式&#xff0c;包括 True…

LLMs之Cheshire-Cat :Cheshire-Cat (Stregatto)的简介(构建自定义人工智能的框架)、安装、使用方法之详细攻略

LLMs之Cheshire-Cat &#xff1a;Cheshire-Cat (Stregatto)的简介(构建自定义人工智能的框架)、安装、使用方法之详细攻略 目录 Cheshire-Cat (Stregatto)的简介 1、文档和资源 2、为什么使用Cat Cheshire-Cat (Stregatto)的安装和使用方法 1、安装 2、最小插件示例 Che…