首頁  >  問答  >  主體

Vue 3 消除了組件 props 的反應性

我有 EditTransaction 元件並像這樣呼叫它:

<edit-transaction
    v-if="editableTransaction.id === transaction.id"
    :key="'transaction'+transaction.id+etcount"
    :class="{'bg-red-300': type === 'expense', 'bg-green-300': type === 'income'}"
    :groups-prop="modelValue"
    :transaction="transaction"
    class="planning-transactions-item px-10 rounded-2xl w-[90%]"
    @close="editableTransaction = {id: null}">
</edit-transaction>

如您所見,我正在其中發送一個交易物件。由於這是一個編輯器,我不希望事務物件是反應性的。如果有人關閉編輯器,我想要原始事務對象而不是修改過的事務對象,所以如果我是正確的並且想要刪除代理,我會將其放入編輯器中:

const form = toRaw(props.transaction)

在編輯器範本內部,有一些資產元件,它們的 v-model 值綁定到表單物件

<div class="flex gap-5 w-full">
    <FormInput id="et-date" v-model="form.due_date" class="et-fields tw-fields w-[150px]"
               placeholder="Date"
               type="date"
               @keyup.enter="saveChanges"></FormInput>
    <FormInput id="et-name" v-model="form.name" class="et-fields tw-fields" placeholder="Name"
               @keyup.enter="saveChanges"></FormInput>
    <FormInput id="et-value" v-model="form.value" class="et-fields tw-fields" mask-thousand
               placeholder="Value"
               @keyup.enter="saveChanges"></FormInput>
</div>

問題是,當我更改交易名稱時,表單物件會更改,而且事務屬性也會更改。因此,父資料中的名稱也會發生變化,因為事務屬性是反應性的。 我做錯了什麼或如何實現一個表單對象,該對象的值在組件創建時使用 props 值填充並且沒有任何代理?

P粉337385922P粉337385922211 天前317

全部回覆(2)我來回復

  • P粉950128819

    P粉9501288192024-03-22 09:25:51

    使用 props 將初始值傳遞給子元件的狀態是很常見的。這表示您「複製」了本地 data 中某個 prop 的值。它可以確保 prop 值免受意外更改的影響: 在 Vue 中閱讀更多內容文檔

    這是一個非常簡單的範例,展示了上述方法:

    /your-child-component-vue/

    #
    export default {
      props: ['initialCounter'],
      data() {
        return {
          // counter only uses this.initialCounter as the initial value;
          // it is disconnected from future prop updates.
          counter: this.initialCounter
        }
      }
    }
    

    現在,閱讀您的範例,我發現您正在嘗試更新表單中的某些數據,並且您不想更改初始信息,除非透過按鈕或其他內容確認。解決這個問題的流程是:

    • 將使用者可能變更的初始資料作為 prop 傳遞。
    • 如果使用者透過輸入元素更改了某些數據,但未確認這些更改(透過按鈕),請保持數據不變(這表示您不會向父元素發出任何更改,保持prop 值不變)
    • 如果使用者更改了某些資料並確認了它,則將更新後的資料傳送給父級 (this.$emit),以便它了解變更。

    回覆
    0
  • P粉573943755

    P粉5739437552024-03-22 00:34:17

    所以我找到了兩個解決方案:

    const form = reactive({...props.transaction})

    const form = Object.assign({}, props.transaction)

    兩者都有效,當我更改表單值時,它不會改變道具。

    回覆
    0
  • 取消回覆