Почему 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' } },
// more configs for radio buttons and other custom components
],
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>
@EstusFlask сделал небольшое обновление вопроса, чтобы уточнить, что я не хочу, чтобы он ограничивался полями ввода.
Как выглядит ваш "компонент"? Каково текущее поведение, которое вы получаете, по сравнению с тем, что вы ожидаете? в настоящее время мы не можем исключить, что ваш установленный компонент не работает должным образом. Кроме того, приведенный выше комментарий от Estus Flasks был направлен на то, чтобы убедиться, что ваша идея/использование v-модели работает в первую очередь.
@tjarbo Идея состоит в том, чтобы иметь возможность сделать <component :is = "header.component.type" v-model = "item[header.field]" v-bind = "header.component.props" />
, который работает как для нативных элементов, так и для моих пользовательских компонентов. Я понимаю, что мои пользовательские компоненты должны реализовывать v-модель, но я ожидал, что она будет работать из коробки для ванильных элементов, таких как <input>
Похоже, вам придется отключить v-модель для обработки возможных вариаций в header.component.type с помощью v-if
Этот случай очень интересен. Я буду исследовать это дальше.
Вот выпуск Vue GitHub: github.com/vuejs/core/issues/4428#issuecomment-1075329007. Когда-нибудь это будет исправлено.
Vue v-model
хорошо работает с нативными элементами.
Но это явно не работает вместе с <component :is
Ваш код генерирует
<input modelvalue = "foo">
Очень быстрый обходной путь — реализовать привязку value
напрямую.
:value = "item[header.field]" @input = "item[header.field] = $event.target.value"
Но тогда вам нужно будет соответствующим образом обновить свои компоненты, чтобы работать с value
вместо modelValue
.
ОБНОВЛЯТЬ
Обходной путь с использованием v-model:value
работает только одним способом, как и :value
.
<component :is = "header.component.type" v-model:value = "item[header.field]" />
const { createApp, ref } = Vue
const config = ref({
headers: [
{ field: 'id', label: 'Id', component: { type: 'input' } },
{ field: 'name', label: 'Name', component: { type: 'input' } },
// more configs for radio buttons and other custom components
],
data: [
{ id: 1, name: 'foo' },
{ id: 2, name: 'bar' }
]
})
const App = {
setup() {
return { config, test: 1 }
}
}
const app = createApp(App)
app.mount('#app')
#app { line-height: 1.75; }
[v-cloak] { display: none; }
<div id = "app">
<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" :value = "item[header.field]" @input = "item[header.field] = $event.target.value" />
</td>
</tr>
</table>
{{ config.data }}
<hr/>
v-model test: <input v-model = "test" />
</div>
<script src = "https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
Итак, я думаю, самым надежным способом было бы обернуть все компоненты, включая нативные, в оболочку, реализующую унифицированную v-модель? Например. :modelValue = "item[header.field]"
и заставить компоненты реализовывать/генерировать @update:modelValue
?
Я бы, возможно, так и сделал.
Вы пытались заменить
component :is = "header.component.type"
наinput
?