В следующей части шаблона
<input type="text" :name="inputName" v-model="inputValue">
inputValue
- это переменная, полученная из v-slot
, а не вычисляемое свойство inputValue
для компонента <block-element>
;поэтому, если вы присваиваете ему (что делает v-model
), он не будет вызывать сеттер, он просто устанавливает значение локальной переменной в коде шаблона.
Вы можете «исправить» этокак это:
<block-element :element="element" v-slot="{ inputName }" ref="block">
<div>
<input type="text" :name="inputName" v-model="$refs.block.inputValue">
<p>inputValue: {{ $refs.block.inputValue }}</p>
</div>
</block-element>
, но это просто грязно и нарушает абстракцию, которую вы пытались создать.
Другой способ - иметь свойство сеттера inputValue
для объекта области действия, которое будет правильноделегируйте обновление компоненту:
render() {
const self = this;
return this.$scopedSlots.default({
inputName: this.inputName,
get inputValue() { return self.inputValue },
set inputValue(value) { self.inputValue = value; },
});
}
<block-element :element="element" v-slot="scope">
<div>
<input type="text" :name="scope.inputName" v-model="scope.inputValue">
<p>inputValue: {{ scope.inputValue }}</p>
</div>
</block-element>
, но это также не идеально, поскольку объект области видимости обычно не доступен для записи, и эта конкретная деталь реализации должна быть задокументирована.
В такой ситуации, когда вы хотите, чтобы слот с областью действия передавал данные обратно в родительский компонент, вы могли бы реализовать это, передав функцию обратного вызова в слот.Вы можете предоставить функцию для установки inputValue
, но тогда вы не сможете использовать v-model
:
render() {
return this.$scopedSlots.default({
inputName: this.inputName,
inputValue: this.inputValue,
setInputValue: value => this.inputValue = value,
});
}
<block-element :element="element" v-slot="{ inputName, inputValue, setInputValue }">
<div>
<input type="text" :name="inputName" :value="inputValue" @input="setInputValue($event.target.value)">
<p>inputValue: {{ inputValue }}</p>
</div>
</block-element>
Теперь нет никаких сомнений относительно того, что делать.