v-model 在 Vue 3 中不能与 一起使用吗?

huangapple go评论83阅读模式
英文:

v-model not working with <component> in Vue 3?

问题

I'll provide the translated code portion without addressing your request for translation:

为什么下面的示例中v-model不绑定到我的输入?`<component>`有限制吗?

<script setup>
import { ref } from 'vue'

const config = ref({
  headers: [
    { field: 'id', label: 'Id', component: { type: 'input' } },
    { field: 'name', label: 'Name', component: { type: 'input' } },
    // 更多用于单选按钮和其他自定义组件的配置
  ],
  data: [
    { id: 1, name: 'foo' },
    { id: 2, name: 'bar' }
  ]
})
</script>

<template>
  <table>
    <tr>
      <td v-for="header in config.headers">
        <b>{{ header.label }}</b>
      </td>
    </tr>
    <tr v-for="item in config.data">
      <td v-for="header in config.headers">
        <component :is="header.component.type" v-model="item[header.field]" />
      </td>
    </tr>
  </table>
  {{ config.data }}
</template>

Please note that I have removed your request for not providing other content, and I've translated the code portion as requested.

英文:

Why isn't v-model binding to my input in the example below? Is there a limitation of &lt;component&gt;?

&lt;script setup&gt;
import { ref } from &#39;vue&#39;

const config = ref({
  headers: [
    { field: &#39;id&#39;, label: &#39;Id&#39;, component: { type: &#39;input&#39; } }, 
    { field: &#39;name&#39;, label: &#39;Name&#39;, component: { type: &#39;input&#39; }  },
    // more configs for radio buttons and other custom components
  ],
  data: [
    { id: 1, name: &#39;foo&#39; },
    { id: 2, name: &#39;bar&#39; }
  ]
})
&lt;/script&gt;

&lt;template&gt;
  &lt;table&gt;
    &lt;tr&gt;
      &lt;td v-for=&quot;header in config.headers&quot;&gt;
      	&lt;b&gt;{{ header.label }}&lt;/b&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr v-for=&quot;item in config.data&quot;&gt;
      &lt;td v-for=&quot;header in config.headers&quot;&gt;
        &lt;component :is=&quot;header.component.type&quot; v-model=&quot;item[header.field]&quot; /&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
  {{ config.data }}
&lt;/template&gt;

答案1

得分: 1

Vue的v-model在原生元素上运行得很好。

但是显然它无法与&lt;component :is一起工作。

您的代码生成

&lt;input modelvalue=&quot;foo&quot;&gt;

一个非常快速的解决方法是直接实现value的绑定。

:value=&quot;item[header.field]&quot; @input=&quot;item[header.field] = $event.target.value&quot;

但是然后您需要相应地更新您的组件,以便使用value而不是modelValue

更新

使用v-model:value的解决方法只能单向工作,与:value相同。

&lt;component :is=&quot;header.component.type&quot; v-model:value=&quot;item[header.field]&quot; /&gt;
const { createApp, ref } = Vue

const config = ref({
  headers: [
    { field: &#39;id&#39;, label: &#39;Id&#39;, component: { type: &#39;input&#39; } }, 
    { field: &#39;name&#39;, label: &#39;Name&#39;, component: { type: &#39;input&#39; }  },
    // 更多用于单选按钮和其他自定义组件的配置
  ],
  data: [
    { id: 1, name: &#39;foo&#39; },
    { id: 2, name: &#39;bar&#39; }
  ]
})

const App = {
  setup() {
    return { config, test: 1 }  
  }
}

const app = createApp(App)
app.mount(&#39;#app&#39;)
#app { line-height: 1.75; }
[v-cloak] { display: none; }
<div id=&quot;app&quot;>
<table>
    <tr>
      <td v-for=&quot;header in config.headers&quot;>
        <b>{{ header.label }}</b>
      </td>
    </tr>
    <tr v-for=&quot;item in config.data&quot;>
      <td v-for=&quot;header in config.headers&quot;>
        <component :is=&quot;header.component.type&quot; :value=&quot;item[header.field]&quot; @input=&quot;item[header.field] = $event.target.value&quot; />
      </td>
    </tr>
  </table>
  {{ config.data }}
  <hr/>
  v-model test: <input v-model=&quot;test&quot; />
</div>
<script src=&quot;https://unpkg.com/vue@3/dist/vue.global.prod.js&quot;></script>
英文:

Vue v-model does work well for native elements.

But it obviously fails to work together with &lt;component :is

Your code generates

&lt;input modelvalue=&quot;foo&quot;&gt;

The very quick workaround is to implement the binding of value directly.

:value=&quot;item[header.field]&quot; @input=&quot;item[header.field] = $event.target.value&quot;

But then you will need to update your components accordingly, to work with value instead of modelValue.

UPDATE

The workaround using v-model:value does work only in one way, same as :value.

&lt;component :is=&quot;header.component.type&quot; v-model:value=&quot;item[header.field]&quot; /&gt;

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const { createApp, ref } = Vue

const config = ref({
  headers: [
    { field: &#39;id&#39;, label: &#39;Id&#39;, component: { type: &#39;input&#39; } }, 
    { field: &#39;name&#39;, label: &#39;Name&#39;, component: { type: &#39;input&#39; }  },
    // more configs for radio buttons and other custom components
  ],
  data: [
    { id: 1, name: &#39;foo&#39; },
    { id: 2, name: &#39;bar&#39; }
  ]
})

const App = {
  setup() {
    return { config, test: 1 }  
  }
}

const app = createApp(App)
app.mount(&#39;#app&#39;)

<!-- language: lang-css -->

#app { line-height: 1.75; }
[v-cloak] { display: none; }

<!-- language: lang-html -->

&lt;div id=&quot;app&quot;&gt;
&lt;table&gt;
    &lt;tr&gt;
      &lt;td v-for=&quot;header in config.headers&quot;&gt;
        &lt;b&gt;{{ header.label }}&lt;/b&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr v-for=&quot;item in config.data&quot;&gt;
      &lt;td v-for=&quot;header in config.headers&quot;&gt;
        &lt;component :is=&quot;header.component.type&quot; :value=&quot;item[header.field]&quot; @input=&quot;item[header.field] = $event.target.value&quot; /&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
  {{ config.data }}
  &lt;hr/&gt;
  v-model test: &lt;input v-model=&quot;test&quot; /&gt;
&lt;/div&gt;
&lt;script src=&quot;https://unpkg.com/vue@3/dist/vue.global.prod.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年4月13日 16:54:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003526.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定