How to use component v-model
Challenge
You want to make your component usable with v-model
, but this syntax sugar works differently in Vue 2 and Vue 3.
// Vue 2:
export default {
props: ['value'],
methods: {
emitValue(value) { this.$emit('input', value) }
}
}
//Vue 3
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
methods: {
emitValue(value) { this.$emit('update:modelValue', value) }
}
}
Manual Solution
Write the component Vue 3-style but use Vue 2's model
option to redefine the prop and event.
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
model: {
prop: 'modelValue',
event: 'update:modelValue'
},
methods: {
emitValue(value) { this.$emit('update:modelValue', value)}
}
}
Polyfill via @vue-bridge/runtime
@vue-bridge/runtime
's defineComponent()
wrapper will insert this option for you if you write your component Vue 3 style:
import { defineComponent } from '@vue-bridge/runtime'
export default defineComponent({
props: ['modelValue'],
emits: ['update:modelValue'],
/** this will be inserted ny defineComponent:
model: {
prop: 'modelValue',
event: 'update:modelValue'
},
*/
methods: {
emitValue(value) { this.$emit('update:modelValue', value)}
}
})
Attention
This means that counter to the Vue 2 default, your components will now expect a modelValue
prop and emit an update:modelValue
event even when used in a Vue 2 app.
You should document this for your library's users.
v-bind:arg
vs. v-bind.sync
You can't use v-model:name=""
(Vue 3) or v-bind.sync:name=""
(Vue 2) in your own library's codebase, because you will compile your templates with both compilers, which each only understand one of these APIs.
Instead, you have to fall back to the "normal" long forms of these shortcuts:
<child-component
v-bind:name="name"
@update:name="name = $event"
/>
This does not affect consumers!
The consumers of your library can of course use these APIs (appropriate for the Vue version in in their project) on your components.
This limitation only applies to the usage within your cross-version library's codebase.