Heim > Artikel > Web-Frontend > Vue+ElementUI implementiert dynamisches Rendering und visuelle Konfiguration von Formularen
Dieser Artikel stellt hauptsächlich die Methode von Vue+ElementUI vor, um dynamisches Rendering und visuelle Konfiguration von Formularen zu realisieren. Freunde, die es benötigen, können darauf verweisen
Dynamisches Rendering bedeutet, über asynchrone Daten zu verfügen, die wie folgt aussehen:
{ "inline": true, "labelPosition": "right", "labelWidth": "", "size": "small", "statusIcon": true, "formItemList": [ { "type": "input", "label": "姓名", "disable": false, "readonly": false, "value": "", "placeholder": "请输入姓名", "rules": [], "key": "name", "subtype": "text" }, { "type": "radio", "label": "性别", "value": "", "button": false, "border": true, "rules": [], "key": "gender", "options": [ { "value": "1", "label": "男", "disabled": false }, { "value": "0", "label": "女", "disabled": false } ] } ] }
Dann müssen Sie den JSON wie folgt rendern:
Die endgültigen übermittelten Formulardaten sehen so aus:
{ "name": "Genji", "gender": "1" }
Dann unser Ziel besteht darin, es wie folgt zu kapseln. Eine Komponente:
<dynamic-form :config="someConfig" v-model="someData" />
Implementierung
Bevor Sie beginnen, müssen Sie wissen, wie das V-Modell funktioniert:
<input v-model="something">
Das ist nur syntaktischer Zucker für das folgende Beispiel:
<input :value="something" @input="something = $event.target.value">
Nachdem wir das verstanden haben, implementieren wir diese Komponente Schritt für Schritt.
Erstens die Konfiguration an el-form weiterleiten:
<template> <el-form class="dynamic-form" :inline="formConfig.inline" :model="value" :label-position="formConfig.labelPosition" :label-width="formConfig.labelWidth" :size='formConfig.size' :status-icon="formConfig.statusIcon"> <slot/> </el-form> </template> <script> export default { props: { formConfig: { type: Object, required: true }, value: { type: Object, required: true } }, } </script>
Zweitens den Standardwert festlegen.
Da jedes form-item
ein V-Modell erfordert, hat jedes Feld vor dem Rendern garantiert einen Wert. Hierbei ist zu beachten, dass die von der übergeordneten Komponente übergebenen Requisite nicht direkt in der Komponente geändert werden sollte. Daher verwenden wir {...this.value}
, um sie schnell hierher zu kopieren, und vergessen schließlich nicht, die übergeordnete Komponente zu benachrichtigen. Der Code lautet wie folgt:
export default { props: { formConfig: {...}, value: {...}, }, methods: { setDefaultValue() { const formData = { ...this.value } // 设置默认值 this.formConfig.formItemList.forEach(({ key, value }) => { if (formData[key] === undefined || formData[key] === null) { formData[key] = value } }) this.$emit('input', formData) } }, mounted() { this.setDefaultValue() }, }
Der dritte Schritt besteht darin, das Formularelement zu rendern.
Wie rendert man die folgenden Daten in das bekannte el-form-item?
{ "type": "input", "label": "姓名", "disable": false, "readonly": false, "value": "", "placeholder": "请输入姓名", "rules": [], "key": "name", "subtype": "text" }
Die erste Möglichkeit besteht darin, die integrierte Komponentenkomponente von vue zu verwenden, die wie folgt geschrieben werden kann:
<el-form-item> <component :is="`el-${item.type}`" /> </el-form-item>
Die zweite Möglichkeit besteht darin, v-if zu verwenden, um eine nach der anderen zu beurteilen:
<el-form-item> <el-input v-if="item.type === 'input'" /> <span v-else>未知控件类型</span> </el-form-item>
Bedenken Da die Verarbeitungslogik jedes Formularsteuerelements sehr unterschiedlich ist, hat der Autor die zweite Methode übernommen.
Gemäß dieser Idee kapseln wir ein dynamic-form-item
, empfangen ein Element und rendern ein el-form-item:
<template> <el-form-item :rules="item.Rules" :label="item.label" :prop="item.key"> <el-input v-if="item.type==='input'" v-bind="$attrs" v-on="$listeners" :type="item.subtype" :placeholder="item.placeholder" :disabled="item.disable" :readonly="item.readonly" :autosize="item.autosize"></el-input> <el-select v-else-if="item.type==='select'" v-bind="$attrs" v-on="$listeners" :multiple="item.multiple" :disabled="item.disabled" :multiple-limit="item.multipleLimit"> <el-option v-for="o in item.options" :key="o.value" :label="o.label" :value="o.value" :disabled="o.disabled"> </el-option> </el-select> <!--突然有点想念JSX--> ... <span v-else>未知控件类型</span> </el-form-item> </template> <script> export default { props: { item: { type: Object, required: true } } } </script>
Tipps: Verwenden Sie v-bind="$attrs" v-on="$listeners"
, um die übergeordnete Komponente einfach weiterzuleiten v-model
Befehl, siehe Vue-Komponenten höherer Ordnung für Details.
Schließlich können wir ein vollständiges Formular in einer Schleife ausgeben:
<dynamic-form-item v-for="item in formConfig.formItemList" :key="item.key" v-if="value[item.key]!==undefined" :item="item" :value="value[item.key]" @input="handleInput($event, item.key)" />
v-model="value[item.key]"
kann hier nicht verwendet werden. Wie oben erwähnt, können Requisiten nicht direkt in der Komponente geändert werden, daher leiten wir weiter es hier einmal.
methods: { handleInput(val, key) { // 这里element-ui没有上报event,直接就是value了 this.$emit('input', { ...this.value, [key]: val }) }, setDefaultValue() {...} },
Vollständige Codeadresse: src/components/dynamic-form/form.vue
Erweiterte Funktionen
1. Digitale Anzeigeeinheiten, Einschränkungen Dezimalziffern
element-ui verfügt nicht über diese Funktion, aber ich denke, dass sie recht häufig vorkommt, daher habe ich el-input verwendet, um eine Eingabenummer manuell zu kapseln:
<!--普通使用--> <input-number v-model="someNumber" :min="1" :max="99" :decimal1="2" append="元"></input-number> <!--在dynamic-form-item中的应用--> <input-number v-else-if="item.type==='number'" v-bind="$attrs" v-on="$listeners" :min="item.min" :max="item.max" :decimal1="item.decimal1" :append="item.append" :prepend="item.prepend" :disabled="item.disabled"></input-number>
Vollständiger Code: src/components/dynamic-form/input-number.vue
2. Asynchrone Überprüfung
Dank async-validator können wir Passen Sie Validierungsregeln einfach an.
In der Konfiguration
{ "type": "input", ... "rules":[ { "sql": "SELECT {key} FROM balabala", "message": "xx已被占用", "trigger": "blur" } ] }
In der dynamic-form-item
-Komponente durchlaufen Sie item.rules und konvertieren die SQL-Verifizierung in eine benutzerdefinierte Validierungsfunktion:
<template> <el-form-item :rules="Rules" > ... </el-form-item> </template> <script> import request from '@/utils/request' export default { props: { item: {...} }, computed: { Rules() { const rules = this.item.rules if (rules === undefined) return undefined const R = [] rules.forEach(rule => { if (rule.sql) { const validator = (rule2, value, callback) => { // 根据项目自行修改 request('/api/validate', 'POST', { key: rule2.field, value, sql: rule.sql.replace(/{key}/ig, rule2.field) }) .then(res => { callback(!res || undefined) }) .catch(err => { this.$message.error(err.message) callback(false) }) } R.push({ validator, message: rule.message, trigger: 'blur' }) } else { R.push(rule) } }) return R } }, } </script>
3. Schnelle Konfiguration von Provinzen und Städten
Danke an den Autor von element-china-area-data.
In der Konfiguration:
{ "type": "cascader", ... "areaShortcut": "provinceAndCityData" }
In der Dynamic-Form-Item-Komponente:
<template> <el-form-item> ... <el-cascader :options="item.options || require('element-china-area-data')[item.areaShortcut]" ></el-cascader> </el-form-item> </template>
4. Ladeoptionen von der Fernbedienung
Einschließlich, aber nicht beschränkt auf Radio, Kontrollkästchen, Kaskader, auswählen
In der Konfiguration:
{ "type": "checkbox", ... "optionsUrl": "/api/some/options" }
In der Dynamic-Form-Item-Komponente:
<template> <el-form-item> ... <el-select> <el-option v-for="o in item.options || ajaxOptions" ></el-option> </el-select> </el-form-item> </template> <script> import request from '@/utils/request' export default { props: { item: {...} }, computed: {...}, data() { return { ajaxOptions: [] } }, created() { const { optionsUrl, key, type } = this.item if (optionsUrl) { // 根据项目自行修改 request(`${optionsUrl}?key=${key}`, 'GET') .then(res => { this.ajaxOptions = res }) .catch(err => { this.$message.error(err.message) }) } } } </script>
Das Obige habe ich für alle zusammengestellt, ich hoffe es wird in Zukunft verwendet werden. Hilfreich für alle.
Verwandte Artikel:
Beispiel für die NodeJS-Methode zum Herstellen einer Verbindung mit der Mongodb-Datenbank
Wählen Sie die Selektor-Mehrfachauswahl-Überprüfungsmethode in iview aus
Verwendung von Axios Element zur Implementierung der globalen Methode zum Laden von Anforderungen
Das obige ist der detaillierte Inhalt vonVue+ElementUI implementiert dynamisches Rendering und visuelle Konfiguration von Formularen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!