深入Vue底层,手写一个vuex
Posted 欧阳呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入Vue底层,手写一个vuex相关的知识,希望对你有一定的参考价值。
深入底层,手把手教你写一个Vuex
1. Vuex是什么?什么场景下使用?
- Vuex是vue的一个插件,叫做状态管理模式,全局共享某一些状态
- 通俗来讲,当各组件需要共享某一组状态的时候,会用到Vuex,兄弟组件及跨级组件传值也可以派上用场(如果数据量不大,或者组件状态不需要共享也可以用中央信息插件event-bus)
2. Vuex的基本使用
- vue-cli 4.0 以上,在搭建脚手架的时候选择此项就可以
- 项目搭建完成,便会在src文件夹下看到一个store,这就是自动生成的仓库
- 以下是vuex的一些基本操作,供参考:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store(
state:
name: 'Vuex',
age: 18
,
// 可以看做vuex的计算属性
getters:
addName(state)
return `$state.name牛逼`
,
// 提交数据更改
mutations:
syncAdd(state, payload)
state.age += payload
,
syncReduce(state, payload)
state.age -= payload
,
// 处理异步,此处为异步提交数据
actions:
asyncReduce(commit, payload)
setTimeout( () =>
commit('syncReduce', payload)
, 1000)
,
// 管理多个模块,当vuex比较大的时候会用到
modules:
)
- vue组件中的调用
<template>
<div id="app">
<h2>$store.state.name</h2>
<div>$store.getters.addName</div>
<div>年龄: $store.state.age</div>
<div><button @click="add()">加10</button></div>
<div><button @click="reduce()">减10-异步</button></div>
</div>
</template>
<script>
export default
mounted ()
// 这里可以访问到 vuex中的整个store
console.log(this.$store)
,
methods:
// 同步加10
add()
this.$store.commit('syncAdd', 10)
,
// 异步减2
reduce()
// 会去找对应的action
this.$store.dispatch('asyncReduce', 2)
</script>
3. 手写一个vuex
- 从以上的应用,便可以反推出Vuex的基本源码
let Vue;
class Store
constructor(options = )
// 实现响应式 核心(刚刚直接拿过用户的数组放上去,是没有响应式的)
this.s = new Vue(
data()
return state: options.state
)
// 将用户传入的getters放到store实例之上
let getters = options.getters
this.getters =
// 通过循环,拿出键值,绑定访问器属性get 劫持对象的所有属性
Object.keys(getters).forEach((getterName) =>
Object.defineProperty(this.getters,
getterName,
get: () =>
// 执行此函数
return getters[getterName](this.state)
)
)
// 获取所有同步更新的操作方法
let mutations = options.mutations
// 放到实例上去
this.mutations =
// 订阅,下面commit是发布
Object.keys(mutations).forEach( (mutationName)=>
// 当前实例上,通过名找方法
this.mutations[mutationName] = (payload) =>
// 内部的第一参数是状态
mutations[mutationName](this.state, payload)
)
let actions = options.actions
this.actions =
forEachFn(actions, (actionName, fn) =>
this.actions[actionName] = (payload) =>
// fn 是这个玩意 asyncReduce
fn(this, payload)
)
// 提交更改,在当前store找到对应函数执行,通过名字找 发布
commit = (mutationName, payload) =>
this.mutations[mutationName](payload)
// action 分发的方法
dispatch = (actionName, payload) =>
this.actions[actionName](payload)
// 为了方便取值
get state()
return this.s.state
const install = (_Vue) =>
Vue = _Vue
Vue.mixin(
beforeCreate()
console.log('beforeCreate')
if (this.$options && this.$options.store) // 根实例
// 根实例增加$store属性
this.$store = this.$options.store
else
this.$store = this.$parent && this.$parent.$store
)
export default
install,
Store
- 总体思路就是在Vue实例上挂上一个store实例,使用Vue提供的install方法注入,之后将用户传入的都绑定上去即可
1. 希望本文能对大家有所帮助,如有错误,敬请指出
2. 原创不易,还请各位客官动动发财的小手支持一波(关注、评论、点赞、收藏)
3. 拜谢各位!后续将继续奉献优质好文
4. 如果存在疑问,可以私信我(主页有Q)
以上是关于深入Vue底层,手写一个vuex的主要内容,如果未能解决你的问题,请参考以下文章