快速了解Vuex

提要:提起react就会想起其应用最广泛的redux状态管理工具,vue中的官方推荐的状态管理工具就是Vuex。

看到同事在鼓捣Vuex的东西,前面项目完成后也没有好好总结一下Vuex的知识,所有就再回头看看,温故知新。

什么是Vuex?

根据Vuex文档中的描述,Vuex是使用于Vue.js应用的状态管理库,为应用中的所有组件提供集中式的状态存储与操作,保证了所有状态以可预测的方式进行修改。

这个状态自管理应用包含是三个部分:

  1. state: 驱动应用的数据源;
  2. view:以声明方式将state映射到视图;
  3. actions:相应view上的用户输入导致的状态变化。

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

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

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

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

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

另外,通过定义和隔离状态管理中心的各种概念并强制遵循一定的规则,我们的代码就会变得结构化且易维护。

这就是Vuex背后的基本思想,借鉴了Flux、Redux。所有以前用过Redux后,学习Vuex也没有比较吃力的情况。

什么情况下应该用Vuex

如果不需要开发大型单页应用,使用Vuex可能是繁琐冗余的。如果你的应用足够简单,最好不要使用Vuex。但是,如果需要构件一个大型单页应用,就应该考虑使用组件外部的状态管理工具,对于vue应用Vuex就成为自然而然的选择。

Vuex中的几个核心概念

学习一个知识点就需要掌握知识点中涉及到的一些核心概念,弄懂了概念,学习起来就能够如鱼得水。

State

单一状态数

Vuex使用单一状态树,就是用一个对象就包含了全部的应用的层级状态。所以它便作为一个【唯一数据源(SSOT)】而存在。这也意味着,每个应用将紧紧包含一个store实例。但一状态树让我们能够直接定位任一特定的状态片段,在调试的过程中也能够轻易地取得整个当前应用状态的快照。

在Vue组件中获取Vuex状态

由于Vuex的状态存储是响应式的,从store实例中读取状态最贱单的方式就是在计算属性中返回某个状态:

// 创建一个 Counter 组件
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return store.state.count
    }
  }
}

没当 store.state.count 变化的时候,就会从新求取计算属性,并且触发更新相关联的DOM。

然而,这种模式导致组件依赖的全局状态单例,在模块化的构建系统中,在每个需要使用state的组件中需要频繁地导入,并且在测试组件时需要模拟状态。

Vuex通过store选项,提供了一种机制将状态从根组件注入到每个子组件中(需要使用Vue.use(Vuex)):

const app = new Vue({
  el: ‘#app‘,
  // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

通过在根事例中注册store选项,该store实例会注入到根组件下的所有子组件中,且子组件能够通过this.$store访问到。

const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.state.count
    }
  }
}
mapState辅助函数

当一个组件需要获取多个状态时,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用mapState辅助函数帮助我们生成计算属性:

//在单独构建的版本中辅助函数为Vuex.mapState
import { mapState } from ‘vuex‘

export default {
    //...
    computed: mapState({
        //箭头函数可使代码更简练
        count: state => state.count,
        //传字符串‘count‘等同于`stete => state.count`
        countAlias: ‘count‘,
        //为了能够使用`this`获取局部状态,必须使用常规函数
        countPlusLocalState(state) {
            return state.count + this.localCount
        }
    })
}

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

computed: mapState([
    //映射 this.count 为 store.state.count
    ‘count‘
])
对象展开运算符

mapState函数返回的是一个对象。我们如何将它与局部计算属性混合使用呢?通常,我们需要使用一个工具函数来将多个对象合并为一个,以使我们可以将最终对象传给computed属性。但是自从有了对象展开运算符,现在我们可以极大地简化写法:

computed: {
    localComputed (){    },
    //使用对象展开运算符将此对象混入到外部对象中
    ...mapState({
        //...
    })
}
组件仍然保有局部状态

使用Vuex并不意味着需要将所有的状态放入Vuex。虽然将所有的状态放到Vuex会使状态更显式和易调试,但是会是代码变得冗长和不直观。如果有些状态严格属于单个组件,最好是作为组件的局部状。应该能作为局部状态的就保留局部状态。

Getters

有时候我们需要从store中的state中派生出一些状态,例如对列表尽心过滤并计数:

computed: {
    doneTodosCount () {
        return this.$store.state.todos.filter(todo => todo.done.length)
    }
}

如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多出导入它——无论哪种方式都不是很理想。

Vuex允许我们在store中定义“getters”(可以认为是store的计算属性)。Getters接受state作为其第一个参数:

const store = new Vuex.Store({
    state: {
        todos: [
            {id: 1, text: "...", done: true},
            {id: 2, text: "...", done: false}
        ]
    },
    getters: {
        doneTodos: state => {
            return state.todos.filter(todo => todo.done)
        }
    }
})

Getters会暴露出store.getters对象:

store.getters.doneTodos //-> [{id: 1, text: ‘...‘, done: true}]

Getters也可以接受其他getters作为第二个参数:

getters: {
    doneTodosCount: (state, getters)=> {
        return getters.doneTodos.length;
    }
}

store.getters.doneTodosCount //-> 1

我们可以很容易地在任何组件中使用它:

computed: {
    doneTodosCount(){
        return this.$store.getters.doneTodosCount;
    }
}
mapGetters辅助函数

mapGetters辅助函数仅仅是将store中的getters映射到局部计算属性:

import {mapGetters} from ‘vuex‘

export default {
    computed: {
        // 使用对象展开运算符将 getters 混入 computed 对象中
        ...mapGetters([
            ‘doneTodosCount‘,
            ‘anotherGetter‘
        ])
    }
}

如果你想讲一个getter属性另去一个名字,使用对象形式:

mapGetters({
    // 映射 this.doneCount 为 store.getters.doneTodosCount
    doneCount: ‘doneTodosCount‘
})
未完

以上内容是看到同事在用mapGetters这个方法,突然想到前面做的Vue项目中并没有去尝试使用一些辅助函数去减少代码量,于是乎回过头来再看看Vuex的官网,把内容敲一遍,加深理解。后面项目中如果用到vue,就更加深入的研究一下Vue以及Vuex的一些彩蛋内容。

时间: 2024-11-05 11:42:06

快速了解Vuex的相关文章

Vue.js——快速入门Vuex

一. 什么是Vuex? Vuex是一个专门为Vue.js应用程序开发的状态管理模式, 它采用集中式存储管理所有组件的公共状态, 并以相应的规则保证状态以一种可预测的方式发生变化. 上图中绿色虚线包裹起来的部分就是Vuex的核心, state中保存的就是公共状态, 改变state的唯一方式就是通过mutations进行更改. 可能你现在看这张图有点不明白, 等经过本文的解释和案例演示, 再回来看这张图, 相信你会有更好的理解. 二. 为什么要使用Vuex? 试想这样的场景, 比如一个Vue的根实例

快速理解 VUEX 原理

1. vuex 的作用: vuex其实是集中的数据管理仓库,相当于数据库mongoDB,MySQL等,任何组件都可以存取仓库中的数据. 2. vuex 流程和 vue 类比: 我们看一下一个简单的vue响应式的例子,vue中的 data .methods.computed,可以实现响应式. 视图通过点击事件,触发 methods 中的 increment 方法,可以更改 data 中 count 的值,一旦 count 值发生变化,computed 中的函数能够把 getCount 更新到视图.

vuex中filter的使用 &amp;&amp; 快速判断一个数是否在一个数组中

vue中filter的使用 computed: mapState({ items: state => state.items.filter(function (value, index, arr) { return index < 5 }) }), 如上所示,对于vuex,我们在使用mapState获取state时, 可以使用filter来过滤其中的元素,在filter的回调函数中接受三个参数,第一个是value,即每一个元素的值: 第二个是index, 即每一个元素所在的index, 第三个

使用vue2.x+webpack+vuex+sass+axios+elementUI等快速搭建前端项目框架

一.本文将分享如何快速搭起基于webpack+vue的前端项目框架,利用vue的自己的脚手架工具vue-cli搭建起基本的环境配置,再通过npm包管理工具引入相应的依赖来完善项目的各种依赖框架.下面是具体实操. 二.基本命令操作. 1.在开发之前需要首先安装node.js,直接百度搜索或者在其中文官网也可以下载http://nodejs.cn/download/, 在装完node之后npm包管理工具也自动的安装好,安装完之后,在命令行输入node -v或者npm -v,出现版本号说明安装成功.如

vue2.0项目实战(5)vuex快速入门

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试.状态快照导入导出等高级调试功能. 以上是vuex的官方文档对vuex的介绍,官方文档对vuex的用法进行了详细的说明.这里就不再细讲vuex的各个用法. 为什么要用vuex 当你打算开发大型单页应用(SPA),会

vue2+vuex+vue-router 快速入门(三) vue 实例介绍

vue 实例介绍 vue 实例分两种,一种为组件实例,另外一种为根实例.组件实例负责创建个性化组件.而根实例负责把组件渲染到指定的真实的 DOM 结构中.并且 vue 为我们提供了一种特殊的文件格式 .vue 来创建 组件实例..vue 文件格式如下: *.vue <template> ... </template> <script> export default { data(){ return {} } } </script> <style lan

快速学会使用Vuex

一.Vuex简介 官方定义 Vuex是一个专门为Vue.js应用程序开的状态管理模式 它采用集中式存储管理应用的所有组件的状态 并以相应的规则保证以一种可预测的方式发生变化 二.应用场景 多个视图依赖于同一状态 来自不同视图的行为需要改变同一个状态 三.Vuex的安装和组成介绍 State——数据仓库,存储所有数据状态 Getter——用来获取数据的 Mutation——用来修改数据的,同步 Action——用来提交mutation,异步 安装 安装vuex包:npm install vuex

vuex 快速上手,具体使用方法总结(含使用例子)

网上有关vuex的文章很多,我这里只讲实用的: vuex 用处:管理全局状态(类似全局变量,每个组件都能访问到) vuex 用法: //下面是一个js文件,用最简单最全的例子展示了全局数据 city 和 cityID 的声明以及改变的方法: import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { city: '深圳', cityID: "1&quo

vue2+vuex+vue-router 快速入门(二) 项目搭建

安装 我们可以通过两种方式把 vue 引入到我们的项目中,一种直接通过 <script> 引入 ,这时 vue 会被注册为一个全局变量.第二种便是通过 npm 进行安装,这种方式可以很好的配合 webpack 或 browserify 模块打包器使用.我们的项目使用 webpack 进行打包. 项目搭建 在经过简短的考虑之后,我们决定使用 npm 管理项目依赖,webpack 进行项目打包.js 遵循 es6 规则,采用 babel 进行转换.less 管理 css 样式.vue 提供了一个官