Vue3 实现共享数据三种方式

1. Vuex

1.1 安装vuex

npm install vuex@latest

1.2 创建store文件夹,创建index.js文件

在vuex@4.x中 创建vuex实例需要使用createStore方法

// store/index.js
import { createStore } from 'vuex'
import useLoginStore from './modules/login'

export default createStore({
    modules: {
        useLoginStore
    }
})
1.3 创建store/modules文件夹,创建login.js文件

在这里遇到了一个问题,就是需要使用createStore方法创建store实例,这样在应用模块的情况下是不生效的。如果在应用模块的情况下需要导出一个普通对象。如下:
问题解决参考:

// 问题解决参考:https://github.com/vuejs/vuex/blob/main/examples/composition/shopping-cart/store/modules/products.js
export default {
    namespaced: true,
    state:{
        ....
    },
    mutations:{
        ...
    },
    actions:{
        ....
    },
    getters:{
        ....
    }
}
1.5 挂载到vue应用上
createApp().use(store).mount('#app')
1.6 开始应用

注意:在vue3中,由于没有了this,所以需要使用引入useStore方法,来获取store实例。

import { useStore } from 'vuex'
setup(){
	const store = useStore();
	// 获取state
	store.state.useLoginStore.xxx
	// 异步请求
	store.dispatch('useLoginStore/xxx')
	// 同步状态
	store.commit('useLoginStore/xxx')
	// 获取getters OR 也可以通过:computed(()=> store.state.useLoginStore.xxx)
	store.getters['useLoginStore/xxx']
}

2. Global State

在vue3中,组件和响应式功能被隔离开了,也就是说在任意一个JavaScript文件中都可以使用响应式功能。不同vue2组件与响应式耦合在一起。那么可以借助这个特性创建全局状态
在这里插入图片描述

2.1 创建store文件夹,创建useLoginStore.js文件
// useLoginStore.js
const state = reactive({
    ....
})

const store = readonly(state);// 只读

function Login(){
    ...
}
function logout(){
    ...
}

export {
    store,
    Login,
    logout,
    ...
}

3. Provide / Inject

vue2中,提供了provideinject配置,可以让开发者在高层组件中注入数据,然后在后代组件中使用

在这里插入图片描述

除了兼容vue2的配置式注入,vue3composition api中添加了provideinject方法,可以在setup函数中注入和使用数据

在这里插入图片描述

考虑到有些数据需要在整个vue应用中使用,vue3还在应用实例中加入了provide方法,用于提供整个应用的共享数据

3.1 提供整个应用响应式对象,可以被后代组件使用
// useLoginStore.js
function provideLoginStore(app){
    const state = reactive({})
    function Login(){

    }
    function logout(){

    }
    app.use(key,{
        state,
        Login,
        logout,
    })
}

function useLoginStore(defalutValue = null){
    return inject(key, defalsutValue)
}

export {
    provideLoginStore,
    useLoginStore
}

3.2 进一步封装

未来可能会有很多个store,将useLoginStore抽离出去,直接维护这个index.js文件,然后main.js也只调用这个

// index.js
import { provideLoginStore } from './useLoginStore'
// 继续导入其他共享数据模块...
// import { provideStore as provideNewsStore } from "./useNews"s

// 提供统一的数据注入接口
function installStores(app){
    app.use(provideLoginStore);
    // 继续注入其他共享数据
    // provideNewsStore(app);
}

3.3 注册到全局
const app = createApp(App);
installStores(app);// 这样就把所有的store都注册到全局了
3.4 使用
// 子组件
import { injectStore } from './store/useLoginUser'

const store = injectStore();

对比

vuexglobal stateProvide&Inject
组件数据共享
可否脱离组件
调试工具
状态树自行决定自行决定
量级
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值