Skip to content

Instantly share code, notes, and snippets.

@34fame
Last active July 19, 2021 00:18
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 34fame/d9f96cf43ff5008d4d9a5911d1faf18c to your computer and use it in GitHub Desktop.
Save 34fame/d9f96cf43ff5008d4d9a5911d1faf18c to your computer and use it in GitHub Desktop.
Dynamically Render Form Fields
<script>
export default {
name: 'MyFormField',
props: {
field: {
type: Object,
required: true,
},
input: {
type: Function,
required: true,
},
model: {
type: Object,
required: true,
}
},
methods: {
renderLabel(h) {
return h('div', {
class: ['text-caption'],
},[
this.field.label
])
},
renderField(h) {
return h(this.field.component, {
class: [
...this.field.fieldOptions.class,
],
attrs: {
...this.field.fieldOptions.attrs,
},
props: {
...this.field.fieldOptions.props,
value: this.model[this.field.model]
},
style: {
...this.field.fieldOptions.style,
},
on: {
input: (value) => {
this.input(value, this.field.model)
}
}
})
},
},
render(h) {
return h('div', {
class: ['column', 'q-gutter-xs'],
}, [
this.renderLabel(h),
this.renderField(h),
])
},
}
</script>
<template>
<q-form class="q-gutter-md">
<my-form-field
v-for="field in fields"
:key="field.model"
:field="field"
:input="(value,field) => handleInput(value,field)"
:model="model"
/>
</q-form>
</template>
<script>
export default {
name: 'MyForm',
data() {
return {
model: {},
fields: [
{
component: 'q-input',
label: 'Name',
model: 'name',
fieldOptions: {
class: [],
on: ['input'],
attrs: {
placeholder: 'Enter your full name',
},
props: {
filled: true,
},
style: {
width: '320px',
},
},
},
{
component: 'q-select',
label: 'Gender',
model: 'gender',
fieldOptions: {
class: [],
on: ['input'],
attrs: {},
props: {
filled: true,
options: [ 'Female', 'Male' ]
},
style: {
width: '200px',
},
},
},
],
}
},
methods: {
handleInput(value, field) {
this.$set(this.model, field, value)
}
},
components: {
MyFormField: () => import('components/MyFormField.vue'),
},
}
</script>
<style scoped>
</style>
@34fame
Copy link
Author

34fame commented Jul 19, 2021

Additional details for Quasar:
In this gist, you can see in the "MyForm.vue" that I refer to components 'q-input' and 'q-select'.

When using the Vue render method we have to manually include these Quasar components in the quasar.conf.js file under "framework -> components". By using render() we are bypassing the setup automatically created with the quasar create command.

So you would need something like this:

framework: {
  components: [
    'QInput',
    'QSelect'
  ],
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment