V-модель не работает с <component> в Vue 3?

Почему 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>

Вы пытались заменить component :is = "header.component.type" на input?

Estus Flask 13.04.2023 11:01

@EstusFlask сделал небольшое обновление вопроса, чтобы уточнить, что я не хочу, чтобы он ограничивался полями ввода.

Johan 13.04.2023 11:22

Как выглядит ваш "компонент"? Каково текущее поведение, которое вы получаете, по сравнению с тем, что вы ожидаете? в настоящее время мы не можем исключить, что ваш установленный компонент не работает должным образом. Кроме того, приведенный выше комментарий от Estus Flasks был направлен на то, чтобы убедиться, что ваша идея/использование v-модели работает в первую очередь.

tjarbo 13.04.2023 11:26

@tjarbo Идея состоит в том, чтобы иметь возможность сделать <component :is = "header.component.type" v-model = "item[header.field]" v-bind = "header.component.props" />, который работает как для нативных элементов, так и для моих пользовательских компонентов. Я понимаю, что мои пользовательские компоненты должны реализовывать v-модель, но я ожидал, что она будет работать из коробки для ванильных элементов, таких как <input>

Johan 13.04.2023 11:30

Похоже, вам придется отключить v-модель для обработки возможных вариаций в header.component.type с помощью v-if

Estus Flask 13.04.2023 11:42

Этот случай очень интересен. Я буду исследовать это дальше.

Tolbxela 13.04.2023 14:08

Вот выпуск Vue GitHub: github.com/vuejs/core/issues/4428#issuecomment-1075329007. Когда-нибудь это будет исправлено.

Tolbxela 13.04.2023 19:29
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
7
106
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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?

Johan 13.04.2023 14:19

Я бы, возможно, так и сделал.

Tolbxela 13.04.2023 15:16

Другие вопросы по теме