vue3如何使用provide实现状态管理详解

 更新时间:2021年10月17日 11:40:06   作者:bluesky108  
Vue3中有一对新增的api,provide和inject,熟悉Vue2的朋友应该明,这篇文章主要给大家介绍了关于vue3如何使用provide实现状态管理的相关资料,需要的朋友可以参考下

前言

在 Vue 生态中, Vuex 这个官方的状态管理库在 Vue 应用开发中,为我们带来了非常便捷的功能。但是 Vuex 20K+ 的大小,也带来了一些成本,对于项目规模较小的应用来说, 引入 Vuex 只是为了存储用户信息之类的一小撮数据,有点不值得。

Vue2.2.x 在后期就提供了 provide/inject API 来帮我们实现跨层级组件之间的通信。

Vue3.x 把 provide 也放到了应用 API 上,这就更方便让我们在此基础上,实现一个基础的状态管理。

如何通过 provide/inject 实现 Vuex的功能

首先我们想一下大概的逻辑,把它做成一个插件,通过 use 方法注册到应用实例中。

在 install 方法中,通过 app.provide 方法,把数据挂载到根组件上,该数据应该是一个响应式数据,并且为了数据安全,应该对数据的变更进行限制,遵循单向数据流的设计,不能让用户直接的进行修改,所以在暴露数据时,应该对数据进行 readonly(只读) 处理。

实现类似 Vuex 的 useStore 功能,让用户通过此方法访问数据。

实现类似 Vuex 的 mapState、mapMutations 和 mapActions方法,简化操作。

用法直接跟 Vuex 一样。

在应用中注册此插件

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

import store from './store'

const app = createApp(App)

app.use(router).use(store).mount('#app')

插件的入口文件

在入口文件中,直接导出所有方法。

// sky-vuex/index.ts
export * from './main/index'

创建 store ,把对应的数据挂载到根组件上

store 本身是一个对象,包含 state 属性和 commit、dispatch 等方法。 store 最主要的一些功能就是让所有组件,都能拿到 store 对象,来获取 state 中的数据,以及调用相关方法来修改 state。

// sky-vuex/main/index.ts
import {inject, reactive, readonly} from 'vue'

const mainStoreSky = Symbol('main store key')

interface storeOptions {
  state?: any
  actions?: any
  mutations?: any
}

export const createStore = (options: storeOptions = {}) => { // 创建 store 对象
  const initOptions = {
    state: {},
    actions: {},
    mutations: {},
  }

  const mergeOptions: storeOptions = Object.assign(initOptions, options)

  const state = reactive(mergeOptions.state)

  const store = {
    state: readonly(state),
    dispatch(eventName: string, ...args: any[]) {
      mergeOptions.actions[eventName](store, ...args)
    },
    commit(eventName: string, ...args: any[]) {
      ...
    },
  }

  return {
    install(app: any) {
      app.provide(mainStoreSky, store)
    },
  }
}

export const useStore = (): any => { // 其他组件通过此方法,获取 store 对象
  return inject(mainStoreSky)
}

实现 mapState、mapMutations 和 mapActions方法

export const mapState = () => {
  const store = useStore()
  return store.state
}

export const mapActions = (eventName: string) => {
  const store = useStore()
  return (...args: any[]) => store.dispatch(eventName, ...args)
}

export const mapMutations = (eventName: string) => {
  const store = useStore()
  return (...args: any[]) => store.commit(eventName, ...args)
}

组件中使用

// store/index.ts
import { createStore } from '../sky-vuex/index'

export default createStore({
  state: {
    age: 18
  },
  mutations: {
    setAge(state: any, data: number) {
      state.age = data
    }
  },
})

// Home.vue
<template>
  <div class="home">
    <button @click="handleAge(23)">修改数据</button>
    <h1>{{ state.age }}</h1>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { useStore, mapActions, mapMutations } from '@/sky-vuex/index'

export default defineComponent({
  name: 'Home',
  setup() {
    const store = useStore()

    const handleAge = mapMutations('setAge')
    // const handleAge = mapActions('setAge')

    // const handleAge = () => {
    //   store.dispatch('setAge', 5)
    // }

    return {
      state: store.state,
      handleAge,
    }
  },
})
</script>

总结

至此已经实现了基础的 Vuex 功能,可以自己动手实践一下,进行优化,有问题欢迎大家提出

到此这篇关于vue3如何使用provide实现状态管理的文章就介绍到这了,更多相关vue3 provide实现状态管理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue-router路由懒加载和权限控制详解

    vue-router路由懒加载和权限控制详解

    这篇文章主要介绍了vue-router路由懒加载和权限控制的相关资料
    2017-12-12
  • vue-router传参的4种方式超详细讲解

    vue-router传参的4种方式超详细讲解

    我们在组件切换时经常会有传递一些数据的需求,这样就涉及到了路由传参的问题,下面这篇文章主要给大家介绍了关于vue-router传参的4种超详细方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • 在vue中实现iframe嵌套Html页面及注意事项说明

    在vue中实现iframe嵌套Html页面及注意事项说明

    这篇文章主要介绍了在vue中实现iframe嵌套Html页面及注意事项说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 为什么要使用Vuex的介绍

    为什么要使用Vuex的介绍

    今天小编就为大家分享一篇关于为什么要使用Vuex的介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • vue-element-admin中node-sass换成dart-sass,安装依赖报code 128多种问题的解决方法

    vue-element-admin中node-sass换成dart-sass,安装依赖报code 128多种问题的解决

    这篇文章主要介绍了vue-element-admin中node-sass换成dart-sass,安装依赖报code 128多种问题的解决方法,本文给大家分享问题原因分析及解决方法,需要的朋友可以参考下
    2023-02-02
  • Vue使用antd组件a-form-model实现数据连续添加功能

    Vue使用antd组件a-form-model实现数据连续添加功能

    这篇文章主要介绍了Vue使用antd组件a-form-model实现数据连续添加功能,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • Vue3项目中的hooks的使用教程

    Vue3项目中的hooks的使用教程

    今天我们稍微说一下 vue3 项目中的 hooks 的使用,其实这个 hooks 呢是和 vue2 当中的 mixin 是类似的,学习过 vue2 的小伙伴一定对 mixin 一定比较熟悉,快跟随小编一起来学习学习吧
    2022-08-08
  • vue中的el-tooltip提示黑框遮挡问题

    vue中的el-tooltip提示黑框遮挡问题

    这篇文章主要介绍了vue中的el-tooltip提示黑框遮挡问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 一步一步实现Vue的响应式(对象观测)

    一步一步实现Vue的响应式(对象观测)

    这篇文章主要介绍了一步一步实现Vue的响应式(对象观测),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • vue3更新的setup语法糖实例详解

    vue3更新的setup语法糖实例详解

    vue3上线已经很久了,许多小伙伴应该都已经使用过vue3了,下面这篇文章主要给大家介绍了关于vue3更新的setup语法糖的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04

最新评论