Inputs and Vue3. Troubles with v-model, event.target.value

,

Help me please! How to work with inputs in Vue3, with reactivity?
v-model - not work, event.target.value - undefined

I’m try to refactor my CEP panel with new technology, but I encounter UXP flaws again and again. How do you guys work with this? :slightly_smiling_face: Or am I missing something?

Wrap UXP/Spectrum elements in Vue components using modelValue.

// main.vue
<script setup>
import { ref } from "vue"
import Input from "Input.vue"

const string = ref("nice")
</script>

<template>
  <div>
    <p>string is: {{ string }}</p>
    <Input v-model="string" />
  </div>
</template>
// Input.vue
<script setup>
const props = defineProps({
  modelValue: String
})

const emit = defineEmits(["update:modelValue"])
</script>

<template>
  <sp-textfield :value="props.modelValue" @input="emit('update:modelValue', $event.target.value)"></sp-textfield>
</template>

I can’t speak for the new defineModel method in Vue 3.4 as I’ve not experimented with that yet.

If using Vue then I’d recommend using Bolt UXP as a foundation. I’ve found that when watching for changes, over time UDT takes progressively longer to reload Vue and it’s a real development bottleneck. Bolt solves this with some kind of websocket magic that I’m not going to pretend to understand :smiley:

2 Likes

Thanks for the answer! I’ll have to do this. We call this, if translated into English, “crutches”, the meaning is obvious. :grinning:

It’s a pretty standard Vue pattern, I use it all the time.

Let me get back to the question. Wrapping sp-textarea or just input does not give any result, because event.target does not have the .value property. Look in the devtools yourself. Maybe it’s just for me?

In the console I see how I can get to the value through a strange object event.target._properties is a Map object that can be expanded (…$event.target._properties.values()) but it looks ugly.

How do Your components look like, because I have no trouble accessing the value like this:

<!-- Main.vue -->
<script setup>
import { ref } from "vue";
import MyInput from '@/path/to/your/components/MyInput.vue'
const name = ref('Default Name')
</script>

<template>
  <div>
    <MyInput 
      v-model="name"
      placeholder="Type something"
      @update:modelValue="(value) => console.log('Parent:\n', value)"
    />
    <br>
    This is the name: {{ name }}
  </div>
</template>

<!-- MyInput.vue -->
<script setup>
  import { defineProps } from "vue";
  const props = defineProps({
    placeholder: { type: String },
    modelValue: { type: String }
  })
</script>
<template>
<div>
  <sp-textfield
    @input="$emit('update:modelValue', $event.target.value) /* `$emit` should be globally available */"
    :value="modelValue"
    :placeholder="placeholder"
  />
  <br><!-- or -->
  <sp-textfield
    @input="callback($event.target.value) /* pass value to some callback and emit from there (`defineEmits` required)*/"
    :value="modelValue"
    :placeholder="placeholder"
  />
  <br>
  {{ modelValue }}
</div>
</template>

Thank you for reply. Copied your template. No reactivity. Console outputs undefined.
And what version of Vue do you have? Is it with webpack? Maybe something with the settings. And/Or manifest.json. I use the official example for Vue 3 from Adobe’s GitHub.
PS 26.2.0 (macos)

"vue": "^3.2.22",
"vue-loader": "^16.8.3",
"@vue/compiler-sfc": "^3.2.22",

Can you send me your project by email?

Unfortunately I can’t, because my project has grown quite large and I don’t have the time to isolate the required files. But I also am using the great Bolt UXP boilerplate (as already suggested by @Timothy_Bennett ) as a starting point (I prefer vite over webpack). Did You give it a try? It’ll make Your life much easier in terms of Your project setup.
You can still throw out stuff that You don’t need.
Let me know, if this works.

1 Like

Yes, everything works great on Bolt UXP! I had avoided this boilerplate because it seemed overloaded with TypeScript to me. Thank you for the help.
It’s a shame that the official example from Adobe doesn’t work properly. Oh well.

1 Like

Glad You got it working! :upside_down_face:
Yes, it’s a bit much at first sight.
I neither use Typescript – couldn’t wrap my head around it yet, though I know, it would make my app less error prone and has some other advantages…
The examples from Adobe on github are still very useful references, but yeah, You have to adapt them to Your needs.