我有一个应用程序,我正在为其创建一个自定义组件,该应用程序将输出表的一行。它包含一个数字字段,该数字字段是可调节的,因此在该自定义组件中我正在使用Quasar Framework(q-numeric
(中的另一个自定义组件。我正在努力看到如何通过2个组件在顶部级别绑定一个变量 - 也许不能直接完成,但是我希望避免中间组件中的大量额外代码。到目前为止,从上到下看起来这样:
在app.vue模板中,我有这样的行:
<config-item v-model="numParticipants">Number of Participants</config-item>
configitem.vue,看起来像这样:
<template>
<tr>
<td class="text-right"><slot></slot></td>
<td class="text-right">
<q-numeric
v-model="value"
:min="min"
:max="max"
:step="step"
@input="$emit('input', value)"
></q-numeric>
</td>
</tr>
</template>
<script>
export default {
props: {
label: String,
value: Number,
min: {
type: Number,
default: 1
},
max: {
type: Number,
default: 1000
},
step: {
type: Number,
default: 1
}
}
}
</script>
当然这不起作用,因为我现在将属性 value
绑定到 q-numeric
,这将变为它。确实,我不想将顶级变量numParticipants
绑定到q-numeric
-是否可以在我的config-item
组件中实现某种"通过"?还是我的组件需要具有其自己的数据元素,从传递属性开始初始化,并根据q-numeric
进行更新?我知道我 can 这样做,但是我希望有一个更清洁的解决方案...
更新:您可以通过制作基于道具计算的可写(必须命名为'value'(来传播 v-model
的层次结构。get
函数显然返回道具值;set
函数执行$emit
。
计算的规格是完全固定的,因此我将其提取为常数。
const vModelComputed = {
get() {
return this.value;
},
set(newValue) {
this.$emit('input', newValue);
}
};
new Vue({
el: '#app',
data: {
numParticipants: 1
},
components: {
middleComponent: {
props: ['value'],
template: '<div>Value: {{value}} <q-numeric v-model="localValue"></q-numeric></div>',
computed: {
localValue: vModelComputed
},
components: {
qNumeric: {
props: ['value'],
template: '<div><input v-model="localValue" type="number"> inner value: {{value}}</div>',
computed: {
localValue: vModelComputed
}
}
}
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<div id="app">
Participants: {{numParticipants}}
<middle-component v-model="numParticipants"></middle-component>
</div>
这是我最终得到的 - 似乎是最简单的方法。我有点希望Vue有一个机制可以将其隐藏起来,而"中间"组件有效承诺不更改模型,而只是想将其移交给孩子。
基本上,我创建了一个中介数据元素ivalue
,并在mounted()
事件中初始化了它,并使用孩子的input()
事件将input()
事件发给父母。
<template>
<tr>
<td class="text-right"><slot></slot></td>
<td class="text-right">
<q-numeric
v-model="ivalue"
:min="min"
:max="max"
:step="step"
@input="$emit('input', ivalue)"
></q-numeric>
</td>
</tr>
</template>
<script>
export default {
data: () => ({
ivalue: 0
}),
mounted () {
this.ivalue = this.value
},
props: {
label: String,
value: Number,
min: {
type: Number,
default: 1
},
max: {
type: Number,
default: 250000
},
step: {
type: Number,
default: 1
}
}
}
</script>