CodeSandbox:https://codesandbox.io/s/61my3w7xrw?fontsize=14
我有一个使用作用域插槽的无渲染组件:
name: "BlockElement",
props: {
element: {
type: Object,
required: true
}
},
data() {
return {
inputValue: this.element.value
};
},
render() {
return this.$scopedSlots.default({
inputName: this.inputName,
inputValue: this.inputValue
});
}
像这样使用它:
<block-element :element="element" v-slot="{ inputName, inputValue }">
<div>
<input type="text" :name="inputName" v-model="inputValue">
<p>inputValue: {{ inputValue }}</p>
</div>
</block-element>
...因此该值不会在更改时更新。我在做什么错了?
答案 0 :(得分:1)
在模板的以下部分
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:id="@+id/staggered_feed_image_card"
app:cardCornerRadius="16dp"
app:cardElevation="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/no_dread"
android:id="@+id/staggered_feed_image"
android:scaleType="centerCrop"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
<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>
setter属性,该属性会将更新正确地委派给组件:
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,
});
}
现在对做什么没有任何困惑。