Как использовать v-модель Vue3 + TypeScript для текстового поля? "ОШИБКА: недопустимая цель назначения"

Полная ошибка:

[plugin:vite:vue] Transform failed with 1 error:
/home/projects/vue3-vite-typescript-starter-jkcbyx/src/App.vue:33:73: 
ERROR: Invalid assignment target

"/home/projects/vue3-vite-typescript-starter-jkcbyx/src/App.vue:33:73"

Invalid assignment target
31 |        ? (_openBlock(), _createElementBlock("div", _hoisted_2, [
32 |            _withDirectives(_createElementVNode("textarea", {
33 |              "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($setup.np?.description) = $event))
   |                                                                           ^
34 |            }, null, 512 /* NEED_PATCH */), [
35 |              [

Вот App.vue:

<script setup lang = "ts">
import { ref } from 'vue'

interface Thing {
  description: string
}

const np = ref<Thing>({
  description: 'asdf asdf asdf',
})
</script>

<template>
  {{ np?.description }}
  <br />
  <textarea v-model.trim = "np?.description"></textarea>
</template>

ЗДЕСЬ полное воссоздание ошибки:


Любая помощь здесь приветствуется <3
Эта проблема довольно запутанная.

возможно, стоит отметить ту же ошибку, если вместо нее используется const np = reactive<>().

Rio Weber 15.11.2022 19:26

Ваш код в порядке, но шаблон, похоже, не может обрабатывать необязательный оператор цепочки в v-model = "np?.description". Это может быть связано с версиями Vite/компиляторов, которые использует stackblitz. Если вы удалите оператор, он компилируется нормально.

stellr42 15.11.2022 19:30
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
2
2
209
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы не можете использовать двойную привязку (v-model) с дополнительной цепочкой (np?.description). Двойное связывание означает геттер и сеттер. Что, как вы ожидаете, установит сеттер, когда np будет ложным? Я знаю, что вы завернули его в v-if, но необязательная цепочка сообщает v-model, что структура целевого объекта, возможно, undefined, и это недопустимая цель присваивания.

Один из способов сделать это — создать вычисляемый description, где вы указываете, как установить np.description, когда текущее значение np позволяет это сделать:

const description = computed({
  get() {
    return np.value?.description || ''
  },
  set(description) {
    if (typeof np.value?.description === 'string') {
      np.value = { ...np.value, description }
    }
  },
})

Посмотрите, как это работает здесь: https://stackblitz.com/edit/vue3-vite-typescript-starter-wrvbqw?file=src%2FApp.vue


Вышеприведенное является довольно общим решением (когда вам действительно нужно использовать необязательную цепочку с v-model).
Более простая альтернатива в вашем случае (возможно, потому что вы обернули <textarea> в v-if = "np") вообще не использует необязательную цепочку с v-model:
заменить v-model.trim = "np?.description" на v-model.trim = "np.description".

Это сработает.

Да, это было так, большое спасибо. Я не сомневался в ?, потому что, когда я нажимал «вкладку» в своем редакторе для автозаполнения, там помещалось ?. я чувствую себя глупо

Rio Weber 15.11.2022 19:37

Не! JavaScript сложен по своей природе. Я узнаю что-то об этом каждый день, и я занимаюсь этим уже довольно давно. Удачного кодирования!

tao 15.11.2022 19:38

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