温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

vue3怎么使用provide实现状态管理

发布时间:2021-10-18 09:15:53 来源:亿速云 阅读:150 作者:小新 栏目:开发技术

这篇文章主要介绍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>
        <h2>{{ state.age }}</h2>
      </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>

    以上是“vue3怎么使用provide实现状态管理”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI