Data models with Vue 3
Usage of JavaScript classes for application models.
Introduction
Usage of JavaScript classes to define models has the advantage to be very declarative and has some interesting features such as getters and methods.
However, with the Vue 3 reactivity system, it is generally not recommended to use JavaScript classes to manage a reactive state. Instead, we could use the
ref()
and reactive()
API.
Utility
To make it more declarative, we must define a utility that would wrap data with
reactive()
so all properties are easily accessible.
export function defineModel(define) {
return (data) => reactive(define(data))
}
Definition
Then, define a simple model with its data:
export const Post = defineModel((data) => {
const title = data.title
return { title }
})
and use in component:
<script setup>
const post = Post({ title: 'How to make cookies' })
post.title = 'How to bake cookies' // { title: 'How to bake cookies' }
</script>
Getters
Now, let's say our post needs a slug, depending on the title
property.
To do that, we can use the computed()
function:
export const Post = defineModel((data) => {
const title = data.title
const slug = computed(() => slugify(title.value))
return { title, slug }
})
Usage:
const post = ref(null)
const { data } = await fetchPost()
post.value = Post(data)
// { title: 'How to make cookies', slug: 'how-to-make-cookies' }
post.value.title = 'How to bake cookies'
// { title: 'How to bake cookies', slug: 'how-to-bake-cookies' }