写点什么

快速学一遍 vue 的状态管理模式 -- Vuex

用户头像
空城机
关注
发布于: 2021 年 04 月 05 日
快速学一遍vue的状态管理模式 -- Vuex

Vuex 介绍

在制作工程量比较大的 vue 项目时,经常会遇到各个组件需要操作调用相同的数据的情况。


在应用时,我们可以采用父子组件之间相互传值采用 props 来进行数据的获取和传递,或者使用 store 模式。但是数据量越大,需要管理的数据源越多,那就比较适合 vuex 的使用了。


vuex 中文官网:https://vuex.vuejs.org/zh/


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

普通状态管理模式

一般而言状态自管理应用包含以下几个部分:


  • state,驱动应用的数据源;

  • view,以声明方式将 state 映射到视图;

  • actions,响应在 view 上的用户输入导致的状态变化。



但是当项目中有多个组件要调用和修改这些数据状态时,这种单向的数据流结构就很容易被破坏


原因如下:


  • 多个视图依赖于同一状态。传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力

  • 来自不同视图的行为需要变更同一状态。经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

vuex 管理模式

vuex 是以一个全局单例模式来管理各种不同的数据源和状态。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为。通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。

vuex 安装

npm 安装:npm install vuex


vuex 也支持<script></script>标签导入


在模块化的打包项目当中,使用 vuex 需要 import 导入后,使用 use 调用 vuex


import Vue from 'vue'import Vuex from 'vuex'
Vue.use(Vuex)
复制代码


如果使用<script></script>标签,则无需这些过程,直接使用即可。

vuex 核心

State

对于需要多个组件都能操纵的数据,可以创建 vuex 后写入 state 当中


在 vue cli 项目当中的 main.js 中引入 Vuex 后,创建一个 Vuex.Store 示例,定义时在 state 中写入变量数据


const store = new Vuex.Store({  state: {    data1: '可以被多组件操作的数据',    ......  }})
复制代码


可以在组件或者其子组件当中使用this.$store.state.data1获取到变量值,其实可以在子组件中直接对变量 data1 进行修改,但是不太推荐使用这种方式去修改 vuex 中的变量数据。还是推荐使用后面的MutationAction进行变量的修改。


<template>    <div id="VuexTest2"> <div>组件2号: {{ $store.state.data1 }}</div> </div></template>
<script>export default { name:'VuexTest2', components: {}, props: {}, data() { return { }; }, created() {}, mounted() { console.log(this.$store.state.data1) }, watch: {}, methods: { }, computed: { }};</script><style scoped>
</style>
复制代码


显示效果:




Getter

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。


const store = new Vuex.Store({  state: {    todos: [      { id: 1, text: '...', done: true },      { id: 2, text: '...', done: false }    ]  },  getters: {    doneTodos: state => {    // 返回todos中done为true的对象      return state.todos.filter(todo => todo.done)    }  }})
复制代码


可以通过属性进行访问:Getter 会暴露为 store.getters 对象


this.$store.getters.doneTodos
复制代码


效果:




Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。


mutation 也可以添加参数,会接受 state 作为第一个参数。


注意:Mutation 必须是同步函数


例子:


const store = new Vuex.Store({  state: {    count: 0  },  mutations: {    increment (state, payload) {      // 变更state中的count      state.count += payload.amount;    },  }})
复制代码


组件操作:


this.$store.commit('increment', { amount: 3 })
复制代码


效果:




Action

Action 类似于 mutation,不同在于:


  1. Action 提交的是 mutation,而不是直接变更状态。

  2. Action 可以包含任意异步操作。


例子:


const store = new Vuex.Store({  state: {    count: 0  },  mutations: {    increment (state) {      state.count++    }  },  actions: {    increment (context) {      context.commit('increment')    }  }})
复制代码


组件中触发 action,Action 通过 store.dispatch 方法触发


this.$store.dispatch('increment')
复制代码


mutation 必须同步执行这个限制么。Action 内部可以执行异步操作


actions: {  incrementAsync ({ commit }, payload) {     setTimeout(() => {       commit('increment', payload)     }, 1000)   }, }
复制代码



Module

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


Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。


const moduleA = {  state: () => ({ ... }),  mutations: { ... },  actions: { ... },  getters: { ... }}
const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... }}
复制代码


创建好模块后,就可以使用 module 将之前的模块加载入 vuex 当中了


const store = new Vuex.Store({  modules: {    a: moduleA,    b: moduleB  }})
复制代码


在组件中查看模块状态


this.$store.state.a // -> moduleA 的状态this.$store.state.b // -> moduleB 的状态
复制代码




以上就是快速学一遍后 vuex 可以掌握的基础功能和原理简述了,当然其中还有挺多其他内容的,就需要慢慢一点点在使用过程当中进行挖掘了



发布于: 2021 年 04 月 05 日阅读数: 28
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
快速学一遍vue的状态管理模式 -- Vuex