Heim >Web-Frontend >js-Tutorial >Vue+ElementUI implementiert dynamisches Rendering und visuelle Konfiguration von Formularen

Vue+ElementUI implementiert dynamisches Rendering und visuelle Konfiguration von Formularen

亚连
亚连Original
2018-05-31 17:53:0914402Durchsuche

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

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()
 },
}

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 === &#39;input&#39;" />
 <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===&#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>

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(&#39;input&#39;, { ...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===&#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>

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

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(&#39;element-china-area-data&#39;)[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 &#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>

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!

Stellungnahme:
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