VUE3(十二)provide和inject函數


父傳更深的后代
一般往深度層級傳遞值,有這兩種方式:
· provide / inject
· vuex

provide / inject

一看到“深”這個字,大家肯定第一想到的就Vue2中的provide / inject選項。沒錯,這套邏輯在vue3中同樣適用,這兩個選項變成了兩個方法。

provide允許我們向當前組件的所有后代組件,傳遞一份數據,所有后代組件能夠通過inject這個方法來決定是否接受這份數據。

大致的示意圖如下:

在這里插入圖片描述

實際應用場景

主要應用的場景有兩中,一種深度傳遞一個參數或者一個函數的時候,另一種是給插槽上不確定性的組件傳參的時候。

重點說一下給插槽上的組件傳參。先實現一個最外層的ValidateForm組件,它主要負責接受一整個表單數據和整個表單數據的校驗規則。其內部提供了一個插槽,用於放置一些不確定性的組件。還有一個ValidateFormItem組件可以接受一個字段名,通過這字段名准確知道需要校驗哪個字段(tips:功能其實和element-ui類似)。

組件化開發,需要將參數和功能進行解耦,所以我們這樣來設計:

ValidateForm:model,rules,只管接受整份表單的數據和校驗規則
ValidateFormItem:prop,只管接受字段名,只需知道自己需要驗證哪一個字段

<template>
  <ValidateForm ref="validateFormRef" :model="formData" :rules="rules">
    <ValidateFormItem label="用戶名" prop="keyword">
      <!-- field組件 -->
    </ValidateFormItem>
    <ValidateFormItem label="密碼" prop="password">
      <!-- field組件 -->
    </ValidateFormItem>
  </ValidateForm>
</template>

如果ValidateFormItem組件需要通過prop去效驗某個字段,那它就需要拿到那份表單的數據,通過formData[prop]去取到那個字段的值,那這份formData從哪里來呢?首先不可能每寫一個ValidateFormItem組件都傳遞一份。因為,實際開發中我們並不能確定在ValidateForm下要寫多少個ValidateFormItem組件,如果每寫一個都手動傳遞一份表單的數據,這些寫起來就會多了很多冗余的代碼而且也很麻煩。所以,就由ValidateForm這個組件獨立接受並分發下來。

ValidateForm

所以我們需要ValidateForm來向下分發數據。

<template>
  <form>
    <slot></slot>
  </form>
</template>


<script lang="ts">
import { defineComponent, provide } from 'vue'

export const modelKey = Symbol()
export const rulesKey = Symbol()


export default defineComponent({
  name: 'ValidateForm',
  props: {
    model: {
      type: Object
    },
    rules: {
      type: Object
    }
  },
  setup(props) {
    // 向后代發放數據
    provide(modelKey, props.model)
    provide(rulesKey, props.rules)

    return {}
  }
})
</script>

ValidateFormItem

ValidateFormItem接受上面傳遞的數據。

<script lang="ts">
import { defineComponent, reactive, inject, provide } from 'vue'
import { modelKey, rulesKey } from './ValidateForm.vue'


export default defineComponent({
  name: 'ValidateFormItem',
  props: {
    label: String,
    required: {
      type: Boolean,
      default: false
    },
    prop: String
  },
  setup(props) {
    // 接受ValidateForm傳下來的數據
    const model = inject<any>(modelKey, ref({}))
    const rules = inject<any>(rulesKey, ref({}))
    
    // 根據props.prop在model和rules分別取出需要 校驗的數據 和 校驗的規則
    console.log(model[props.prop])
    console.log(rules[props.prop])
    // 數據校驗的邏輯

    return {
      //...
    }
  }
})
</script>

provide / inject總結

在這篇文章Vue組件通信方式及其應用場景總結中,大佬對其的優缺點已經總結很好了。這里提一下它的缺點,就是不能解決兄弟組件的通信。

這里的provide和inject我也只是了解,在我的項目中並沒有實際應用,我使用的reactive替代vuex的方式來實現更深層次的組件傳值。這個后邊會介紹。

有好的建議,請在下方輸入你的評論。
歡迎訪問個人博客
https://guanchao.site

歡迎訪問小程序:

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM