vuex是一个专门为vue.js设计的状态管理模式,并且也可以使用devtools进行调试,可以多个组件共享状态。简单来说,就是共享的状态用state来存放,用mutations来操作state,但是需要用store.commit来主动式的操作mutations。

  用一个简单的demo来认识vuex。

  注意在使用vuex之前要先安装依赖(前提是已经用Vue脚手架工具构建好项目)

cnpm install vuex –save

  在入口文件main.js里需要引入vuex、注册vuex、实例化store、把store放在全局的实例化对象里。

import Vue from 'vue'
import App from './App'
//1.引入vuex
import Vuex from 'vuex'
import Apple from './components/Apple'
import Banana from './components/Banana'
Vue.config.productionTip = false
//2.注册
Vue.use(Vuex);
//3.实例化store
let store=new Vuex.Store({
state:{
totalPrice:0
},
mutations:{
increment(state,price){
state.totalPrice+=price
},
decrement(state,price){
state.totalPrice-=price
}
},
actions:{
increase (context,price){
context.commit('increment',price)
},
decrease (context,price){
context.commit('decrement',price)
}
},
getters:{
discount(state){
return state.totalPrice *0.8;
}
}
})
new Vue({
el: '#app',
//4.把store放在全局的实例化对象里,可以在全局的所有地方用
store,
components: { App},
template: '<App/>'
})

  实例化store时,用到了state,mutations,actions,getters参数,下面来单独介绍 它们:

state
  vuex使用单一状态树,那么就可以用一个对象来包含全部的应用层级状态。所以state就作为数据源。

mutations
  更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。不能直接调用一个 mutation handler,这个选项更像是事件注册:“当触发一个type为 increment的 mutation 时,调用此handler。”要唤醒一个 mutation handler,需要调用 store.commit 方法触发相应的 type 。可以向store.commit传入额外的参数这个参数就叫做mutations的载荷。 在更多的情况下,载荷应该是一个对象。这样可以包含更多的字段。

  mutations必须是同步函数。那我们如何来异步的更新state呢?答案是actions。

actions
  actions类似于 mutations 不同的是:
  actions 提交的是mutations,而不是直接变更状态,这也就形成了 actions —— mutations —— state 的过程。
  actions 可以包含任意异步操作。
  action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用context.commit提交一个 mutation,或者通过context.state和context.getters来获取 state 和 getters。但是如何触发呢?答案: store.dispatch
getters

  有时候我们需要从 store 中的 state 中派生出一些状态,getter 会暴露为 store.getters 对象在组件中使用。

modules

除了上边用到的4个参数,store还有另一个参数:modules。
  vuex允许把store进行一个功能拆分,分割成不同的模块(module)。每个模块都拥有自己的store,mutations,action,getters。

App.vue

<template>
<div id="app">
<Apple></Apple>
<Banana></Banana>
<p> 总价{{totalPrice}}</p>
<p> 折后价:{{discountPrice}}</p>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld'
import Apple from './components/Apple'
import Banana from './components/Banana'
export default {
name: 'App',
components: {
HelloWorld,
Apple,
Banana
},
computed:{
totalPrice(){
//由于vuex的状态存储是响应式的,所以从store实例中读取状态的最简单方法就是使用计算属性来返回某个状态:
return this.$store.state.totalPrice
},
discountPrice(){
//getter 会暴露为 store.getters 对象
return this.$store.getters.discount
}
}
}
</script>

  由于vuex的状态存储是响应式的,所以从store实例中读取状态的最简单方法就是使用计算属性来返回某个状态:store.state.totalPrice

  getters 会暴露为 store.getters 对象:用store.getters.discount可以获取到getter里discount对state计算后的结果

  当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性。


import { mapState } from 'vuex'
computed: {
...mapState(['totalPrice']) ... }

Banana.vue

<template>
<div>
<p>{{msg}} 单价{{price}}</p>
<button @click="addOne">add one</button>
<button @click="minusOne">minus one</button>
</div>
</template>
<script>
export default{
data(){
return{
msg:'banana',
price:15
}
},
methods:{
addOne(){
//直接commit一个mutation
this.$store.commit('increment',this.price)
},
minusOne(){
this.$store.commit('decrement',this.price)
}
}
}
</script>

addOne()函数里调用 store.commit 方法触发 type为"increment"的mutation;minusOne()函数里调用 store.commit 方法触发 type为"decrement"的mutation。

  可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用。

methods:{
addOne(){
this.increment(this.price)
},
minusOne(){
this.decrement(this.price)
},
...mapMutations(['increment', 'decrement'])
}

Apple.vue

<template>
<div>
<p> {{msg}}单价:{{price}} </p>
<button @click="addOne">add one</button>
<button @click="minusOne">minus one</button>
</div>
</template>
<script>
export default{
data(){
return{
msg:'apple',
price:5
}
},
methods:{
addOne(){
//dispatch一个action,以action作为一个中介再去commit一个mutation
this.$store.dispatch('increase',this.price)
},
minusOne(){
this.$store.dispatch('decrease',this.price)
}
}
}
</script>

  addOne()函数里调用 store.dispatch方法触发名为"increase"的action,对应的,在increase这个action里再去调用 context.commit方法触发 type为"increment"的mutation;minusOne()函数里调用 store.dispatch方法触发名为"decrease"的action,对应的,在decrease这个action里再去调用context.commit方法触发 type为"decrement"的mutation。action相当于中介。

mutations和actions的区别与联系:

action只能调用mutation不能直接更改state,执行 action 来分发 (dispatch) 事件通知 store 去改变。
action里可以进行一些异步的操作,再去触发mutation 。
mutation里必须是同步的触发操作state。

Vue-认识状态管理vuex的更多相关文章

  1. Vue之状态管理(vuex)与接口调用

    Vue之状态管理(vuex)与接口调用 一,介绍与需求 1.1,介绍 1,状态管理(vuex) Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态 ...

  2. vue创建状态管理(vuex的store机制)

    1:为什么说要是永远状态管理 在使用 Vue 框架做单页面应用时,我们时常会遇到传值,组件公用状态的问题.(子父间传值文章传送门) ,如果是简单的应用,兄弟组件之间通信还能使用 eventBus 来作 ...

  3. vue中状态管理vuex的使用分享

    一.main.js中引入 store import store from './store' window.HMO_APP = new Vue({ router, store, render: h = ...

  4. Vue状态管理vuex

    前面的话 由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue提供了vuex.本文将详细介绍Vue状态管理vuex 引入 当访问数据对象时,一个 V ...

  5. 状态管理Vuex

    路由Router 配置 {path:'/login',component:Login} 路由出口 router-view 传参 {path:'/login/:id',component:Login} ...

  6. Vue.js 2.x笔记:状态管理Vuex(7)

    1. Vuex简介与安装 1.1 Vuex简介 Vuex是为vue.js应用程序开发的状态管理模式,解决的问题: ◊ 组件之间的传参,多层嵌套组件之间的传参以及各组件之间耦合度过高问题 ◊ 不同状态中 ...

  7. 转 理解vuex -- vue的状态管理模式

    转自:https://segmentfault.com/a/1190000012015742 vuex是什么? 先引用vuex官网的话: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 ...

  8. vue总结 08状态管理vuex

      状态管理 类 Flux 状态管理的官方实现 由于状态零散地分布在许多组件和组件之间的交互中,大型应用复杂度也经常逐渐增长.为了解决这个问题,Vue 提供 vuex:我们有受到 Elm 启发的状态管 ...

  9. vuex -- vue的状态管理模式

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 状态管理模式.集中式存储管理 一听就很高大 ...

  10. 理解Vue的状态管理模式Vuex

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 状态管理模式.集中式存储管理,一听就很高大 ...

随机推荐

  1. Power BI 与 Azure Analysis Services 的数据关联:4、Power BI 连接到Azure Analysis Services 并展示

    Power BI 与 Azure  Analysis Services 的数据关联:4.Power BI 连接到Azure  Analysis Services 过使用服务器名称别名,用户可以使用较短 ...

  2. 操作过程-CentOS7下添加新硬盘扩充已经存在的逻辑卷分区的存储空间

    Linux添加硬盘扩充已有分区存储空间方式 总体步骤 磁盘初始化分区 创建物理卷 扩展卷组 扩展逻辑卷 通知文件系统生效 ​ 磁盘初始化分区 [root@oracledb ~]# fdisk -l 磁 ...

  3. 第四周读书笔记——读《我是一只IT小小鸟》有感

             读<我是一只IT小小鸟>有感 这是邓老师倾力推荐的一本书.这本书的标题化用了我们耳熟能详的歌词,算是较有新意吧.更重点在于,这本书的作者不是哪一位大牛,而是一群刚刚走出校 ...

  4. MySQL8.0——Resource Group(资源组)

    资源组介绍 简介 MySQL是单进程多线程的程序,MySQL线程包括后台线程(Master Thread.IO Thread.Purge Thread等),以及用户线程.在8.0之前,所有线程的优先级 ...

  5. [HDFS_4] HDFS 的 Java 应用开发

    0. 说明 在 IDEA下 进行 HDFS 的 Java 应用开发 通过编写代码实现对 HDFS 的增删改查操作 1. 流程 1.1 在项目下新建 Moudle 略 1.2 为 Moudle 添加 M ...

  6. 浅copy与深copy举例

     例1: #!/usr/bin/env python import copy d1 = {'x':1,'y':2,'z':[3,4.5]} d2 = d1 d3 = d1.copy() d4 = co ...

  7. postMessage 实现跨源通信 iframe 跨域获取url

    用postMessage实现跨源通信的方法实例 如:在www.bbb.com/index.html页面获取www.aaa.com/index.html的数据,以iframe的形式 www.aaa.co ...

  8. NOIP 2000 进制转换

    题目描述 我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以10为底数的幂之和的形式.例如:123可表示为 1\times 10^2+2\time ...

  9. 转://SQL PROFILE

    我们经常会碰到一些线上的SQL问题,因为执行计划不对,可能需要添加HINT才能解决.但是添加HINT就意味着需要修改应用代码.一般一个应用代码的修改.测试及发布,可能需要两三个工作日才可完成.咱们数据 ...

  10. 第一行代码 -3-1 软件也要拼脸蛋-UI界面

    <ListView android:id="@+id/list_view" android:layout_width="match_parent" and ...