vue3中使用provide、project代替vuex
阿新 • • 發佈:2022-02-16
在資料狀態並不複雜的情況下,可使用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;