从零开始的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
来出发actionsstore.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.js,今天开始自学vue.js官方教程,记录下自己的学习摘要,方便后面查阅(此笔记按照学习天数,每天一篇) Vue.js是什么 Vue是一套用于构建用户界面的渐进式框架,Vue ...
- 从零开始的vue学习笔记(八)
前言 今天花一天时间阅读完Vue Router的官方文档的基础部分,简单的做一下总结和记录 Vue Router是什么 Vue Router 是 Vue.js 官方的路由管理器,用于构建单页应用(SP ...
- vue学习笔记(七)组件
前言 在前面vue的一些博客中,我们几乎将vue的基础差不多学习完了,而从本篇博客开始将会进入到vue的另一个阶段性学习,本篇博客的内容在以后的vue项目中占很大的比重,所以小伙伴们需要认真学习,本篇 ...
- 从零开始的vue学习笔记(五)
单文件组件 Vue.component 来定义全局组件的缺点: 全局定义 (Global definitions) 强制要求每个 component 中的命名不得重复 字符串模板 (String te ...
- Vue学习笔记七:Vue中的样式
目录 两种样式 class样式 内联样式 两种样式 Vue中使用样式方式有两种,一种是class样式,一种是内联样式也就是style class样式 class样式使用的方式有5种,HTML如下 &l ...
- 从零开始的vue学习笔记(二)
数据与方法 当一个 Vue 实例被创建时,它将 data 对象中的所有的属性加入到 Vue 的响应式系统中.data的数据和视图同步更新. 实例创建后添加一个新的属性,对这个属性的的改动将不会触发任何 ...
- 从零开始的vue学习笔记(四)
组件注册 组件名 Vue.component('my-component-name', { /* ... */ }) 这里的my-component-name就是组件名,组件名的取法可以参考指南 ke ...
- 从零开始的vue学习笔记(六)
混入 混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能.简单解释就是把一个Vue组件中的内容提供给别的组件来用.例子: // 定义一个混入对象 var myMixin ...
- 从零开始的vue学习笔记(三)
事件处理 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码,示例: <div id="example-2"> <!-- `gree ...
随机推荐
- .net core 部署到windows上的方法与 系统中相关问题的解决
前言 Net core 项目部门在Windows有很多种方式,大致有以下几种, dotnet 命令, iis(windowshosts), 一些开源的应用容器(docker ) 基于一些exe 程序, ...
- MariaDB数据库自学一
在CentOS下安装Mariadb 数据库,命令: yum -y mariadb mariadb.server 等待几分钟后就可以自动完成安装了,然后启动对应的服务: systemctl start ...
- Kubernetes --- 详细介绍和架构详解
Kubernetes是一个跨主机集群的开源的容器调度平台,它可以自动化应用容器的部署,扩展和操作,提供以容器为中心的基础架构 目录 一. Kubernetes用途 二. Kubernetes特点 三. ...
- Maven学习归纳(四)——传递依赖和依赖的规则
一.传递依赖 官方文档解释的传送门:http://ifeve.com/maven-dependency-mechanism/ 当存在传递依赖的情况时,主工程对间接依赖的jar可以访问吗? 例如:A.j ...
- hadoop2.7.3启动报错问题
在日志里面可以看出是没有对应的权限,因此在hdfs_site.xml中添加 <property> <name>dfs.permissions</name> < ...
- ThreadPoolTaskExecutor介绍
ThreadPoolTaskExecutor是一个spring的线程池技术,其实,它的实现方式完全是使用ThreadPoolExecutor进行实现.对于ThreadPoolExecutor,有一些重 ...
- Winform中怎样根据Name获取同窗体的控件
场景 在同一个Winform窗体中,点击一个Button按钮时, 获取同窗体的其他控件的属性. 首先需要对要获取的控件赋予Name属性,然后就可以通过Name进行获取. 实现 在Button的点击事件 ...
- 5、链表队列(java实现)
1.图例 2.链表节点 public class Node<T> { public T data; public Node next; } 3.具体实现 public class Link ...
- js 中 undefined、NaN、null
undefined 即未定义 js 中 没有声明 或者 声明后未赋值的变量 用typeof判断后类型都是 undefined 但是直接console.log( ) 输出的话 没有声明的变量会报错:而声 ...
- 多线程——Thread类
进程(Process):“正在执行的程序”,程序进入内存运行就变成了一个进程.一个进程会产生多个线程. 多线程(Multithread):一个进程中同时存在几个执行体.单线程是按照函数的顺序执行,多线 ...