VueJS单选按钮组件

11

我尝试在Vue.js中使这个自定义单选按钮组件正常工作。如何使单选按钮使用来自父组件的值进行选中?我知道可以使用v-model,并将其设置为其中一个输入值中的相同值,但似乎无法正常工作。

组件:

export default Vue.component('radioButton', {
  template,
  props: ['name', 'label', 'id', 'value']
})

组件模板:

<label class="radio" :for="id">
  <input type="radio" :id="id" class="radio-button" :value="value" :name="name">
   <span class="radio-circle">
  </span>
  <span class="radio-circle__inner">
  </span>
  <span class="radio-button__label">{{ label }}</span>
</label>

HTML:

<radio-button name="options" id="option-1" label="1" :value="selectedValue" />
<radio-button name="options" id="option-2" label="2" :value="selectedValue" />

你能否发布一个 jsfiddle,展示你已经完成的内容? - highFlyingSmurfs
2个回答

28
对于单选按钮(radio buttons),您需要将true或false作为checked属性传递以将其预设为某个状态。或者,您在v-model中的值应该等于单选按钮的value,这样它就会被选中。
在您发布的有限示例代码中,我认为您的标签是按钮索引,例如1、2、3等等...而且我认为您想要在selectedValue与该单选按钮的label匹配时选择其中一个按钮。例如,如果selectedValue为2,则您希望单选按钮2被选中。
假设上述内容是正确的,则您需要在radio-button组件模板中进行一行更改:
<input type="radio" class="radio-button" :value="label" :name="name" v-model="value">

注意:

  1. 你的按钮 label 是单选按钮的值。当你点击特定的单选按钮时,这就是你期望设置为 selectedValue 的值。

  2. 你在子组件中的 value 实际上是父组件中的 selectedValue,它表示当前选择的单选按钮。因此,应将其放入 v-model 中。

所以,根据表单输入绑定文档,如果 v-model 变量等于该单选按钮的值,则单选按钮将被选中。

但现在又有另一个问题:如果你点击另一个单选按钮,你希望父组件中的 selectedValue 发生变化。这不会发生,因为 props 仅提供了单向绑定。

要解决这个问题,你需要在子组件(单选按钮)中进行 $emit,并在父组件(你的表单)中捕获它。

下面是一个工作的 jsFiddle 示例:https://jsfiddle.net/mani04/3uznmk72/

在此示例中,你的表单模板将单选按钮组件定义如下:

<radio-button name="options" label="1" :value="selectedValue" @change="changeValue"/>
<radio-button name="options" label="2" :value="selectedValue" @change="changeValue"/>
无论何时当子组件内的值发生变化,它都会传递一个带有单选按钮标签的“change”事件给父表单组件的changeValue()方法。一旦父组件更改了selectedValue,你的单选按钮将自动更新。
希望这可以帮到你!

1
为了减少冗余,自Vue.js 2.3.0以来,您可以在父级上使用.sync修饰符,并使用模式update:propName发出事件。因此,不再需要定义@change。https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier - Thoomas

1
我个人会采用另一种方式,保留v-model指令并避免@change事件(如果需要执行任何其他逻辑,可以替换为@input)。这里的问题是v-model值等于单选按钮组件中的"value"属性。
props: {
    value: {},
    v_value: {},
    ....
}

所以你只需要传递真实的当前值进行一些检查,并在标签点击或输入更改时$emit该值,如果没有标签。

<label :for="id" @click="$emit('input', v_value)">
      <input type="radio" :value="label" :name="name" :id="id" /> {{ label }}
</label>

我还添加了一个带有简单HTML标记的版本(但已注释),以防您想要自定义外观的单选按钮:

<div class="label" @click="$emit('input', v_value)">
      <span>{{ label }}</span>
</div>

https://jsfiddle.net/Zyfraglover/ndcp8t6e/


这对于基于键盘的输入和辅助设备可能不起作用。 - luckydonald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接