首页  >  问答  >  正文

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 天前315

全部回复(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
  • 取消回复