Heim > Web-Frontend > js-Tutorial > Hauptteil

Vue+ElementUI implementiert dynamisches Rendering und visuelle Konfiguration von Formularen

亚连
Freigeben: 2018-05-31 17:53:09
Original
14372 Leute haben es durchsucht

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
 }
 ]
 }
 ]
}
Nach dem Login kopieren

Dann müssen Sie den JSON wie folgt rendern:

Die endgültigen übermittelten Formulardaten sehen so aus:

{
 "name": "Genji",
 "gender": "1"
}
Nach dem Login kopieren

Dann unser Ziel besteht darin, es wie folgt zu kapseln. Eine Komponente:

<dynamic-form :config="someConfig" v-model="someData" />
Nach dem Login kopieren

Implementierung

Bevor Sie beginnen, müssen Sie wissen, wie das V-Modell funktioniert:

<input v-model="something">
Nach dem Login kopieren

Das ist nur syntaktischer Zucker für das folgende Beispiel:

<input
 :value="something"
 @input="something = $event.target.value">
Nach dem Login kopieren

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=&#39;formConfig.size&#39; 
 :status-icon="formConfig.statusIcon">
 <slot/>
 </el-form>
</template>
<script>
export default {
 props: {
 formConfig: {
 type: Object,
 required: true
 },
 value: {
 type: Object,
 required: true
 }
 },
}
</script>
Nach dem Login kopieren

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(&#39;input&#39;, formData)
 }
 },
 mounted() {
 this.setDefaultValue()
 },
}
Nach dem Login kopieren

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"
}
Nach dem Login kopieren

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>
Nach dem Login kopieren

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 === &#39;input&#39;" />
 <span v-else>未知控件类型</span>
</el-form-item>
Nach dem Login kopieren

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===&#39;input&#39;" 
 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===&#39;select&#39;" 
 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>
Nach dem Login kopieren

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)" />
Nach dem Login kopieren

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(&#39;input&#39;, { ...this.value, [key]: val })
 },
 setDefaultValue() {...}
},
Nach dem Login kopieren

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===&#39;number&#39;" 
 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>
Nach dem Login kopieren

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"
  }
 ]
}
Nach dem Login kopieren

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 &#39;@/utils/request&#39;
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(&#39;/api/validate&#39;, &#39;POST&#39;, {
    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: &#39;blur&#39; })
  } else {
   R.push(rule)
  }
  })
  return R
 }
 },
}
</script>
Nach dem Login kopieren

3. Schnelle Konfiguration von Provinzen und Städten

Danke an den Autor von element-china-area-data.

In der Konfiguration:

{
 "type": "cascader",
 ...
 "areaShortcut": "provinceAndCityData"
}
Nach dem Login kopieren

In der Dynamic-Form-Item-Komponente:

<template>
 <el-form-item>
  ...
  <el-cascader 
   :options="item.options || require(&#39;element-china-area-data&#39;)[item.areaShortcut]"
   ></el-cascader>
 </el-form-item>
</template>
Nach dem Login kopieren

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"
}
Nach dem Login kopieren

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 &#39;@/utils/request&#39;
export default {
 props: {
 item: {...}
 },
 computed: {...},
 data() {
 return {
  ajaxOptions: []
 }
 },
 created() {
 const { optionsUrl, key, type } = this.item
 if (optionsUrl) {
  // 根据项目自行修改
  request(`${optionsUrl}?key=${key}`, &#39;GET&#39;)
  .then(res => {
   this.ajaxOptions = res
  })
  .catch(err => { this.$message.error(err.message) })
 }
 }
}
</script>
Nach dem Login kopieren

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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage