1. 程式人生 > 其它 >vue3中使用provide、project代替vuex

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;