X

XiaoSong

V1

2023/02/22阅读:25主题:默认主题

手写简易版VueX

VueX是我们常用的数据管理工具,接下来我带大家手写一个简易的VueX来深入了解一下其中的原理。

  1. 在src下新建store/myStore.js和index.js。
  2. 在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
  }
}
  1. 添加 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 }
  1. 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 }
  1. 创建一个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 }
  1. 在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 }
  1. 创建获取数据的函数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',
            LV3
        }
    },

    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>

分类:

前端

标签:

Vue.js

作者介绍

X
XiaoSong
V1