# 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>