从零开始的vue学习笔记(七)
前言
今天花一天时间阅读完vuex的官方文档,简单的做一下总结和记录
Vuex是什么
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,以前的符合“单向数据流”理念的示意图:
它包含三个部分:
- state,驱动应用的数据源;
- view,以声明方式将 state 映射到视图;
- actions,响应在 view 上的用户输入导致的状态变化。
当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。
实际上就是一个组件间通讯的问题,原来是用$ref直接引用子组件,或者多层嵌套组件,或者依赖注入
provide和
inject等暴力方式,在应用和组件复杂的情况下复杂度和可维护性都会成为巨大问题。
所以,vuex就诞生了,vuex的原理图:
这个图描述了vuex的数据传导逻辑,绿色虚线部分为vuex插件本身
- 首先,
Vuex
自身提供了一个store
(仓库),数据结构为树形的,采用单例设计,里面用key-value
(value可以是string、数字、数组、Object等)的形式包含了一个应用的各种状态值,并提供了响应式的状态更新,提供给vue组件Render
来渲染。 - 传统的Vue组件接受用户对界面的操作后,通过分发(
Dispatch
)这些前端事件或者说响应给Vuex的Action
,在Action
中可以用来添加自己的业务逻辑,同时可以异步
调用一些其他的后端API Action
通过Commit
来提交对应的Mutations
里的方法,达到调用Mutations
里的方法的目的,这个时候可以用Devtools
插件来追踪状态数据在Mutations
里的方法调用前后的数据变化,形成快照等(Mutations
里的方法必须是同步
的)Mutations
里的一些mutation
(变异)方法体执行,改变应用的一些State状态属性,这些mutation
是Vuex改变状态的唯一途径,直接修改State状态值是不允许的(数据不可追踪),从而形成了单向数据流
的完整链路,同时状态是可维护
、可追踪
、响应式
、可复用
。
下面就一起来看看Vuex的各个详细部分:
安装
直接下载(推荐)或者CDN引入
从https://unpkg.com/vuex下载下来,然后通过js引入:<script src="/path/to/vue.js"></script> <script src="/path/to/vuex.js"></script>
npm/yarn
//npm npm install vuex --save //yarn yarn add vuex
模块化的打包系统
import Vue from 'vue' import Vuex from 'vuex' //前面vue基础部分就有Vue.use()引入插件的用法, //下面这句在打包系统中是必备的 Vue.use(Vuex)
核心概念
State
首先,Vuex的所有概念都只有一个api:围绕Vuex.Store(...options) 这个构造器展开,类似Vue的概念都围绕Vue的构造器展开一样;State的作用就类似于Vue里面的data
,简单的new Vuex的例子:// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } } })
这样,在我们的Vue插件里就可以用computed计算属性来获取这些state值:
// 创建一个 Counter 组件 const Counter = { template: `<div>{{ count }}</div>`, computed: { count () { return store.state.count } } }
为了简化写法(少些代码),官方提供了一个
mapState
辅助函数避免写store.state.count
这一长串,其他的辅助函数mapGetters
、mapActions
、mapMutations
都是类似的作用,API链接
例子:
// 在单独构建的版本中辅助函数为 Vuex.mapState import { mapState } from 'vuex' export default { // ... computed: mapState({ // 箭头函数可使代码更简练 count: state => state.count, // 传字符串参数 'count' 等同于 `state => state.count` countAlias: 'count', // 为了能够使用 `this` 获取局部状态,必须使用常规函数 countPlusLocalState (state) { return state.count + this.localCount } }) }
Getter
单纯的用State里的状态值还不够强大,所以Vuex提供了Getter来对State作进一步的复杂逻辑处理,类似于Vue里面的computed计算属性对data的进一步处理一样。
例子: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) } } })
如果对更多的语法细节感兴趣,可以阅读官方链接
Mutation
Mutaion中文解释是变异,用来执行对State状态改变的同步
方法,可以简单的类比Vue中的methods,只不过Vue中的methods没有区分同步
和异步
方法,而Vuex中为了追踪数据状态,用Mutation执行同步方法,Action直观性异步方法,做了这种拆分,让Devtools等工具发挥作用。
例子:const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { // 变更状态 state.count++ } } })
更多的语法细节参考链接
- Action
Action 类似于 mutation,不同在于: Action 通过commit提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作
例子:
const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') } } })
组件里通过
store.dispatch来出发actions
store.dispatch('increment')更多语法细节见链接
Module
如果只靠一个大的store里的state状态树来维护整个应用,当规模巨大,势必会有问题,所以引入Module做模块化的拆分,拆成按照命名空间的子状态树。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。
例子:
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态
引入
namespaced: true确保每个模块的独立命名空间,更多语法细节见链接
其他的主题包括:
-
项目结构
这些主题不是核心问题,在需要看的时候或者自己感兴趣的再来看,详见链接。
- VUE 学习笔记 从零开始一步一步构建 VUE 单页应用(四)
- VUE 学习笔记 从零开始一步一步构建 VUE 单页应用(二)
- VUE 学习笔记 从零开始一步一步构建 VUE 单页应用(三)
- 从零开始的vue学习笔记(二)
- VUE 学习笔记 从零开始一步一步构建 VUE 单页应用(一)
- J2ME从零开始(学习笔记4)
- Vue.js学习系列二 —— vuex学习实践笔记(附DEMO)
- Vue学习笔记1.0(第二天)
- J2ME从零开始(学习笔记8)
- vue入门学习笔记
- VUE学习笔记——利用es6模板字符串实现时间格式化
- java 从零开始,学习笔记之基础入门<Oracle_查询>(三十四)
- java 从零开始,学习笔记之基础入门<Oracle_函数_触发器_游标_存储过程_视图>(三十五)
- vue.js 源代码学习笔记 ----- codegen.js
- vue学习笔记:vue-router参数
- vue学习笔记:2.vue过滤器
- VUE学习笔记-组件学习
- vue学习笔记3——外部引入css和路由的一部分
- qt5学习问题笔记二(从零开始)
- java 从零开始,学习笔记之基础入门<数组列表(ArrayList)>(九)