What Causes This Error?
This error occurs when useModel() is called outside of a component’s setup() function or after the synchronous setup phase has completed. Like other Composition API functions, useModel() requires an active component instance.
The Problem
import { useModel } from 'vue'
// ❌ Called outside setup
const model = useModel() // Error!
export default {
setup() {
// ...
}
}
export default {
async setup() {
await fetchData()
// ❌ Called after await
const model = useModel() // Error!
}
}
The Fix
Use defineModel (Recommended)
<script setup>
// ✅ defineModel works in script setup
const model = defineModel()
const count = defineModel('count')
</script>
<template>
<input v-model="model" />
</template>
Call Before Await
export default {
async setup(props) {
// ✅ Create model before await
const modelValue = useModel(props, 'modelValue')
await fetchData()
return { modelValue }
}
}
Common Scenarios
In Composables
// ❌ Composable might be called outside setup
export function useFormModel() {
const model = useModel() // Might fail!
return model
}
// ✅ Accept model from outside
export function useFormModel(modelRef) {
// Work with provided model
return {
reset: () => modelRef.value = ''
}
}
// Usage in component
<script setup>
const model = defineModel()
const { reset } = useFormModel(model)
</script>
With Async Operations
<script setup>
// ✅ Define model first (synchronous)
const value = defineModel()
// Then do async operations
onMounted(async () => {
const data = await fetchData()
value.value = data.defaultValue
})
</script>
Migration from useModel to defineModel
<!-- Old approach -->
<script>
import { useModel } from 'vue'
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
setup(props) {
const model = useModel(props, 'modelValue')
return { model }
}
}
</script>
<!-- New approach (Vue 3.4+) -->
<script setup>
const model = defineModel()
</script>
defineModel Examples
<script setup>
// Basic v-model
const value = defineModel()
// Named v-model
const title = defineModel('title')
// With options
const count = defineModel('count', {
type: Number,
default: 0,
required: true
})
// TypeScript
const name = defineModel<string>('name', {
default: ''
})
</script>
Quick Checklist
- Use
defineModel()in<script setup>(preferred) - Call
useModel()synchronously in setup - Call before any
awaitstatements - Don’t call in callbacks, timeouts, or event handlers
- Composables should accept model refs as parameters