我有一个应用程序,我正在创建一个自定义组件,它将输出一行表格。它包含一个用户可调的数字字段,因此在该自定义组件中我正在使用quasar框架中的另一个自定义组件(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
?我知道我可以这样做,但我希望有一个更清洁的解决方案...
答案 0 :(得分:4)
更新:您可以通过根据道具计算可写的(支柱必须命名为&#39;值&#39;),将v-model
- 能力传播到层次结构中。 get
函数显然返回prop值; 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
}
}
}
}
}
});
&#13;
<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>
&#13;
答案 1 :(得分:0)
这就是我最终的结果 - 似乎是最简单的方法。我有点希望当“中间”组件有效地承诺不改变模型时,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>