vuex
import { inject, reactive, computed } from 'vue'
// 创建唯一常量 用于inject获取数据
const STORE_KEY = 'store-key'
const useStore = () => {
return inject(STORE_KEY)
}
// 创建store
const createStore = (opts) => {
return new store(opts)
}
class store {
constructor(opts) {
// 将配置数据保存到全局
this.$store_opts = opts
// 将store数据通过reactive变成响应式数据
this.$my_store = reactive({
data: opts.state()
})
// 保存创建的mutations
this.$store_mutations = opts.mutations
// 保存创建的actions
this.$store_actions = opts.actions
// 保存创建的 getters
// 使用 Proxy 监听数据返回解包后的getters数据
this.getters = new Proxy(
{},
{
get: function (target, property) {
return target[property].value
}
}
)
// 保护 存在才执行
if (opts.getters) {
// 遍历 getters 数据使用 computed 包裹使其自动计算
Object.keys(opts.getters).map((key) => {
const func = opts.getters[key]
this.getters[key] = computed(() => func(this.state))
})
}
}
// 获取state返回保存的数据
get state() {
return this.$my_store.data
}
// 接收两个参数 类型 载荷
commit = (type, payload) => {
// 获取对应的 mutations 函数
const func = this.$store_mutations[type]
if (!func) {
// 提示不存在
console.warn('store actions is not', type)
return func
} else {
// 执行函数
func(this.state, payload)
}
}
dispatch = (type, payload) => {
// 获取对应的 actions 函数
const func = this.$store_actions[type]
if (!func) {
// 提示不存在
console.warn('commit mutations is not', type)
return undefined
} else {
// 执行函数 传入this 使其可以解构出 commit、state 等
// 返回函数 函数是 async 可以外部执行 await
return func(this, payload)
}
}
// vue 插件注册 固定写法
install = (app) => {
// 通过 provide 全局注入数据
app.provide(STORE_KEY, this)
}
}
export { createStore, useStore }
创建store 仓库
import { createStore } from './myVuex'
const store = createStore({
state: () => {
return {
num: 1,
info: {
name: '',
age: ''
}
}
},
mutations: {
setNum(state, data) {
state.num = data
},
setInfo(state, data) {
state.info = data
}
},
actions: {
async getInfo({ commit }) {
setTimeout(() => {
commit('setInfo', {
name: '嘿嘿嘿',
age: 18
})
}, 1000)
}
},
getters: {
double(state) {
return state.num * 2
}
}
})
export default store
vue注册
import myVuex from './vuex/index'
const app = createApp(App)
app.use(myVuex)
app.mount('#app')
测试代码
import { useStore } from '../../vuex/myVuex'
const store = useStore()
const storeState = computed(() => store.state)
console.log(storeState.value)
store.commit('setNum', 43)
console.log(storeState.value, '2')
const getInfo = async () => {
await store.dispatch('getInfo')
console.log(storeState.value, '2')
}
getInfo()
const num2 = computed(() => store.getters.double)
console.log(num2.value, 'num * 2')
版权声明:本文为mucuni原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。