X
XiaoSong
V1
2023/02/22阅读:25主题:默认主题
手写简易版VueX
VueX是我们常用的数据管理工具,接下来我带大家手写一个简易的VueX来深入了解一下其中的原理。
-
在src下新建store/myStore.js和index.js。 -
在myStore.js中创建一个 Store
类来管理数据:
在
Store
类中的constructor()
是构造函数,在new Store(options)
时自动调用。使用__state
来保存创建store对象
(new Store(options)
)时传进来的要处理的数据,其中使用reactive
包裹变成响应式数据。this
指向当前对象,this.__state
: 给store
对象添加__state
属性。__mutations
保存传来的mutations
对象,里面存放着处理数据的函数。
import {reactive} from 'vue'
class Store {
constructor(options) {
this.__state = reactive({
data: options.state()
})
this.__mutations = options.mutations
}
}
-
添加 creatStore()
用来创建store对象,并使用export
暴露出去。
import {reactive} from 'vue'
class Store {
constructor(options) {
this.__state = reactive({
data: options.state()
})
this.__mutations = options.mutations
}
}
function creatStore(options) {
return new Store(options)
}
export { creatStore }
-
在 Store
类内部添加一个install()
这个函数会在
app.use(store)
时执行, 给这个函数传递一个app
并且使用app.provide()
注册一个数据,这个数据在整个应用都可以被访问到,provide
接收两个参数,第一个参数是注入名
,第二个参数是被注入的数据,在获取数据的时候使用inject(注入名)
获取。
import {reactive, inject} from 'vue'
class Store {
constructor(options) {
this.__state = reactive({
data: options.state()
})
this.__mutations = options.mutations
}
install(app) {
app.provide(STORE_KEY, this)
}
}
function creatStore(options) {
return new Store(options)
}
export { creatStore }
-
创建一个 useStore()
并暴露出去,用来获取store
对象
import {reactive, inject} from 'vue'
class Store {
constructor(options) {
this.__state = reactive({
data: options.state()
})
this.__mutations = options.mutations
}
install(app) {
app.provide(STORE_KEY, this)
}
}
function creatStore(options) {
return new Store(options)
}
function useStore() {
return inject(STORE_KEY)
}
export { creatStore, useStore }
-
在Store类内部添加 commit
函数用来获取处理数据的函数并调用。
import {reactive, inject} from 'vue'
class Store {
constructor(options) {
this.__state = reactive({
data: options.state()
})
this.__mutations = options.mutations
}
commit (type) {
const entry = this.__mutations[type]
entry(this.state)
}
install(app) {
app.provide(STORE_KEY, this)
}
}
function creatStore(options) {
return new Store(options)
}
function useStore() {
return inject(STORE_KEY)
}
export { creatStore, useStore }
-
创建获取数据的函数 get state()
import {reactive, inject} from 'vue'
class Store {
constructor(options) {
this.__state = reactive({
data: options.state()
})
this.__mutations = options.mutations
}
get state() {
return this.__state.data
}
commit (type) {
const entry = this.__mutations[type]
entry(this.state)
}
install(app) {
app.provide(STORE_KEY, this)
}
}
function creatStore(options) {
return new Store(options)
}
function useStore() {
return inject(STORE_KEY)
}
export { creatStore, useStore }
以上就是手写的一个简易版的
VueX
, 接下来我们试一下能不能用,以下代码就不做过多介绍了,毕竟都是大家经常使用的。 在/store/index.js中:
import { creatStore } from "./myVueX"
const store = creatStore({
state() {
return {
name: 'xiaosong',
LV: 3
}
},
mutations: {
add(state) {
state.LV ++
}
}
})
export default store
找一个组件测试一下。当我们点击按钮时数字会+1
<template>
<div>
<button @click="add">{{ num }}</button>
</div>
</template>
<script setup>
import {ref, computed} from 'vue'
import {useStore} from '../stores/myVueX'
const store = useStore()
const num = computed(() => store.state.LV)
const add = () => {
store.commit('add')
}
</script>
作者介绍
X
XiaoSong
V1