vuex 核心概念

简介:

vuex借鉴了flux和redux的思想,但是flux和redux是独立且完整的构架,vuex是耦合与vue框架的,所以使用成本比flux、redux成本低;
 
什么时候用Vuex?

应用简单的时候用global event bus;如果需要构建中大型单页项目应用,考虑在组件外部管理状态用vuex;

如何使用:

通过简单的学习,对vuex的核心概念有了一定的了解,下面包含一些例子,有需要的话可以参考一下;

1. 安装

第一种方法:

npm i vuex -S   必须和vue的版本一致;默认为最新版本;

第二种方法:

在vue之后,直接引入vuex:

<script src="/path/to/vue.js"></script>

<script src="/path/to/vuex.js"></script>

如何使用:

简单的store  

import Vue from 'vue'   导入文件
import Vuex from 'vuex'
Vue.use(Vuex)  Vuex的插件引用

//可以设置store管理
export default new Vuex.Store({
    state,mutations,getter,action
})


所有的组件都能读到:
new Vue({
el:'#app',
router,
store,//依赖注入
template:'<App/>',
component:'App'
})

核心概念:

1. state就是一个纯对象,上面有一些状态挂载,而且一个应用应该只有

 const state = {//初始状态
    count:0, //设置变量
    quantity:10
} 

辅助函数:mapStates  要写在computed函数里面

使用方法:当state和mutations中不止一个数据的时候要加...

import {mapStates,mapMutations,mapGetter,mapAction} from 'vuex' 从vuex中抽离;
computed(){//计算属性,可以进行缓存,值不发生变话,不会重新xuanrandom
     myconut(){
         return 999
      },
       ...mapState([//私有维护使用对象展开运算符将此对象混入到外部对象中
         'count','quantity' //数组形式
       ])
       //第二种方式
       ...mapState({//私有维护使用对象展开运算符将此对象混入到外部对象中
            _count:count //对象形式;防止重名
       })
}
//第三种方式
  computed:mapState({//函数方式
        count:(state)=>{ 
           return state.count //就能直接拿到
  }      
})

2. 通过mutations操作state的唯一办法;需要通过commit调用mutations中的方法;

Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

const mutations = {//vuex定义的方法,可以传递参数
    increment(state,payload){//可以拿到仓库对象   可以传参
        state.count +=payload
    },
    reduce(state){//可以拿到仓库对象   减方法
        state.count ++
    },
    decrement(state,playload){   接收对象传参
        state.count += palyload.age
    }
}

在组件中调用mutations的方法;写在方法里面;
methods(){//调用mutations调用方法
     increment(mount){//随意定义名称 相当于 mutate
          this.$store.commit('increment',amount)//调用mutations的方法名称
     },
     reduce(){ 
       this.$store.commit('reduce')
     },
     decrement(){//
        this.$store.commit({//可以传递对象
         type:'decrement',
         person
       })
  },

辅助函数:mapMutations

methods:mapMutations({//优点问题
        <!-- increment:(context,person)=>{//第一种
            conetxt.commit('increment',person)
        } -->
        'increment'//第二种直接使用
    })
或者
    
...mapMutations({
       'increment','decrement'//在mutations中的方法
})

使用常量替代 Mutation 事件类型

mutation-type:js:引出matations中的方法

 export const  INCREMENT  = 'increment'
 export const  DECREMENT  = 'decrement'

在index.js中导入:
import {INCREMENT,DECREMENT } from './'


import * as mt  from './' 在引用的时候就可以[at.INCREMENT]
import * as at  from './' 在引用的时候就可以[mt.INCREMENT]

const mutations = {//vuex定义的方法,可以传递参数
    [mt.INCREMENT](state,payload){//可以拿到仓库对象 
        state.count +=payload
    },
    [mt.DECREMENT](state){//可以拿到仓库对象 
        state.count ++
    },
    [mt.DECREMENT](state,playload){
        state.count += palyload.age
    }
}
在组件中使用的时候也直接导入就可以;将'increment'进行替换就可以了;
在action中使用:

const actions = {
     [at.INCREMENT](context){//包含store的一些方法,
         context.commit(mt.INCREMENT)//暴露出来的
     }
}
3. Getter

如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它——无论哪种方式都不是很理想。做了一个过滤
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
index.js中添加getter方法:

const getters = {
check(state){
return state.count<0?0 :state.count
}
在调用的时候:
count(){
return this.$store.getter.check
}
或者:
...mapGetter(['mutiply'])
在暴露接口的时候也要将其暴露出去,
4. Action:

Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
在index.js中:

const actions = {
increment(context){//包含store的一些方法,
context.commit('increment')//暴露出来的
}
}

组件中调用:可以将可能执行的异步操作放在...mapActions,
methods:{
increment(){
this.$store.dispath('increment')
}
}
可以改为:...mapAction(['increment'])

增加一点小知识ES7的回调地域

新增了 async/await 两个关键词。async 可以声明一个异步函数,此函数需要返回一个 Promise 对象。await 可以等待一个 Promise 对象 resolve,并拿到结果。

在webapp 风行的时代,前端业务逻辑越来越复杂,往往几个 AJAX 请求之间互有依赖,有些请求依赖前面请求的数据,有些请求需要并行进行。还有在类似 node.js 的后端 JavaScript 环境中,因为需要进行大量 IO 操作,问题更加明显。这个时候使用回调函数来组织代码往往会导致代码难以阅读。

const actions = {
    async  increment(context){//包含state
         context.commit('increment',awaitnew promise((resolve,reject)=>{
             console.time('test')//执行完所需要的事件
             setTimeout()=>{
                resolve()//等待异步完成停止等待;输出commit结果
             },2000)
         })//暴露出来的
     }.
     async decrement(context){
         await context.dispath('increment')//等待上面increment执行完在执行这个
         await new Promise((resolve,reject)=>{
             resolve()
         })
         console.timeEnd('test)
         context.comit('dectement')//最后执行
     },
      async decrement(context){
         await context.dispath('decrement')//等待上面increment执行完在执行这个;返回promise对象
         await new Promise((resolve,reject)=>{
             //利用ajax也可以
             $.ajax({
                 url:,
                 success:function(){
                     resolve()
                 }
             })
         })
         console.timeEnd('test')
     }
      async decrement(,dispath,context){//抽离
         await dispath('decrement')//等待上面increment执行完在执行这个
         await new Promise((resolve,reject)=>{
             resolve()
         })
         console.timeEnd('test)
         commit('dectement')
     }
}
 
原文地址:https://www.cnblogs.com/naniandongzhi/p/8146319.html