dsl*_*101 5 2-way-object-databinding vue.js vuejs2
我理解.sync在Vue 2.3中返回的修饰符,并将其用于实现"多选"问题和答案的简单子组件.父组件像这样调用子组件:
<question
:stem="What is your favourite colour?"
:options="['Blue', 'No, wait, aaaaargh!']
:answer.sync="userChoice"
>
Run Code Online (Sandbox Code Playgroud)
父项具有一个字符串数据元素,userChoice用于存储子组件的结果.孩子为选项提供问题和单选按钮.孩子的基本部分看起来像这样(我使用的是Quasar q-radio):
<template>
<div>
<h5>{{stem}}</h5>
<div class="option" v-for="opt in options">
<label >
<q-radio v-model="option" :val="opt.val" @input="handleInput"></q-radio>
{{opt.text}}
</label>
</div>
</div>
</template>
export default {
props: {
stem: String,
options: Array,
answer: String
},
data: () => ({
option: null
}),
methods: {
handleInput () {
this.$emit('update:answer', this.option)
}
}
}
Run Code Online (Sandbox Code Playgroud)
这一切都很好,除了如果父母然后更改userChoice由于应用程序中发生的其他事情的值,孩子不会更新单选按钮.我不得不把这个包含watch在孩子身上:
watch: {
answer () {
this.option = this.answer
}
}
Run Code Online (Sandbox Code Playgroud)
但感觉有点多余,我担心发布事件以更新父母的数据实际上会导致孩子'观察'事件也被激活.在这种情况下除了浪费几个周期之外它没有任何效果,但如果它记录或计算任何东西,那将是一个误报...
也许这是真正的双向绑定的正确解决方案(即动态父→子,以及子→父).我是否错过了如何连接双方的'in'和'out'数据?
如果你想知道,想要改变'userChoice'的父母最常见的情况是响应一个'Clear Answers'按钮,它会设置userChoice回一个空字符串.这应该具有'取消'所有单选按钮的效果.
您的构造有一些不起作用的奇怪之处,但answer.sync如果您将其传播到q-radio发生更改的组件,则基本上可以工作。更改父级中的答案可以正确处理,但要清除值,似乎您需要将其设置为对象而不是 null (我认为这是因为它需要可分配)。
更新
您的设置options是一个值得注意的事情,但不起作用。
我使用answer来q-radio控制其检查状态(v-model在收音机中有特殊行为,这就是我value与 结合使用的原因v-model)。从您的评论来看,似乎q-radio想要有一个可以设置的值。您应该能够使用基于 的计算来做到这一点answer,您可以使用它来代替option数据项:getreturns answer,并且set执行emit。我已经更新了我的代码片段以使用valprop forq-radio加上我描述的计算结果。发出proxyAnswer一个update事件,这正是.sync修饰符想要的。我还q-radio使用计算的代理来实现,但这只是为了获得应该已经烘焙到您的q-radio.
(我所描述的实际上是您对数据项和观察者所做的事情,但计算是封装它的更好方法)。
new Vue({
el: '#app',
data: {
userChoice: null,
options: ['Blue', 'No, wait, aaaaargh!'].map(v => ({
value: v,
text: v
}))
},
components: {
question: {
props: {
stem: String,
options: Array,
answer: String
},
computed: {
proxyAnswer: {
get() {
return this.answer;
},
set(newValue) {
this.$emit('update:answer', newValue);
}
}
},
components: {
qRadio: {
props: ['value', 'val'],
computed: {
proxyValue: {
get() {
return this.value;
},
set(newValue) {
this.$emit('input', newValue);
}
}
}
}
}
}
},
methods: {
clearSelection() {
this.userChoice = {};
}
}
});Run Code Online (Sandbox Code Playgroud)
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
<question stem="What is your favourite colour?" :options="options" :answer.sync="userChoice" inline-template>
<div>
<h5>{{stem}}</h5>
<div class="option" v-for="opt in options">
<div>Answer={{answer && answer.text}}, option={{opt.text}}</div>
<label>
<q-radio :val="opt" v-model="proxyAnswer" inline-template>
<input type="radio" :value="val" v-model="proxyValue">
</q-radio>
{{opt.text}}
</label>
</div>
</div>
</question>
<button @click="clearSelection">Clear</button>
</div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
553 次 |
| 最近记录: |