如何将 `value` 道具和 `v-model` 道具分配给自定义 Vue 组件?

Posted

技术标签:

【中文标题】如何将 `value` 道具和 `v-model` 道具分配给自定义 Vue 组件?【英文标题】:How to assign `value` prop and `v-model` prop to custom Vue component? 【发布时间】:2021-03-07 07:35:19 【问题描述】:

我想为“radio div”创建一个自定义的 Vue 组件——一个 div(带有一个用于包含我想要的任何内容的插槽),它就像一个单选按钮,因此您可以选择它,并且只能选择一个多个同名。

一般来说,VueJS 中的单选按钮如下所示:

<input type="radio" name="name" value="value" v-model="variable" />

所以我想要一个类似的 API:

<div-radio name="name" value="value" v-model="variable" />

但是,当我查找 how to add v-model support to custom component 时,我在 Google 上找到的第一个链接声称:

对于input 元素,您可以像这样使用v-model

<input v-model="email" />

v-model 翻译成这样:

<input :value="email" @input="e => email = e.target.value" />

如果v-model 转换为:value@input,那么似乎不可能同时拥有一个名为“value”的道具和“v-model”——尽管事实上这就是普通的 VueJS单选按钮工作

我是否误解了v-model 的工作原理?还是有替代解决方案?还是我想要的不可能?

【问题讨论】:

【参考方案1】:

Vue 允许通过组件的model 选项配置v-modelprop 名称和event 名称:

model

2.2.0 中的新功能

类型: prop?: string, event?: string

详情:

允许自定义组件自定义与v-model 一起使用时使用的道具和事件。默认情况下,组件上的v-model 使用value 作为道具,input 作为事件,但某些输入类型(例如复选框和单选按钮)可能希望将value 道具用于不同的目的。使用model 选项可以避免这种情况下的冲突。

示例:

Vue.component('my-checkbox', 
  model: 
    prop: 'checked',
    event: 'change'
  ,
  props: 
    // this allows using the `value` prop for a different purpose
    value: String,
    // use `checked` as the prop which take the place of `value`
    checked: 
      type: Number,
      default: 0
    
  ,
  // ...
)
<my-checkbox v-model="foo" value="some value"></my-checkbox>

以上将等价于:

<my-checkbox
  :checked="foo"
  @change="val =>  foo = val "
  value="some value">
</my-checkbox>

【讨论】:

【参考方案2】:

要使用 v-model,您需要手动处理 value 和 @input:

<template>
 <div>
  <input type="radio" :name="name" :value="value" @input="$emit('input', $event)" />
 </div
</template>

<script>
 export default 
  name: 'div-radio',
  props:
    value: Boolean,
    name: String
  
 
</script>

在宿主组件中,将其视为普通组件:

...
<div-radio name="name" v-model="variable1" />
<div-radio name="name" v-model="variable2" />
... 

【讨论】:

以上是关于如何将 `value` 道具和 `v-model` 道具分配给自定义 Vue 组件?的主要内容,如果未能解决你的问题,请参考以下文章

作为对象的 Vue 道具的反应性

如何使用子组件的道具更新父 v-model?

如何在输入中一起使用 :value 和 v-model

如何正确使用 v-model 和 Composition API :value="modelValue" 语法?将 Vue2 自定义输入转换为 Vue3

为啥 vue v-model 不适用于数组道具?

VueJS:同时使用 v-model 和 :value