#vue.js #vuejs3
Вопрос:
У меня есть модальный компонент, который получает объект как v-model
. Этот объект содержит некоторые ключи, такие как id
или name
.
Теперь, если я сделаю это:
<template>
<div class="h-2/3 w-2/3 bg-green-500">
<input v-model="computedValue.id" />
{{computedValue}}
</div>
</template>
<script>
export default {
name: 'TestModal',
props: {
modelValue: {
type: Object,
},
},
emits: ["update:modelValue"],
data: () => ({
}),
computed: {
computedValue: {
get() {
return this.modelValue;
},
set(newValue) {
console.log("computedValue?")
this.$emit('update:modelValue', newValue)
}
},
},
methods: {
},
}
</script>
он console.log("computedValue?")
никогда не срабатывает, а также излучение не срабатывает.
Как я могу использовать «глубокий сеттер»?
Комментарии:
1. Смысл операций чтения-записи в том, что они могут быть либо прочитаны, либо записаны. Позволить ему мутировать
v-model="computedValue.id"
— это ошибка.
Ответ №1:
Подход, который я использую для этого, заключается в следующем. Возьмите начальную «копию» свойства в качестве переменной данных ( rwModel
). Используйте v-model
для взаимодействия с этой переменной, затем используйте наблюдателя для запуска события/выполнения некоторой работы всякий раз, когда переменная изменяется.
Преимущество в том, что вы никогда не пытаетесь изменить свойство, но вы также делаете минимум, чтобы избежать этого, поэтому его по-прежнему легко проверить и понять. Вы также можете получить старое значение в наблюдателе, что упрощает сравнение.
В качестве альтернативы вместо просмотра вы можете легко изменить это, чтобы иметь событие, которое запускает что — то с обновленными данными-например, кнопку сохранения в форме.
<template>
<div class="h-2/3 w-2/3 bg-green-500">
<input v-model="rwModel.id" />
{{rwModel}}
</div>
</template>
<script>
export default {
props: {
modelValue: {
type: Object,
},
},
emits: ["update:modelValue"],
data() {
return {
rwModel: this.modelValue,
}
},
watch: {
modelValue: {
deep: true,
handler(newValue) {
console.log("watchedValue?")
this.$emit('update:modelValue', newValue)
},
},
},
}
</script>
Ответ №2:
Что происходит: На <input>
элементе, v-model="property"
по сути, эквивалентно
:value="property" @input="property = $event"
,
что в вашем коде переводится как
:value="computedValue.id" @input="computedValue.id = $event"
.
Это установит идентификатор, но вычисляемый установщик никогда не сработает, так как вы устанавливаете computedValue
.
Решение: Поскольку вы хотите использовать внутреннее свойство, вам нужен более точный контроль над событием @input. Таким образом, вы можете просто заменить свои входные данные
v-model="computedValue.id"
с
:value="computedValue.id" @input="computedValue = $event"
Это вызовет ваш вычисляемый сеттер и выведет инструкцию консоли.
Примечание: Даже если computedValue = $event
это выглядит так, как будто мы устанавливаем computedValue
значение ввода, это не так. Поскольку мы написали сеттер для вычисляемого свойства, Vue разумно запускает сеттер при выполнении инструкции.
Комментарии:
1. Это отличная работа. Но, если у вас есть массив или объект в качестве опоры, вы потеряли реактивное вычисляемое свойство. Даже выдача изменений Vue не может обнаружить изменения в реквизите.