Vue教程(四十八)Vuex 概念和基本使用

Posted _否极泰来_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue教程(四十八)Vuex 概念和基本使用相关的知识,希望对你有一定的参考价值。

Vue教程(四十八)Vuex 概念和基本使用

什么是Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式

它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

什么是状态管理模式

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

应用场景有:单页应用中,组件之间的数据状态。
应用实例:
1、购物车功能;
2、下单页面有选择优惠券按钮,点击进入优惠券页面,选择后返回到下单页,数据会绑定回来,显示已选择的优惠券;
3、登录状态等等

单界面的状态管理

new Vue({
  // state
  data () {
    return {
      count: 0
    }
  },
  // view
  template: `
    <div>{{ count }}</div>
  `,
  // actions
  methods: {
    increment () {
      this.count++
    }
  }
})

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

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

多界面状态管理

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

多个视图依赖于同一状态(一个状态改了,多个视图需要进行更新)。

来自不同视图的行为 Actions 需要变更同一状态。

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

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

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

Vuex 安装和基本使用

安装插件

npm install vuex --save

基本使用

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

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

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

安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当,仅需要提供一个初始 state 对象和一些 mutation:

操作:在 src 目录下创建一个 store 文件夹,并在 store 文件夹下创建一个 index.js 文件。在 index.js 文件中,引入 vuex 并通过 Vue.use() 来安装 Vuex :

import Vue from 'vue'
import Vuex from 'vuex'

// 1.安装插件
Vue.use(Vuex)

// 2. 创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000
  },
  mutations: {
    // 对state.counter属性每次+1操作
    increment (state) {
      state.counter++
    },
    // 对state.counter属性每次-1操作
    decrement (state) {
      state.counter--
    }
  }

})

// 3. 导出store独享
export default store
  • 新建组件【src\\components\\HelloVuex.vue】
<template>
  <div>
    <!-- 从$store.state中获取counter值 -->
    <span>counter值:{{$store.state.counter }}</span>
  </div>
</template>

<script>
export default {
  name: 'HelloVuex'
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
  • 修改文件【【src\\components\\App.vue】
<template>
  <div id="root">
    <div>
      计数器:
      <button @click="addition()">+</button>
      <button @click="subtraction()">-</button>
    </div>
    <div class="layout">
      <h3>APP组件内容</h3>
      <span>counter值:{{$store.state.counter}}</span>
    </div>
    <div class="layout">
      <h3>HelloVuex组件内容</h3>
      <hello-vuex />
    </div>
  </div>
</template>

<script>
// 1. 引入HelloVuex组件
import HelloVuex from './components/HelloVuex.vue'
export default {
  name: 'App',
  // 2. 注册组件
  components: {
    HelloVuex
  },
  methods: {
    addition () {
      this.$store.commit('increment')
    },
    subtraction () {
      this.$store.commit('decrement')
    }
  }
}
</script>

<style>
#root {
  width: 100%;
}
.layout {
  width: 49%;
  border: 1px solid black;
  float: left;
}
</style>

执行结果:

安装vue-devtools

下载地址:https://f6.crx4chrome.com/crx.php?i=nhdogjmejiglipccpnnnanhbledajbpd&v=5.3.4&p=11903

我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。

由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutation。

    – 以上为《 Vue教程(四十八)Vuex 概念和基本使用》,如有不当之处请指出,我后续逐步完善更正,大家共同提高。谢谢大家对我的关注。

——厚积薄发(yuanxw)

以上是关于Vue教程(四十八)Vuex 概念和基本使用的主要内容,如果未能解决你的问题,请参考以下文章

Vue教程(四十八)Vuex 概念和基本使用

Vue教程(四十八)Vuex 概念和基本使用

Vue 教程(四十九)Vuex 核心概念和项目结构

Vue 教程(四十九)Vuex 核心概念和项目结构

Vue 教程(四十九)Vuex 核心概念和项目结构

Vue 教程(四十九)Vuex 核心概念和项目结构