Vue学习—— Vuex学习笔记
组件是Vue最强大的功能之一,而组件实例的作用域是相互独立的,意味着不同组件之间的数据是无法相互使用。组件间如何传递数据就显得至关重要,这篇文章主要是介绍Vuex。尽量以通俗易懂的实例讲述这其中的差别,希望对小伙伴有些许帮助。
一、Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
二、什么是“状态管理模式”?
一个简单的 Vue 计数应用开始:
new Vue({
// state
data () {
return {
count: 0
}
},
// view
template: `
<div>{{ count }}</div>
`,
// actions
methods: {
increment () {
this.count++
}
}
})
这个状态自管理应用包含以下几个部分:
state,驱动应用的数据源;
view,以声明方式将 state 映射到视图;
actions,响应在 view 上的用户输入导致的状态变化。
state的数据会在 view上显示出来,用户会根据 view 上的内容进行操作,从而触发 actions,接着再去影响 state(vue 是单向数据流的方式驱动的)。
当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏。下面的图,是把组件的共享状态抽取出来,以一个全局单例模式管理。
三、核心概念
1. state
state:页面状态管理容器对象。集中存储Vue components中data对象的零散数据,以进行统一的状态管理。页面显示所需的数据从该对象中进行读取。
<div>
{{ $store.state.count }}
</div>
console.log(this.$store.state.count)
2. getters
getters:Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。(getters从表面是获得的意思,可以把他看作在获取数据之前进行的一种再编辑,相当于对数据的一个过滤和加工。getters就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。)
定义getter:
getters: {
done(state) {
return state.count + 1;
},
}
3. mutations
mutations:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
组件通过commit提交mutations的方式来请求改变state
this.$store.commit('increment')
提交载荷(Payload)
mutations方法中是可以传参的,具体用法如下:
mutations: {
// 提交载荷 Payload
add(state, n) {
state.count += n
}
},
this.$store.commit('add', 10)
4.Action
Action:类似于 mutation,不同在于Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作。
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
不同于mutations使用commit方法,actions使用dispatch方法。
this.$store.dispatch('incrementAsync')
context
context是与 store 实例具有相同方法和属性的对象。可以通过context.state和context.getters来获取 state 和 getters。
以载荷形式分发
incrementAsyncWithValue (context, value) {
setTimeout(() => {
context.commit('add', value)
}, 1000)
}
this.$store.dispatch('incrementAsyncWithValue', 5)
5.Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(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 的状态
模块的局部状态
对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。
const moduleA = {
state: { count: 0 },
mutations: {
increment (state) {
// 这里的 `state` 对象是模块的局部状态
state.count++
}
},
getters: {
doubleCount (state) {
return state.count * 2
}
}
}
Vuex计数器的例子:
在src目录下创建一个store文件夹。
store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0,
show: ''
},
getters: {
counts: (state) => {
return state.count
}
},
mutations: {
increment: (state) => {
state.count++
},
decrement: (state) => {
state.count--
},
changVal: (state, v) => {
state.show = v
}
}
})
export default store
state就是我们的需要的状态,状态的改变只能通过提交mutations,例如:
increase() {
this.$store.commit('increment')
}
带有载荷的提交方式:
changObj () {
this.$store.commit('changVal', this.obj)
}
载荷也可以是一个对象,这样可以提交多个参数。
changObj () {
this.$store.commit('changVal', {
key:''
})
}
在main.js中引入store.js
import store from './store/store'
export default new Vue({
el: '#app',
router,
store,
components: {
App
},
template: '<App/>'
})
在组件中使用
在组建可以通过$store.state.count获得状态
更改状态只能以提交mutation的方式。
<div class="store">
<p>
{{$store.state.count}}
</p>
<button @click="increase"><strong>+</strong></button>
<button @click="decrease"><strong>-</strong></button>
<hr>
<h3>{{$store.state.show}}</h3>
<input
placeholder="请输入内容"
v-model="obj"
@change="changObj"
clearable>
</input>
</div>
</template>
<script>
export default {
data () {
return {
obj: ''
}
},
methods: {
increase() {
this.$store.commit('increment')
},
decrease() {
this.$store.commit('decrement')
},
changObj () {
this.$store.commit('changVal', this.obj)
}
}
}
</script>
mapState、mapGetters、mapActions
很多时候 , $store.state.dialog.show 、$store.dispatch('switch_dialog') 这种写法又长又臭 , 很不方便 , 我们没使用 vuex 的时候 , 获取一个状态只需要 this.show , 执行一个方法只需要 this.switch_dialog 就行了 , 使用 vuex 使写法变复杂了 ?使用 mapState、mapGetters、mapActions 就不会这么复杂了。
以 mapState 为例 :
<template>
<el-dialog :visible.sync="show"></el-dialog>
</template>
<script>
import {mapState} from 'vuex';
export default {
computed:{
//这里的三点叫做 : 扩展运算符
...mapState({
show:state=>state.dialog.show
}),
}
}
</script>
相当于 :
<template>
<el-dialog :visible.sync="show"></el-dialog>
</template>
<script>
import {mapState} from 'vuex';
export default {
computed:{
show(){
return this.$store.state.dialog.show;
}
}
}
</script>
mapGetters、mapActions 和 mapState 类似 , mapGetters 一般也写在 computed 中 , mapActions 一般写在 methods 中。
Vuex官方文档
Vue学习—— Vuex学习笔记的更多相关文章
- vue之vuex学习
知识点一:vuex是状态管理器(单向数据流) 每个Vuex应用程序的核心是商店.“商店”基本上是一个容纳您的应用程序状态的容器.有两件事使Vuex商店与普通的全局对象不同: Vuex商店是被动的.当V ...
- Vue学习笔记-Vue.js-2.X 学习(四)===>脚手架Vue-CLI(基本工作和创建)
(五) 脚手架Vue-CLI 一 Vue-CLI前提(nodejs和webpack) 二 Vue学习-nodejs按装配置,Node.js 就是运行在服务端的 JavaScript. 1. 去nod ...
- Vue.js中学习使用Vuex详解
在SPA单页面组件的开发中 Vue的vuex和React的Redux 都统称为同一状态管理,个人的理解是全局状态管理更合适:简单的理解就是你在state中定义了一个数据之后,你可以在所在项目中的任何一 ...
- 最新 Vue 源码学习笔记
最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...
- Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明-Babel)
五 Vue学习-vue-cli脚手架学习(创建只选一个选项:Babel) 1. 项目目录说明 node_modules : 包管理文件夹 public : 静态资源 src : 源代码 gitign ...
- Vue学习笔记-Vue.js-2.X 学习(五)===>脚手架Vue-CLI(PyCharm)
Vue项目在pycharm中配置 退出运行: ctrl+c Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明)
- Vue学习笔记-Vue.js-2.X 学习(三)===>组件化高级
(四) 组件化高级 1.插槽(slot)的基本使用 A:基本使用: <slot></slot> B:默认置:<slot><h1>中间可以放默认值< ...
- Vue学习笔记-Vue.js-2.X 学习(二)===>组件化开发
===重点重点开始 ========================== (三) 组件化开发 1.创建组件构造器: Vue.extends() 2.注册组件: Vue.component() 3.使用 ...
- Vue学习笔记-Vue.js-2.X 学习(一)===>基本知识学习
一 使用环境: windows 7 64位操作系统 二 IDE:VSCode/PyCharm 三 Vue.js官网: https://cn.vuejs.org/ 四 下载安装引用 方式1:直接 ...
随机推荐
- git tag命令
创建本地标签 git tag -a [tagname] -m [msg] git tag -a [tag_name] [commit_id] -m [msg] 创建远程标签 git push orig ...
- Java入门系列之线程池ThreadPoolExecutor原理分析思考(十五)
前言 关于线程池原理分析请参看<http://objcoding.com/2019/04/25/threadpool-running/>,建议对原理不太了解的童鞋先看下此文然后再来看本文, ...
- Kubectl patch命令使用
kubectl patch 使用(patch)补丁修改.更新资源的字段. 支持JSON和YAML格式. 请参阅https://htmlpreview.github.io/?https://github ...
- JuiceSSH:安卓平台免费好用的 SSH 客户端
为了解决上下班路上或者没带电脑时,查看 Linux 服务器日志或者紧急运维的需求,最终找到了 JuiceSSH 这款软件,强烈推荐给大家. 简介 JuiceSSH 是一个为 Android 打造的全功 ...
- 数字电路技术之触发器(基本RS触发器)
一.触发器的知识 1.触发器是构成时序逻辑电路的基本逻辑部件. 2.[1]它有两个稳定的状态:0状态和1状态: [2]在不同的输入情况下,它可以被置成0状态或1状态: [3]当输入 ...
- 解决项目迁移至Kubernetes集群中的代理问题
解决项目迁移至Kubernetes集群中的代理问题 随着Kubernetes技术的日益成熟,越来越多的企业选择用Kubernetes集群来管理项目.新项目还好,可以选择合适的集群规模从零开始构建项目: ...
- Java数组模拟环形队列
2.环形队列 (上一篇队列:https://www.cnblogs.com/yxm2020/p/12676323.html) 百度百科 1.假溢出 系统作为队列用的存储区还没有满,但队列却发生了溢 ...
- MySQL不香吗,为什么还要有noSQL?
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是分布式专题的第14篇文章,我们一起来看看NoSQL数据库. 其实我很早就想写写分布式数据库相关的文章,既是我现在正在学习的,也是我很感 ...
- python 基础篇 自定义函数
多态 我们可以看到,Python 不用考虑输入的数据类型,而是将其交给具体的代码去判断执行,同样的一个函数(比如这边的相加函数 my_sum()),可以同时应用在整型.列表.字符串等等的操作中. 在编 ...
- 模拟电磁曲射炮_H题 方案分析【2019年电赛】【刘新宇qq522414928】
请查看我的有道云笔记: 文档:电磁曲射炮分析.note链接:http://note.youdao.com/noteshare?id=26f6b6febc04a8983d5efce925e92e21