vuex概念总结及简单使用实例

原文

博客原文

大纲

1、什么是Vuex
2、什么是“状态管理模式”?
3、什么情况下应该使用 Vuex?
4、Vuex和全局变量的概念区别
5、最简单的store
6、Vuex的简单使用
6.1、vue文件版本
6.2、js文件版本

1、什么是Vuex

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

2、什么是“状态管理模式”?

让我们从一个简单的 Vue 计数应用开始:

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

这个状态自管理应用包含以下几个部分:
1、state,驱动应用的数据源;
2、view,以声明方式将 state 映射到视图;
3、actions,响应在 view 上的用户输入导致的状态变化。
以下是一个表示“单向数据流”理念的极简示意:

image.png
问题暴露

但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
1、多个视图依赖于同一状态。
2、来自不同视图的行为需要变更同一状态。
对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

解决方式

因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
另外,通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,我们的代码将会变得更结构化且易维护。
这就是 Vuex 背后的基本思想,借鉴了 Flux、Redux、和 The Elm Architecture。与其他模式不同的是,Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。

image.png
3、什么情况下应该使用 Vuex?

虽然 Vuex 可以帮助我们管理共享状态,但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 global event bus 就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

4、Vuex和全局变量的概念区别

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
1、Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
2、你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

5、最简单的store
/*
    安装 Vuex 之后,让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 
state 对象和一些 mutation:
*/
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

/*
    现在,你可以通过 store.state 来获取状态对象,以及通过 store.commit 方法触发
状态变更:
*/

store.commit('increment')

console.log(store.state.count) // -> 1

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

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

vue-cli搭建的项目
利用脚手架搭建项目之后,可以通过npm引入vuex
npm install vuex

也可以直接通过引入文件
<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>

实例:基本的Vuex计数应用
vue文件版本
1、创建store状态管理
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 状态
const state = {
  count: 0
}

const mutations = {
  INCREMENT (state) {
    state.count++
  },
  DECREMENT (state) {
    state.count--
  }
}

const actions = {
  increment: ({ commit }) => commit('INCREMENT'),
  decrement: ({ commit }) => commit('DECREMENT')
}

const getters = {
  moreCount: function () {
    return state.count + 'more'
  }
}

export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations
})

2、引入store状态管理
import Vue from 'vue'
import App from './App'
import store from './store'

Vue.config.productionTip = false

new Vue({
  el: '#app',
  store,
  components: { App },
  template: '<App/>'
})
3、使用store进行状态管理——计数
3.1、相应点击事件发布(dispatch)状态
<template>
  <div>
    <div>{{ msg }}</div><br>
    <div>
      <button @click="increment()">+</button>
      <button @click="decrement()">-</button>
    </div><br>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'HelloWorld'
    }
  },
  methods: {
    increment () {
      console.log('+++')
      this.$store.dispatch('increment')
    },
    decrement () {
      console.log('---')
      this.$store.dispatch('decrement')
    }
  }
}
</script>

<style scoped>
</style>
3.2、接收状态改变之后的值
 <template>
  <div>
    {{ msg }}<br>
    {{ count }}<br>
    {{ moreCount }}
  </div>
</template>

<script>
export default {
  name: 'SimpleCounter',
  data () {
    return {
      msg: 'SimpleCounter'
    }
  },
  computed: {
    count () {
      return this.$store.state.count
    },
    moreCount () {
      return this.$store.getters.moreCount
    }
  }
}
</script>

<style scoped>
</style>
js文件版本
<html>
    <meta charset="utf-8">
    <head>
        <title>Test</title>
    </head>
    <body>

        <div id="app">
            <p>{{ count }}</p>
            <p>
                <button @click="increment">+</button>
                <button @click="decrement">-</button>
            </p>
        </div>

        <script src="./vue.js"></script>
        <script src="./vuex.js"></script>
        <script src="./vuex-demo2.js"></script>
    </body>
</html>
const store = new Vuex.Store({
    state: {
      count: 0
    },
    mutations: {
      increment: state => state.count++,
      decrement: state => state.count--
    }
  })

new Vue({
    el: '#app',
    computed: {
      count () {
          return store.state.count
      }
    },
    methods: {
      increment () {
        store.commit('increment')
      },
      decrement () {
          store.commit('decrement')
      }
    }
  })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 UI组件 element ★13489...
    秋玄语道阅读 13,685评论 3 116
  • Vuex是什么? Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件...
    萧玄辞阅读 3,102评论 0 6
  • 目录 组件化 组件通信 状态管理 Vuex 是什么 Vuex 有什么特点 Vuex 解决了什么问题 什么类型的数据...
    前端小华子阅读 1,983评论 0 16
  • 2017年最重要的一天 罗胖在2017年跨年演讲上,用这样一个问题作为开头: 对你来说,2017年最重要的一天是哪...
    毛豆爸的破冰之旅阅读 259评论 4 4
  • 今天无意中发现手机储存了几百张屏保图片,都是平时看见觉得好看保留下来的。突然间萌生了一个想法,把这里的照片不断地删...
    终南山下采薇人阅读 155评论 0 0