Maison > interface Web > js tutoriel > le corps du texte

Méthode Vue+ElementUI pour réaliser un rendu dynamique et une configuration visuelle des formulaires

亚连
Libérer: 2018-05-31 17:53:09
original
14337 Les gens l'ont consulté

Cet article présente principalement la méthode de Vue+ElementUI pour réaliser le rendu dynamique et la configuration visuelle des formulaires. Les amis qui en ont besoin peuvent s'y référer

Le rendu dynamique signifie avoir des données asynchrones, qui ressemblent à ceci :

{
 "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
 }
 ]
 }
 ]
}
Copier après la connexion

Ensuite, vous devez restituer le json comme ceci :

Les données finales du formulaire soumis ressemblent à ceci :

{
 "name": "Genji",
 "gender": "1"
}
Copier après la connexion

Ensuite, nous Le but est d'encapsuler un tel composant :

<dynamic-form :config="someConfig" v-model="someData" />
Copier après la connexion

Mise en œuvre

Avant de commencer, vous devez savoir comment v -model fonctionne :

<input v-model="something">
Copier après la connexion

Ceci n'est que du sucre syntaxique pour l'exemple suivant :

<input
 :value="something"
 @input="something = $event.target.value">
Copier après la connexion

Après avoir compris cela, implémentons ce composant étape par étape.

Tout d'abord, transférez la configuration à el-form :

<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>
Copier après la connexion

Deuxièmement, définissez la valeur par défaut.

Parce que chaque form-item nécessite un v-model, chaque champ est garanti d'avoir une valeur avant le rendu. Une chose à noter ici est que le composant ne doit pas modifier directement le prop transmis par le composant parent, nous utilisons donc {...this.value} pour le copier rapidement ici, et enfin n'oublions pas d'en informer le composant parent. Le code est le suivant :

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()
 },
}
Copier après la connexion

La troisième étape consiste à restituer l'élément de formulaire.

Comment restituer les données suivantes dans l'élément el-form-item familier ?

{
 "type": "input",
 "label": "姓名",
 "disable": false,
 "readonly": false,
 "value": "",
 "placeholder": "请输入姓名",
 "rules": [],
 "key": "name",
 "subtype": "text"
}
Copier après la connexion

La première façon est d'utiliser le composant intégré de vue, qui peut s'écrire comme ceci :

<el-form-item>
 <component :is="`el-${item.type}`" />
</el-form-item>
Copier après la connexion

La deuxième façon est d'utiliser v-if pour en juger un par un :

<el-form-item>
 <el-input v-if="item.type === &#39;input&#39;" />
 <span v-else>未知控件类型</span>
</el-form-item>
Copier après la connexion

Considérant que la logique de traitement de chaque contrôle de formulaire est très différente, l'auteur a adopté la deuxième méthode.

Selon cette idée, nous encapsulons un dynamic-form-item , recevons un élément et restituons un élément de formulaire el :

<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>
Copier après la connexion

conseils : utilisez v-bind="$attrs" v-on="$listeners" pour transférer facilement le parent Pour la directive v-model du composant, voir Composants d'ordre supérieur Vue pour plus de détails.

Enfin, nous pouvons boucler pour générer un formulaire complet :

<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)" />
Copier après la connexion

v-model="value[item.key]" ne peut pas être utilisé ici. Comme mentionné ci-dessus, les accessoires ne peuvent pas être modifiés directement dans le composant, donc ici nous. Ou transmettez-le.

methods: {
 handleInput(val, key) {
 // 这里element-ui没有上报event,直接就是value了
 this.$emit(&#39;input&#39;, { ...this.value, [key]: val })
 },
 setDefaultValue() {...}
},
Copier après la connexion

Adresse complète du code : src/components/dynamic-form/form.vue

Fonctions étendues

1. , limitez le nombre de décimales

element-ui n'a pas cette fonction, mais je pense que c'est assez courant, j'ai donc utilisé el-input pour encapsuler manuellement un numéro d'entrée :

<!--普通使用-->
<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>
Copier après la connexion

Code complet : src/components/dynamic-form/input-number.vue

Vérification asynchrone

Merci. avec async-validator, nous pouvons facilement personnaliser les règles de validation.

Dans la configuration

{
 "type": "input",
 ...
 "rules":[
  {
   "sql": "SELECT {key} FROM balabala",
   "message": "xx已被占用",
   "trigger": "blur"
  }
 ]
}
Copier après la connexion

Dans le composant dynamic-form-item , parcourez item.rules et convertissez la vérification SQL en une fonction de validation personnalisée :

<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>
Copier après la connexion

3. Configuration rapide des provinces et des villes

Merci à l'auteur de element-china-area-data.

En configuration :

{
 "type": "cascader",
 ...
 "areaShortcut": "provinceAndCityData"
}
Copier après la connexion

Dans le composant Dynamic-form-item :

<template>
 <el-form-item>
  ...
  <el-cascader 
   :options="item.options || require(&#39;element-china-area-data&#39;)[item.areaShortcut]"
   ></el-cascader>
 </el-form-item>
</template>
Copier après la connexion

4. Options de chargement à distance

Inclus mais non. limité à la radio, case à cocher, cascader, sélectionnez

Dans la configuration :

{
 "type": "checkbox",
 ...
 "optionsUrl": "/api/some/options"
}
Copier après la connexion

Dans le composant Dynamic-form-item :

<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>
Copier après la connexion

Ce qui précède, c'est moi que j'ai compilé pour tout le monde, j'espère que cela sera utile à tout le monde à l'avenir.

Articles connexes :

Exemple de méthode nodejs pour se connecter à la base de données mongodb

Sélectionner la méthode de vérification multi-sélection du sélecteur dans iview

Utilisation d'Axios Element pour implémenter la méthode de chargement de requête globale

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!