欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue3使用provide/inject实现全局变量功能,部分摆脱vuex

程序员文章站 2022-03-27 17:11:02
...

vue3新的provide/inject功能可以穿透多层组件,实现数据从父组件传递到子组件。

这时将所有需要使用的全局变量在根组件就provide,这样,所有的组件都能使用到这个变量。

如果需要变量是响应式的,就需要在provide的时候使用ref或者reactive包装变量。

for (let key in store) {
    let type = typeof store[key]
    if (type == 'function') {//这里是粗略的写法,目前当类型是函数时,直接provide
        app.provide(key, store[key])//这里的app是install函数中提供的app,其中包含了provide
    } else if (type == 'object') {//是对象时,使用reactive包装
        app.provide(key, reactive(store[key]))
    } else {//是其他值时,使用ref包装,这时调用需要使用.value
        app.provide(key, ref(store[key]))
    }
}

把上面的代码整和为vue3插件。这里定义一个createStore函数用来指示需要进行管理的全局变量。

/*
*  ./plug.js
*/
function createStore(store) {
    return {
        install: (app, options) => {//返回的对象中需要包含install函数。
            for (let key in store) {
                let type = typeof store[key]
                if (type == 'function') {
                    app.provide(key, store[key])
                } else if (type == 'object') {
                    app.provide(key, reactive(store[key]))
                } else {
                    app.provide(key, ref(store[key]))
                }
            }
        }
    }
}
export {
    createStore
}

在store文件夹中,我们可以像vuex一样调用createStore函数,然后导出这个函数返回的结果,这个结果需要在main.js中use。

import {createStore} from "./plug"
export default createStore({
    //这里是全局变量
    key1:'value1',
    key2:{
    	a:53,
    }
})

之后再main.js中像vuex一样use引用就行

import { createApp } from 'vue'
import App from './App.vue'
import store from  './store/index'
createApp(App).use(store).mount('#app')

使用时,只需要inject变量名就行。

let global_events = inject("global_events");

为什么这里不使用原先vue2那种this写法呢?因为在vue3中setup中的组合式API写法,已经不提倡继续使用this了。而且由于在执行 setup 时尚未创建组件实例,因此在 setup 选项中没有 this。

我们还可以借此实现全局的event系统,实现eventbus。下期将在此基础上实现event系统