# Components
TIP
In case you need to achieve more reactivity, then take a look at Integration of vue-async-computed.
# DisplayField
The DisplayField component can be used to display the value of the given field. The property model can either be a
model instance or null to allow async loading of the model instance. The component will not render when null has
been passed as model. To change the output for specific fields see Fields rendering.
<template>
[...]
<display-field :model="album" field-name="title"/>
<!-- or directly with field -->
<display-field :field="album.getField('title')"/>
[...]
</template>
<script>
import {DisplayField} from 'vue-service-model'
export default {
components: {DisplayField},
data () {
return {
album: null
}
},
created () {
this.loadAlbum()
},
methods: {
async loadAlbum () {
this.album = await Album.objects.detail(1)
}
}
}
</script>
WARNING
When using direct field property, keep in mind that the model will be null during loading
# Loading state
To display the loading state of the component, when the data is being fetched, you can use the loading slot.
<template>
[...]
<display-field :model="album" field-name="title">
<template v-slot:loading>
<span>Loading title...</span>
</template>
</display-field>
[...]
</template>
# Passing additional properties to prepareDisplayRender
You can optionally pass additional properties to prepareDisplayRender with the property render-props. This allows more control on how your custom field should be rendered.
<template>
[...]
<display-field :field="noteField" :render-props="{ note: 'Warning' }"/>
<display-field :field="noteField" :render-props="{ note: 'Error' }"/>
[...]
</template>
<script>
[...]
class NoteField extends CharField {
async prepareDisplayRender (renderProps) {
const note = renderProps?.note || 'Info'
const value = await this.value
return value && `${note}: ${value}`
}
}
[...]
</script>
# InputField
The InputField component is equal to the DisplayField. The input value will directly change the data of your model (using the valueSetter).
<template>
[...]
<input-field :model="album" field-name="title"/>
<!-- or directly with field -->
<input-field :field="album.getField('title')"/>
[...]
</template>
<script>
import {InputField} from 'vue-service-model'
export default {
components: {InputField},
data () {
return {
album: null
}
},
created () {
this.loadAlbum()
},
methods: {
async loadAlbum () {
this.album = await Album.objects.detail(1)
}
}
}
</script>
WARNING
When using direct field property, keep in mind that the model will be null during loading
# Loading state
To display the loading state of the component, when the data is being fetched, you can use the loading slot.
<template>
[...]
<input-field :model="album" field-name="title">
<template v-slot:loading>
<span>Loading title...</span>
</template>
</input-field>
[...]
</template>
# Common input properties
There are two common input properties disabled and readonly. These should always be implemented when creating new field types.
<template>
[...]
<!-- disabled input -->
<input-field :model="album" field-name="title" disabled/>
<!-- readonly input -->
<input-field :model="album" field-name="title" readonly/>
[...]
</template>
# Passing additional properties to prepareInputRender
You can optionally pass additional properties to prepareInputRender with the property render-props. It works the same as for DisplayField.
<template>
[...]
<input-field :field="myField" :render-props="{ anyOption: 7 }"/>
[...]
</template>
# FieldLabel
In case you just want to render the label of the field you can use the FieldLabel component which will resolve the async field label.
You can use your model instance or the static model class
<template>
[...]
<!-- with model static class -->
<field-label :model="Album" field-name="title"/>
<!-- or directly with field -->
<field-label :field="Album.getField('title')"/>
<!-- with model instance -->
<field-label :model="album" field-name="title"/>
<!-- or directly with field -->
<field-label :field="album.getField('title')"/>
[...]
</template>