Vuex 状态管理

news2024/11/25 6:49:20

文章目录

  • Vuex
    • 概述
    • 安装
    • 单向数据流
    • Vuex核心概念
      • State
        • mapState 辅助函数
        • 扩展运算符
      • Getter
        • mapGetters 辅助函数
      • Mutation
        • 提交载荷
        • 提交载荷对象
        • 对象风格提交
        • 使用常量替代mutation事件类型
      • Action
        • 异步分发
      • Module
        • 命名空间

Vuex

概述

Vuex 是一个状态管理库,用于管理 Vue.js 应用程序中的共享状态。它可以帮助你在应用程序中保持数据的一致性和可预测性。

Vuex包括以下几个核心概念:

  • state:存储应用程序的状态数据。
  • getters:提供一种计算派生状态的方式,类似于Vue.js中的计算属性。
  • mutations:用于修改状态的方法,但是只能进行同步操作。
  • actions:用于提交mutations,可以进行异步操作。
  • modules:将store拆分为模块,每个模块都有自己的state、getters、mutations和actions。

Vuex 官方文档

安装

npm install vuex@next --save

单向数据流

<script >
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++;
    }
  }
}
</script>

<template>
  <button @click="count++">{{ count }}</button>
</template>

在这里插入图片描述

这是一个单向数据流:

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

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

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

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

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

Vuex核心概念

在这里插入图片描述

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)

Vuex 和单纯的全局对象有以下两点不同:

  • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  • 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

State

用于存储应用程序的状态数据。

  • 在Vue组件中,通过 this.$store 访问store实例。
  • 通过$store.state获取状态对象。
  • Vuex 的状态存储是响应式的。

支持Vuex

import store from "./store";

const app = createApp(App);
// 将 store 实例作为插件安装
app.use(store);
app.mount("#app");

定义store对象

import { createStore } from "vuex";

const store = createStore({
  state() {
    return {
      count: 0,
    };
  }
});
export default store;

使用store

<template>
    <p>count: {{ $store.state.count }}</p>
    <!-- 不推荐 -->
    <button @click="$store.state.count++">修改count</button>
</template>

mapState 辅助函数

使用mapState辅助函数可以简化代码,如:将{{ $store.state.count }}简化为{{ count }}

<script >
import { mapState } from 'vuex'

export default {
  //mapState传对象
  computed: mapState({
    //简化代码:
    //方式一;使用箭头函数
    // count: state => state.count,
      
    //方式二:字符串参数,等价于`state => state.count`
    count: "count"
  })
}
</script>

<template>
  <p>count: {{ $store.state.count }}</p>
  <p>{{ count }}</p>
  <button @click="$store.state.count++">修改count</button>
</template>

当映射的计算属性的名称与 state 的子节点名称相同时,也可以给 mapState 传一个字符串数组:

<script >
import { mapState } from 'vuex'

export default {
  //mapState传数组
  computed: mapState(["count", "msg"])
}
</script>

<template>
  <p>count: {{ $store.state.count }}</p>
  <p>{{ count }}</p>
  <p>{{ msg }}</p>
  <button @click="$store.state.count++">修改count</button>
</template>

扩展运算符

computed属性在Vue组件中只能有一个,可以使用对象扩展运算符兼容局部计算属性。

<script >
import { mapState } from 'vuex'

export default {
  data() {
    return {
      num: 10
    }
  //对象扩展运算符
  computed: {
    addNum() {
      return this.num + 5;
    },
    ...mapState(["count", "msg"])
  }
}
</script>

<template>
  <p>count: {{ $store.state.count }}</p>
  <p>{{ count }}</p>
  <p>{{ msg }}</p>
  <p>{{ addNum }}</p>
  <button @click="$store.state.count++">修改count</button>
</template>

Getter

提供一种计算派生状态的方式,类似于Vue.js中的计算属性,例如对列表进行过滤并计数。

从 Vue 3.0 开始,getter的结果不再像计算属性一样会被缓存起来。

定义store对象

import { createStore } from "vuex";

const store = createStore({
  state() {
    return {
      msg: "hello world",
    };
  },
  getters: {
    reverseMsg(state) {
      return state.msg.split("").reverse().join("");
    },
    reverseMsgLength(state, getters) {
      return getters.reverseMsg.length;
    },
  }
});
export default store;

在Vue中使用

<template>
  <p>{{ $store.getters.reverseMsg }}</p>
  <p>{{ $store.getters.reverseMsgLength }}</p>
</template>

mapGetters 辅助函数

可以通过mapGetters辅助函数将getter映射到计算属性中。

<script >
import { mapState, mapGetters } from 'vuex'

export default {
  data() {
    return {
      num: 10
    }
  },
  computed: {
    addNum() {
      return this.num + 5;
    },
    ...mapState(["count", "msg"]),
    ...mapGetters(["reverseMsg", "reverseMsgLength"])
  }
}
</script>

<template>
  <p>{{ $store.getters.reverseMsg }}</p>
  <p>{{ $store.getters.reverseMsgLength }}</p>
  <p>{{ reverseMsg }}</p>
  <p>{{ reverseMsgLength }}</p>
</template>

Mutation

用于修改状态的方法,但是只能进行同步操作。

  • 使用$store.commit()方法触发mutation函数。

定义store对象

import { createStore } from "vuex";

const store = createStore({
  state() {
    return {
      count: 0
    };
  },
  mutations: {
    //修改状态的方法
    increment(state) {      
      state.count++;
    },
  },
});
export default store;

在Vue中使用

<script >
export default {
  methods: {
    increment() {
      //使用`$store.commit`触发方法
      this.$store.commit("increment");
    }
  }
}
</script>

<template>
  <p>count: {{ $store.state.count }}</p>
  <button @click="increment">修改count</button>
</template>

提交载荷

你可以向 store.commit 传入额外的参数,即 mutation 的载荷(payload)

在store对象中定义

mutations: {
    add(state, num) {
        state.count += num;
    },
},

使用

<script >
export default {
  data() {
    return {
      num: 10
    }
  },
  methods: {
    add() {
      this.$store.commit("add", 5);
    }
  }
</script>

<template>
  <p>count: {{ $store.state.count }}</p> 
  <button @click="add">修改num</button>
</template>

提交载荷对象

在store对象中定义

mutations: {
    add2(state, payload) {
        state.count += payload.num;
    },
}

使用

<script >
export default {
  methods: {
    add2() {
      this.$store.commit("add2", { num: 10 });
    }
  }
}
</script>

<template>
  <p>count: {{ $store.state.count }}</p>
  <button @click="add2">修改num</button>
</template>

对象风格提交

this.$store.commit({
    type: "add",
    num: 20
})

使用常量替代mutation事件类型

定义mutation-type.js文件

export const ADD = "add";

在store对象中使用

import { createStore } from "vuex";
import { ADD } from "../mutation-type";

const store = createStore({
  state() {
    return {
      count: 0
    };
  },
  mutations: {
    [ADD](state, num) {
      state.count += num;
    }
  },
});
export default store;

Action

用于提交mutations,可以进行异步操作。

  • 使用$store.dispatch()方法触发actions中定义的函数。

在store对象中定义

import { createStore } from "vuex";

const store = createStore({
  state() {
    return {
      count: 0
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit("increment");
    },
  },
});
export default store;

在Vue中使用

<script >
export default {
  methods: {
    increment2() {
      this.$store.dispatch("increment");
    }
  }
}
</script>

<template>
  <p>count: {{ $store.state.count }}</p>
  <button @click="increment2">修改num(actions)</button>
</template>

**使用参数解构简化代码 **

actions: {
    increment({ commit }) {
        commit("increment");
    },
},

异步分发

在store对象中定义

import { createStore } from "vuex";

const store = createStore({
  state() {
    return {
      count: 0,
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit("increment");
      }, 1000);
    },
  },
});
export default store;

在Vue中使用

<script >
export default {
  methods: {
    incrementAsync() {
      this.$store.dispatch("incrementAsync")
    }
  }
}
</script>

<template>
  <p>count: {{ $store.state.count }}</p>
  <button @click="incrementAsync">修改num(异步)</button>
</template>

Module

将store拆分为模块,每个模块都有自己的state、getters、mutations和actions。

新建user模块

const user = {
  state() {
    return {
      userName: "xiaoming",
    };
  },
  getters: {
    userNameAge(state, getters, rootState) {
      return state.userName + " 18岁";
    },
  },
  mutations: {
    updateUserName(state) {
      state.userName = "小明";
    },
  },
};
export default user;

添加子模块

import { createStore } from "vuex";
import user from "./user";

const store = createStore({
  modules: {
    user,
  },
});
export default store;

访问user模块

<script >
export default {
  methods: {
    changeUserName() {
      console.log(this.$store);
      this.$store.commit("updateUserName");
    }
  }
}
</script>

<template>
  <p>{{ $store.state.user.userName }}</p>
  <button @click="changeUserName">修改userName</button>
  <p>{{ $store.getters.userNameAge }}</p>
</template>

命名空间

如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

新建Student的store对象

const student = {
  namespaced: true, //开启命名空间
  state() {
    return {
      userName: "xiaohei",
    };
  },
  getters: {
    userNameAge(state, getters, rootState) {
      return state.userName + " 8岁";
    },
  },
  mutations: {
    updateStudentName(state) {
      state.userName = "小黑";
    },
  },
};
export default student;

在Vue3中使用

<script >
export default {
  methods: {
    changeStudentName() {
      this.$store.commit("student/updateStudentName");
    }
  }
</script>

<template>
  <h2>student模块</h2>
  <p>{{ $store.state.student.userName }}</p>
  <button @click="changeStudentName">修改studentName</button>
  <p>{{ $store.getters["student/userNameAge"] }}</p>
</template>

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

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

相关文章

CRM系统是什么?为什么使用它?

CRM系统是什么&#xff1f;为什么使用它&#xff1f;这篇来简单说下&#xff0c;CRM系统是什么&#xff1f;能帮助我们做什么&#xff1f;有什么好处&#xff1f; 01 CRM系统是什么&#xff1f; 我总结了7种关于CRM的概念&#xff0c;任意一个解释得其实都没什么问题&#xff…

【数据结构】核心数据结构之二叉堆的原理及实现

1.大顶堆和小顶堆原理 什么是堆 堆&#xff08;Heap&#xff09;是计算机科学中一类特殊的数据结构&#xff0c;通常是一个可以被看作一颗完全二叉树的数组对象。 完全二叉树 只有最下面两层节点的度可以小于2&#xff0c;并且最下层的叶节点集中在靠左连续的边界 只允许最后…

2023FL Studio最新中文版电子音乐、混音和母带制作DAW

水果具有独特的底层逻辑&#xff0c;其开创了编曲“块”的思维。用FL Studio编曲的流程是在把一个样式编辑好&#xff0c;然后将编辑好的样式当做音频块&#xff0c;在播放列表中像“搭积木”一样任意编排&#xff0c;形成一首歌&#xff0c;这种模式非常利于电子音乐编曲。 2…

Apinto V0.12 发布:新增流量镜像与 Mock 插件,路由特性更丰富!

Hello~ 各位开发者朋友们好呀&#xff0c; Eolink 旗下开源网关 Apinto 本周又更新啦&#xff01;这次的更新我们给大家带来了 2个好用的插件&#xff0c;且目前已经支持静态资源路由了&#xff01;希望新的功能能让大家的开发工作更加高效 &#xff5e; 1、新增流量镜像插件 …

学习streamlit-1

Streamlit A faster way to build and share data apps streamlit在几分钟内就可以将数据脚本转换为可共享的web应用程序&#xff0c;并且是纯python编程&#xff0c;无需前端经验。 快速开始 streamlit非常容易上手&#xff0c;运行demo只需2行代码&#xff1a; pip install…

0306spring--复习

一&#xff0c;spring是什么 Spring是一个轻量级的控制反转&#xff08;IOC&#xff09;和面向切面编程&#xff08;AOP&#xff09;的容器框架 理念&#xff1a;使现有的技术更加容易使用&#xff0c;本身是一个大杂烩&#xff0c;整合了现有的技术框架 优点&#xff1…

Windows系统利用Qemu仿真ARM64平台

Windows系统利用Qemu仿真ARM64平台0 写在最前1 Windows安装Qemu1.1 下载Qemu1.2 安装Qemu1.3 添加环境变量1.4测试安装是否成功2. Qemu安装Ubuntu-Server-Arm-642.1 安装前的准备2.2 安装Ubuntu server arm 64位镜像3 Windows配置Qemu网络和传输文件3.1 参考内容3.2 Windows安装…

正版Scrivener 3 论文/小说写作工具神器软件

一款非常优秀的写作软件&#xff0c;提供了各种写作辅助功能&#xff0c;如标注多个文档、概述介绍、全屏幕编辑、快照等&#xff0c;能够轻松、便捷的辅助作者从作品构思、搜集资料、组织结构、增删修改到排版输出的整个写作流程。 作为一个专业的写作软件&#xff0c;Scriven…

spring 的invokeBeanFactoryPostProcessors()

在spring启动过程中有个10多个关键的方法其中invokeBeanFactoryPostProcessors&#xff08;&#xff09;在函数在BeanDefinition完全加载后执行&#xff0c;实现的是spring bean的后置增强器BeanFactoryPostProcessor。 BeanFactoryPostProcessor在bean的生命周期中&#xff0…

企业移动内容管理(MCM)

1.什么是移动内容管理 &#xff08;MCM&#xff09; 移动内容管理 &#xff08;MCM&#xff09; 是指在组织中使用的移动设备上分发和管理企业文件的过程&#xff0c;以确保授权用户可以通过批准的设备安全地访问所需的资源。MCM 允许 IT 管理员在其组织员工使用的智能手机、平…

音频基础知识简述 esp-sr 上手指南

此篇博客先对音频基础知识进行简要叙述&#xff0c;然后帮助读者入门 esp-sr SDK。 1 音频的基本概念 1.1 声音的本质 声音的本质是波在介质中的传播现象&#xff0c;声波的本质是一种波&#xff0c;是一种物理量。 两者不一样&#xff0c;声音是一种抽象的&#xff0c;是声…

Vue学习笔记(6)

6.1 组件 6.1.1 什么是组件 Vue的组件是可复用的Vue实例&#xff0c;它可以封装HTML元素和 CSS样式以及与之相关的JavaScript行为。每个组件都有自己的作用域&#xff0c;因此它可以避免全局作用域中的命名冲突&#xff0c;并且可以方便地在不同的Vue实例中重复使用。组件的结…

2023年武汉安全员C证报考条件、流程、报名时间是什么?启程别

2023年武汉安全员C证报考条件、流程、报名时间是什么&#xff1f;启程别 安全员C建筑施工企业专职安全生产管理人员&#xff0c;是指在企业专职从事安全生产管理工作的人员&#xff0c;包括企业安全生产管理机构的负责人及其工作人员和施工现场专职安全生产管理人员。武汉安全员…

Firewall App Blocker v1.7 防火墙管理设置工具多语言版

Firewall App Blocker 是一款由 BlueLife 与 Velociraptor 开发的免费且功能强大的防火墙设置软件。在 Windows 操作系统中,您可以使用 Windows 防火墙来阻止或解除阻止某些应用程序的联网,然而微软并没有为 Windows 防火墙提供一个易于使用的界面,来让用户使用其强大的功能…

高斯分布、高斯混合模型、EM算法详细介绍及其原理详解

相关文章 K近邻算法和KD树详细介绍及其原理详解朴素贝叶斯算法和拉普拉斯平滑详细介绍及其原理详解决策树算法和CART决策树算法详细介绍及其原理详解线性回归算法和逻辑斯谛回归算法详细介绍及其原理详解硬间隔支持向量机算法、软间隔支持向量机算法、非线性支持向量机算法详细…

【备战面试】每日10道面试题打卡-Day5

本篇总结的是计算机网络知识相关的面试题&#xff0c;后续也会更新其他相关内容 文章目录1、计算机网络的各层协议及作用是什么&#xff1f;2、简述一下DNS的工作流程3、TCP与UDP有什么区别&#xff1f;4、TCP协议如何保证可靠传输5、拥塞控制机制是什么&#xff1f;6、HTTP 与…

朋友去华为面试,轻松拿到26K的Offer,羡慕了......

最近有朋友去华为面试&#xff0c;面试前后进行了20天左右&#xff0c;包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说&#xff0c;80%的人都会栽在第一轮面试&#xff0c;要不是他面试前做足准备&#xff0c;估计都坚持不完后面几轮面试。 其实&…

应用层与传输层~

文章目录应用层自定义应用层协议什么是自定义应用层协议自定义方式运输层运输层概述运输层特点运输层协议UDP协议UDP的特点UDP首部格式校验规则TCP协议TCP的特点TCP协议段格式TCP的性质确认序号超时重传连接管理三次握手四次挥手TCP的状态滑动窗口流量控制拥塞控制延迟应答捎带…

linux笔记(10):ubuntu环境下,基于SDL2运行lvgl+ffmpeg播放mp4

文章目录1.ubuntu安装ffmpeg1.1 源码安装1.1 克隆ffmpeg源码1.2 配置编译条件&#xff0c;编译&#xff0c;安装1.2 直接安装依赖包2.下载lvgl源码2.1 测试原始代码2.2 运行lv_example_ffmpeg_2()例程2.2.1 配置 LV_USE_FFMPEG 为 12.2.2 lv_example_ffmpeg_2()替换lv_demo_wid…

C++核心知识(二)—— 类和对象(类的封装)、对象的构造和析构(浅拷贝、深拷贝、explicit、动态分配内存)

【上一篇】C核心知识&#xff08;一&#xff09;—— C概述、C对C的扩展(作用域、struct类型、引用、内联函数、函数默认参数、函数占位参数、函数重载)【下一篇】C核心知识&#xff08;三&#xff09;—— 静态成员(变量、函数、const成员)、面向对象模型(this指针、常函数、常…