Vuex 原理浅析笔记

Vuex 原理浅析笔记

技术杂谈小彩虹2021-07-12 11:07:5460A+A-

vuex

::运用场景:根据项目规模判断::

不能直接改变store,改变store唯一途径就是显示地提交mutations。这样使得我们可以方便跟踪每一个状态的变化,从而让我们实现一些工具帮助我们更好的了解我们的应用

state

单一状态书,用一个对象就包含了全部的应用层级状态

  • mapState 当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余
  • 对象展开符号 …mapState({{})
import { mapState } from 'vuex'
dexport default {
	computed: mapState({
		count: state => state.count,
		countAlias: 'count',
		countPlusLocalState (state) {
			return state.count + this.localCount
		}
		// ...mapState({count}) 扩展函数符
	})
}

getters

从store中的state 中派生出一些状态

  • mapGetters 辅助函数仅仅是将store中的getters映射到局部计算属性
  • 对state进行扩展,通过getters 进行设置 (相当于 computed,可以认为是store的计算属性) 公用的一些方法
const store = new Vuex.Store({
	state:{
		todos:[
			{id:1,text:'...',done:true},
			{id:2,text:'...',done:false}
		]
	},
	getters:{
		doneTodos:state => {
			return state.todos.filter(todo => todo.done)
		}
})
computed: {
	doneTodosCount () {
		return this.$store.getters.doneTodos
	}
}
computed:{
	...mapGetters([
		'doneTodosCount'
	])
}

mutations

  • 更改Vuex的store中的状态的唯一方法是提交mutation(不能直接调用句柄,必须通过触发)
  • mutations就是vue methods
  • 每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler)
  • 使用常量替代Mutation事件类型
  • mutation必须是同步函数
//mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'

//store.js
import { SOME_MUTATION } from './mutation-types'

const store = new Vuex.Store({
	state:{...},
	mutations:{
		[SOME_MUTATION](state){
			//mutate state
		}
	}
})
Mutations(调用篇)
import { mapMutations } from 'vuex'
import { SOME_MUTATION } from './mutation-types'

export default {
	methods:{
		test(){
			this.$store.commit(SOME_MUTATION)
		},
		...mapMutations([
			'SOME_MUTATION'
			//映射 this.increment()为this.$store.commit('SOME_MUTATION')
		])
	}
}

actions

接受用户传过来的event

  • 提交的是mutation
  • 可以包含任何异步操作
  • mapActions 辅助函数将组件的methods映射为store。dispatch调用
  • view -> store.dispatch(‘increment’)
  • action -> commit(‘someMutation’)
actions:{
	async actionA({commit}){
		commit('gotData',await getData())
	},
	async actionB({dispatch,commit}){
		await dispatch('actionA') //等待actionA完成
		commit('gotOtherData',await getOtherData())
	}
}
Action 调用
import { mapActions } from 'vuex'
export default {
	methods:{
		test(){
			store.dispatch('actionB')
		}
	},
	...mapActions([
		'actionB'
		//映射 this.increment()
		//this.$store.dispatch('actionB')
	])
}

modules

  • Vuex 运行我们将store分割到模块(module)。 每个模块拥有自己的state、mutation、action、getters甚至嵌套子模块——从上至下进行类似的分割
  • store创建之后,你可以使用store.registerModule方法注册模块
const moduleA = {
	state:{...},
	mutations:{...},
	actions:{...},
	getters:{...}
}

const moduleB = {
	state:{...},
	mutation:{...},
	action:{...}
}
const store = new Vuex.Store({
	modules:{
		a:moduleA,
		b:moduleB
	}
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
store.registerModule('myModule',{
	// ...
})

plugins

  • Vuex的store接受plugins选项,这个选项暴露出每次mutation的钩子。Vuex插件就是一个函数,它接受sotre作为唯一参数
  • 在插件中不允许直接修改状态——类似于组件,只能通过提交mutation来触发变化
  • 自定义的状态快照
//plugins 代码演示
const myPlugin = store => {
	//当store初始化后调用
	store.subscribe((mutation, state) => {
		//每次 mutation 之后调用
		// mutation 的格式为 {type, payload }
	})
}
const store = new Vuex.Store({
	plugins: [myPlugin]
})

Vuex 的思维处理表单

  • <input :value:"message" @input="updateMessage">
  • 测试Actions需要增加一个mocking服务层,测试文件中用mock服务回应API调用。为了便于解决mock依赖,可以用Webpack 和inject-loader打包测试文件
  • Hot Module Replacement API ,Vuex 支持在开发过程中热重载 mutation、modules、actions、getters
测试Actions 演示
import { expect } from ‘chai' const actionsInjector = require('inject!./actions') // 使用mocks创建模块 const actions = actionsInjector({ '../api/shop': { getProducts (cb) { setTimeout(() => { cb([ /* mocked response */ ]) },100) } } }) 

测试代码

describe('actions', () => {
	it('getAllProducts', done => {
		testAction(actions.getAllProducts,[]),{},[
		{type:'REQUEST_PRODUCTS'},
		{type:'RECEIVE_PRODUCTS',payload:{}}
	]},done)
})

vuex-router-sync

(sync 同步、async异步) vue 视图 vuex 数据源 vue-router 路由 vuex-router-sync 连接vuex\vue-router

视图层

<div id="app">
    <h1>Hello APP</h1>
    <p>
    	<router-link to="/foo">go to foo</router-link>
      <router-link to="/bar">go to bar</router-link>
    </p>
    <router-view></router-view>
 </div>

结合Vuex

import {  sync } from 'vuex-router-sync'
import store from './vuex/store'
import router from './router'
sync(store,router)
this.$store.state.route.path //current path (string)
this.$store.state.route.params //current params (object)
this.$store.state.route.query //current query (object)

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1

联系我们