简介:
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')
}
}