vuex学习笔记
来源:互联网 发布:应聘淘宝客服被骗 编辑:程序博客网 时间:2024/05/21 06:26
vuex应用的核心就是store(仓库),仓库中包含着应用中大部分的状态(state)。1. vuex的状态是响应式的,当vue组件从store中读取状态时,若store的状态发生变化,那么相应的组件也会相应地得到高效的更新。2. 不能直接改变store中的状态。改变store中的状态唯一途径就是显式地提交(commit) mutations。
创建state实例const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }})
现在,通过store.state就可以获取 状态对象,以及通过store.commit方法触发状态变更:
store.commit('increment')console.log(store.state.count) => 1
我们是通过提交mutation的方式,而非直接改变store.state.count。这样可以更明确地追踪到状态的变化,也让我们更有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。实现如时间穿梭般的体验。
一.state
vuex使用单一状态树,用一个对象就包括了全部的应用层级状态,每个应用将紧紧包含一个stroe实例。单一状态树让我们能够直接定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用的状态快照。(时间穿梭于始终。)单状态数跟模块化并不冲突,能实现将状态和状态变更事件分布于各个子模块中。
vue通过stroe选项,将状态从根组件【注入】到每一个子组件中
const app = new Vue({ el:'#app', store, compents:{counter}, template:` <div class = 'app'> <counter></counter> <div> `})
以上代码在根实例中注册了store选项,该store实例会注入到根组件下的所有子组件中,且子组件能通过this.$store访问到。
const counter = { template:`<div>{{count}}</div>`, computed:{ count(){ return this.$store.state.count } }}如上,子组件counter中的计算属性获取了store实例
当需要获取多个状态时候,不必声明多个计算属性。
可以使用mapState辅助函数来帮助我们生成计算属性
import {mapState} from 'vuex'export default { computed:mapState({ count: state => state.count, countAlias: 'count', countPlusLocalState(state){ return state.count + this.localCount } })}
使用vuex并不意味着需要将所有的状态放入vuex。如果有些状态严格属于某个单组件,最好还是作为组件的局部状态。
二.Getters
有时候需要从store中的state中派生出一些状态,例如对列表进行过滤并计数:
computed:{ doneTodosCount(){ return this.$store.state.todos.filter(todo => todo.done).length }}
如果在多个子组件中都需要重复用到这个计算属性,那么就必须在每个子组件中都复制粘贴这个计算属性。
在vuex在store实例中定义了getters(可以认为是store的计算属性),那么子组件想要计算如上情况时,就只需要寻找在挂载在根实例上的store中的getters就可以了。
(store中的getters类似于vue实例的computed)
如下vuex实例:
const store = new Vuex({ state:{ todos:{ {id: 1,text: '...',done: true}, {id: 2,text: '...',done: false} } }, getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) } }})可以看到,getters中进行了有关state的计算。因此所有的子组件都可以直接从根组件的store.getters得到“计算属性”
在组件中的使用如下:
computed:{ doneTodosCount () { //通过获取从根组件上传来的stroe的对象的getters属性 return this.$store.getters.doneTodesCount } }
三.mutations
更改store中的状态的唯一方法是提交 mutation。mutations类似于事件,每一个mutation都有一个事件类型(type)和一个回调函数(handler)。这个回调函数就是我们实际进行状态更改的地方。
要唤醒一个mutation handler,使用相应的type调用store.commit方法:
const store = new Vuex.Store({ state: { count: 1 }, mutations: { increment (state) { //变更状态 state.count++ } }})store.commit('increment') //increment调用commit
可以向commit中传入额外的参数,即mutation的载荷(payload),一般是一个对象,可以包含多个字段并且易读。
//···mutations: { increment: (state, payload){ state.count += payload.amount }}store.commit('increment',{ amount: 10})//另一种风格是直接使用包含type属性的对象:store.commit({ type: 'increment', amount: 10})
mutation必须是同步函数。
任何在回调函数中进行的状态的改变都是不可追踪的在组件中提交mutations时,可以使用
this.$store.commit(xxx)
提交mutation,或者使用mapMutations辅助函数将组件中 的methods映射为store.commit
调用import { mapMuations } from 'vuex'export default { //··· methods: { ...mapMutations([ 'increment' //映射 this.increment() 为this.$store.commit('increment') ]), ...mapMutations([ add: 'increment' //映射this.add()为this.$store.commit('increment') ]) }}
四.Actions
Actions类似于mutations,不同在于
- Acitons提交的mutations,而不是直接变更状态
- Action可以包含任意异步操作(mutations必须是同步的)
const store = new Vuex.Store({ state:{ count: 0 }, mutaitons: { increment (state) { state.count ++ } }, actions: { increment (context){ context.commit('increment') } }})
Actions函数接受一个与store实例具有相同方法和属性的context对象。一般通过es6中的 参数解构来优化代码
actions:{ increment ({ commit }) { commit( 'increment' ) }}
分发 Action
Action通过store.dispatch方法触发:store.dispatch('increment')
之所以不直接commit mutation是因为mutation 必须是同步执行的。
于是使用dispatch分发actions,就可以在action中进行异步操作了Action的分发方式跟mutation的commit方式一样
//载荷方式store.dispatch('increment',{ amount: 10})//对象方式store.dispatch({ type: 'incrementAsync', amount: 10 })
actions实例,调用了异步api和分发多重mutations。通过提交mutations来记录action产生的副作用(即状态变更):
actions: { checkout ({commit, state},products) { //把当前购物车的物品备份起来 const savedCartItems = [...state.cart.added] //发出结账请求,然后乐观地清空购物车 commit(types.checkout_request) //购物api接受一个成功回调函数和一个失败回调 shop.buyProducts( products, //成功操作 () => commit(types.checkout_success), //失败操作 () => commit(types.checkout_failure,savedCartItems) ) }}
在组件中分发patch
你在组件中使用 this.$store.dispatch(‘xxx’) 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store):import { mapActions } from 'vuex'export default { // ... methods: { ...mapActions([ 'increment' // 映射 this.increment() 为 this.$store.dispatch('increment') ]), ...mapActions({ add: 'increment' // 映射 this.add() 为 this.$store.dispatch('increment') }) }}
组合actions
action通常是异步的,要想处理更加复杂的异步流程,需要组合多个action。可以让store.dispatch处理被触发的action回调函数返回promise,并且dispatch仍旧返回promise。actions: { actionA ({ commit }) { return new Promise( (resolve, reject) => { setTimeout(() => { commit('someMutation') resolve() } },1000) }) }//dispatch返回的是promise
现在就可以处理actionA返回来的promise
store.dispatch('actionA').then(() => { //...})
在另一个action中也可以
actions: {//... actionB( {dispatch, commit}) { return dispatch('actionA').then( () => { commit('someOtherMutation') }) }}//以此来实现组合多个actions
一个store.dispatch在不同模块中可以触发多个action函数。这种情况下,只有当所有的触发函数完成后,返回的promise才会执行
- Vuex学习笔记
- vuex学习实践笔记
- Vuex学习笔记
- vuex学习实践笔记
- vuex学习实践笔记
- vuex学习笔记
- Vuex 学习笔记
- vue之vue-router vuex学习笔记
- 基于vue-cli的vuex学习笔记
- Vuex 笔记
- vuex笔记
- VueX笔记
- vuex学习
- 学习vuex
- VUEX学习笔记(1)-实现计算器(附最详注释)
- Vuex源码阅读笔记
- vuex 使用笔记
- Vuex 学习总结
- MySQL 5.7.18 安装教程
- Linux-用shell脚本写一个进度条
- NGUI学习要点总结
- 策略模式
- HDU 5795 A Simple Nim (SG函数+打表找规律)
- vuex学习笔记
- 朱金付C++第五章
- (三)Redux:创建和使用Reducer
- 嵌入人生
- 刷题记录-luoguP1525 关押罪犯
- 小白学爬虫-----bs4的学习-1
- 【HNOI2016模拟4.4】Alphadog
- JS编程训练 | 题14:正确函数定义
- 单片机显示时钟