Full Error:
[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 | [
Here is the 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>
HERE is a Full recreation of the error:
Any help here is appreciated <3
This problem is rather confounding.
CodePudding user response:
You can't use dual-binding (v-model
) with optional chaining (np?.description
). Dual binding means getter & setter. What do you expect the setter to set when np
is falsey? I know you wrapped it in v-if
but optional chaining tells v-model
the target object structure is possibly undefined
, and that's an invalid assignment target.
One way to go about it is create a description
computed, where you specify how to set np.description
when the current value of np
allows it:
const description = computed({
get() {
return np.value?.description || ''
},
set(description) {
if (typeof np.value?.description === 'string') {
np.value = { ...np.value, description }
}
},
})
See it working here: https://stackblitz.com/edit/vue3-vite-typescript-starter-wrvbqw?file=src/App.vue
The above is a pretty generic solution (when you actually do need to use optional chaining with v-model
).
A simpler alternative, in your case (possible because you wrapped the <textarea>
in v-if="np"
), is not using optional chaining with v-model
at all:
replace v-model.trim="np?.description"
with v-model.trim="np.description"
.
It will work.