vue3中使用provide、project代替vuex

在数据状态并不复杂的情况下,可使用provide、project代替vuex

 

在context文件夹下创建button.ts 主要用于button组件的状态管理: provide:是一个对象,或者是一个返回对象的函数。里面呢就包含要给子孙后代的东西,也就是属性和属性值

//  src/context/button.ts
import { provide, ref, Ref, inject, computed } from 'vue'
import { getAllCount } from '@/service'

定义interface

//  src/context/button.ts
interface ListContext {
    count: Ref<number>,
    message: Ref<string>,
    changeCount: (data: number) => void
}

provide方法:

//  src/context/button.ts
// provide名称,推荐用Symbol const listymbol = Symbol() export const buttonProvide = () => { const count = ref<number>(0); const message = computed(() => { return `数量为:${count}` }) //进异步请求 const changeCount = async function (data: number) { try { let res: any = await getAllCount("");
       count.value = res.data; } catch (error) {
       count.value = data; console.log(error) } } provide(listymbol, { count, message, changeCount }) } 

inject方法

//  src/context/button.ts
export const buttonInject = () => {
    const listContext = inject<ListContext>(listymbol);
    if (!listContext) {
        throw new Error(`buttonInject must be used after buttonProvide`);
    }
    return listContext
};

button组建的状态provide、inject方法就写好了,接下来需要另外写个index.ts 统一将他们暴露出去

//  src/context/index.ts
import { buttonProvide, buttonInject } from './button'
console.log("buttonInject", buttonInject)

export { buttonInject }
export const useProvider = () => {
    buttonProvide()
}

现在就可以使用了,这里必须先将provide挂载到某个你需要共用的地方,可以是某几个组件的父页面,也可以是APP.tsx

// App.tsx
import { defineComponent } from 'vue';
import { useProvider } from '@/context/index'
export const App = defineComponent({
  name: 'App',
  setup: (props) => {
    useProvider()
    return () => (
      <div>
        <div id="nav">
          <router-link to="/">Home</router-link> |
          <router-link to="/about">About</router-link>
        </div>
        <router-view />
      </div>
    )
  }
})

组件中调用

import { defineComponent } from 'vue';
import { Button } from 'ant-design-vue';
import { buttonInject } from '@/context/index'   
interface ButtonProps {
    type: any
}
const ButtonCom = defineComponent({
    setup(props: ButtonProps, { slots }) {
        const { count,message,changeCount } = buttonInject() 
        const handleClick = () => {
            changeCount(1)
        };
        return () => (
      <div>
{message} <Button type={props.type} onClick={handleClick}> {slots.default && slots.default()} </Button>
      </div> ) } }) export default ButtonCom;

 

posted @ 2022-02-16 10:58  飞驰的小马哥  阅读(802)  评论(0)    收藏  举报