【富文本编辑器实战】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 了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HugggingFace 推理 API、推理端点和推理空间相关模型部署和使用以及介绍

HugggingFace 推理 API、推理端点和推理空间相关模型部署和使用以及介绍。 Hugging Face是一家开源模型库公司。 2023年5月10日&#xff0c;Hugging Face宣布C轮1亿美元融资&#xff0c;由Lux Capital领投&#xff0c;红杉资本、Coatue、Betaworks、NBA球星Kevin Durant等跟投…

Java程序设计:选实验5 GUI初级应用

使用JLabel、JTextArea、JButton等控件实现句子的中译英demo&#xff0c;该demo包含四个文本框&#xff0c;在第一个文本框输入一句英文&#xff0c;在第二个和第三个文本框显示该句的英文翻译&#xff08;要求使用百度翻译API、有道翻译API或其他API中的两种&#xff1b;自行上…

深度学习记录--mini-batch gradient descent

batch vs mini-batch gradient descent batch&#xff1a;段&#xff0c;块 与传统的batch梯度下降不同&#xff0c;mini-batch gradient descent将数据分成多个子集&#xff0c;分别进行处理&#xff0c;在数据量非常巨大的情况下&#xff0c;这样处理可以及时进行梯度下降&…

Text:字体相关设置

效果如下&#xff1a; import QtQuickWindow {width: 640height: 480visible: truetitle: qsTr("Text")Text {id: t1text: "你好&#xff0c;世界&#xff01;"color: "#29acc0" /*字体颜色*/font.pixelSize: 40 /*字体大小*/font.family: &quo…

在 Python 中检查一个数字是否是同构数

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 同构数&#xff0c;又称为自守数或自同构数&#xff0c;是一类特殊的数字&#xff0c;它们具有一种有趣的性质&#xff1a;将其平方后的数字&#xff0c;可以通过某种方式重新排列得到原来的数字。本文将详细介绍…

以后要做GIS开发的话是学GIS专业还是学计算机专业好一些?

GIS开发其实严格来说分为前后端以及底层开发。不同的方向&#xff0c;代表了不同的开发语言。 所以大家首先要了解自己具体要做的岗位类型是什么&#xff0c;其次才是选择专业侧重点。 但是严格来说&#xff0c;选择某个专业&#xff0c;到就业方向这个过程&#xff0c;并不是…

(C++) list底层模拟实现

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 首先&#xff0c;list底层是一个带头双向循环链表&#xff0c;再一个&#xff0c;我们还要解决一个问题&#xff0c;list的迭代器&#xff0c;vector和string的迭代器可以直接&#xff0c;是因为他们的地址空间是连续的&…

【AJAX框架】AJAX入门与axios的使用

文章目录 前言一、AJAX是干什么的&#xff1f;二、AJAX的安装2.1 CDN引入2.2 npm安装 三、基础使用3.1 CDN方式3.2 node方式 总结 前言 在现代Web开发中&#xff0c;异步JavaScript和XML&#xff08;AJAX&#xff09;已经成为不可或缺的技术之一。AJAX使得网页能够在不刷新整个…

hadoop-common: CMake failed with error code 1

问题 在编译hadoop源码时遇到如下错误 hadoop-common: CMake failed with error code 1 看了这个错误表示一脸懵逼 排查 在mvn 的命令中增加 -X 和 -e mvn clean package -e -X -Pdist,native -DskipTests -Dmaven.javadoc.skip -Dopenssl.prefix/usr/local/bin/openssl 在…

3.C语言——函数

函数 1.什么是函数2.函数的分类1.库函数2.自定义函数 3.函数的参数1.实际参数&#xff08;实参&#xff09;2.形式参数&#xff08;形参&#xff09; 4.函数的声明1.同一个文件的函数声明2.多文件的函数声明 5.函数的调用6.函数的嵌套调用和链式访问1.嵌套调用2.链式访问 7.函数…

P1059 [NOIP2006 普及组] 明明的随机数————C++、Python

目录 [NOIP2006 普及组] 明明的随机数题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 解题思路Code——CCode——Python运行结果 [NOIP2006 普及组] 明明的随机数 题目描述 明明想在学校中请一些同学一起做一项问卷调查&#xff0c;为了实验的客观性&#xff0…

力扣 | 438. 找到字符串中所有字母异位词

滑动窗口解题 示例 在s里面控制一个p字符串长度的滑动窗口&#xff0c;统计该滑动窗口中的每种字符出现的次数 import java.util.ArrayList; import java.util.Arrays; import java.util.List;public class Problem_438_FindAnagrams {public List<Integer> findAnagram…

开放签开源工具版更新至1.1版本,进一步提升电子签名服务能力

本周开放签开源工具版增加了SDK与API能力&#xff0c;更新至1.1版本&#xff0c;使开放签电子签章工具能力进一步提升。 SDK将便于java用户直接使用CA证书颁发和签名能力。API接口采用HTTP&#xff08;S&#xff09;通讯&#xff0c;JSON报文格式&#xff0c;具有跨平台、跨语…

力扣hot100 最长有效括号 动态规划

Problem: 32. 最长有效括号 文章目录 思路Code 思路 &#x1f468;‍&#x1f3eb; 参考题解 Code ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) class Solution {public int longestValidParentheses(String s){int n s.length();…

electron使用rollup打包后,运行报错Could not dynamically require……

同学们可以私信我加入学习群&#xff01; 正文开始 分析解决总结 分析 这报错信息意思是rollup不支持动态的require&#xff0c;全部报错信息为&#xff1a; Could not dynamically require “./src/cat”. Please configure the dynamicRequireTargets or/and ignoreDynamic…

spring-boot项目,mybatis只读取了父模块的mapper目录,子模块的mapper目录读取不到

spring-boot项目&#xff0c;mybatis只读取了父模块的mapper目录&#xff0c;子模块的mapper目录读取不到 问题复现问题解决 问题复现 我的mybatis配置&#xff1a; 父模块mapper目录 子模块mapper目录 运行报错&#xff1a; 找不到子模块中的mapper配置 问题解决 debug…

做完十年数据分析后的思考与总结

种一棵树最好的时间是十年前&#xff0c;其次是现在。十年了&#xff0c;本次分享大多来自工作中的日常所思所想&#xff0c;欢迎自取。 01 数据分析的本质 数据是基础&#xff0c;分析才是重点。 行业内有专门的统计岗&#xff0c;就是只负责做好数据统计就可以了&#xff0…

第一篇【传奇开心果】Vant 开发移动应用:从helloworld开始

传奇开心果系列博文 博文系列目录Vant of Vue 开发移动应用示例博文目录一、从helloworld开始二、添加几个常用组件三、添加组件事件处理四、添加页面和跳转切换路由五、归纳总结知识点六、知识点示例代码 博文系列目录 Vant of Vue 开发移动应用示例 博文目录 一、从hellow…

Mybatis面试题(四)

MyBatis 面试题 26、Mapper 编写有哪几种方式&#xff1f; 第一种&#xff1a;接口实现类继承 SqlSessionDaoSupport&#xff1a;使用此种方法需要编写mapper 接口&#xff0c;mapper 接口实现类、mapper.xml 文件。 1、在 sqlMapConfig.xml 中配置 mapper.xml 的位置 <m…

IP改编国漫市场:繁荣背后的秘密,谁将成为下一个超级IP?

近年来IP改编已经是大众主流的趋向&#xff0c;原创剧本越来越少&#xff0c;现在市面上的动画影视大都是根据现有的IP进行二次创作&#xff0c;出来的效果也都参差不齐&#xff0c;比如说根据小说改编的《斗破苍穹》、《斗罗大陆》、《师兄啊师兄》&#xff0c;或者根据漫画改…