欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue構(gòu)建動(dòng)態(tài)表單的方法示例

 更新時(shí)間:2018年09月22日 10:30:30   作者:supportlss  
這篇文章主要介紹了vue構(gòu)建動(dòng)態(tài)表單的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

概述

后臺(tái)管理系統(tǒng)里面有非常多的表單需求,我們希望能夠通過寫一個(gè)json格式的數(shù)據(jù),通過vue的循環(huán)動(dòng)態(tài)地去渲染動(dòng)態(tài)表單。并且能夠在外部得到渲染出來的表單的數(shù)據(jù),可以對(duì)表單進(jìn)行重置操作。我結(jié)合element ui的控件的下拉框,輸入框,時(shí)間選擇控件和vue-treeselect,做了一個(gè)動(dòng)態(tài)表單。

v-model的理解

先簡(jiǎn)單講一下vue-model是怎么玩的。其實(shí)vue-model相當(dāng)于給表單元素傳遞一個(gè)value,外部監(jiān)聽input事件。所以我們自己封裝表單組件的時(shí)候也是可以傳遞一個(gè)value值,監(jiān)聽input事件獲取輸入的值。

<input type="text" v-model="something">
<!--等價(jià)于-->
<input type="text"
    v-bind:value="something"
    v-on:input="something = $event.target.value">

封裝表單組件

組件最重要的開發(fā)思想就是設(shè)計(jì)好輸入輸出。這里就以下拉框組件為例吧。使用的是element ui的下拉框,進(jìn)行一個(gè)簡(jiǎn)單封裝。
輸入:name:每個(gè)表單的數(shù)據(jù)標(biāo)識(shí),如區(qū)域編碼輸入框,父元素應(yīng)該傳遞areaCode過來。

value: 表單選擇/輸入的值,從父元素獲取后賦值給currentValue,通過監(jiān)聽父元素的值實(shí)現(xiàn)同步變
化。

options:下拉框要渲染的選項(xiàng)值,一般是個(gè)對(duì)象數(shù)組。

輸出:onInputEvent,emit一個(gè)input事件,讓父元素能夠感知組件的數(shù)據(jù)變化。

也就是可以在組件使用的地方監(jiān)聽input事件

<template>
 <el-form-item :label="label">
  <el-select v-model="currentValue" @input="onInputEvent">
   <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value">
   </el-option>
  </el-select>
 </el-form-item>
</template>

<script>
 import formMixins from '../../../mixins/form-model'
 export default {
  name: "SelectList",
  props: ['name', 'label', 'value','options'],
  mixins: [formMixins],
  data() {
   return {
    currentValue: this.value
   }
  },
  methods: {
   onInputEvent(value) {
    this.$emit('input', this.name, value);
   }
  },
  watch: {
   value(val) {
    this.currentValue= val;
   }
  }
 }
</script>

一點(diǎn)封裝

由于每個(gè)表單組件都是監(jiān)聽父元素的value值變化,數(shù)據(jù)變化時(shí)都是觸發(fā)onInputEvent并執(zhí)行this.$emit('input'),所以我們可以把這部分內(nèi)容抽取出來放在mixins里面。

form-model.js

export default {
 props: ['name', 'value'],

 data () {
  return {
   currentValue: this.value
  };
 },
 methods: {
  onInputEvent(value) {
   this.$emit('input', this.name, value);
  },
  reset() {
   this.currentValue = "";
  }
 },
 watch: {
  value (val) {
   this.currentValue = val;
  }
 }
};

然后我們的下拉框組件就可以少寫一些共用的代碼,直接用 mixins: [formMixins]

<template>
 <el-form-item :label="label">
  <el-select v-model="currentValue" @input="onInputEvent">
   <el-option
    v-for="item in options"
    :key="item.value"
    :label="item.label"
    :value="item.value">
   </el-option>
  </el-select>
 </el-form-item>
</template>

<script>
 import formMixins from '../../../mixins/form-model'
 export default {
  name: "SelectList",
  props: ['name', 'label', 'value', 'options'],
  mixins: [formMixins],
  data() {
   return {
    currentValue: this.value
   }
  }
 }
</script>

動(dòng)態(tài)生成表單

這里主要是根據(jù)配置的數(shù)據(jù),循環(huán)生成表單組件。默認(rèn)提供提交和重置按鈕,如果不需要可以通過slot傳遞其他操作按鈕。這里的要點(diǎn)主要有:

監(jiān)聽表單組件的數(shù)據(jù)變化:

每個(gè)表單組件都有一個(gè)name標(biāo)識(shí)它的業(yè)務(wù)含義,綁定的數(shù)據(jù)也是formData[field.name],@input事件傳遞updateForm,在updateForm里面更新this.formData[name],保證了this.formData里面的數(shù)據(jù)是和表單組件選擇/填寫的內(nèi)容一致。

重置時(shí)改變表單組件的數(shù)據(jù):

因?yàn)榻M件內(nèi)部會(huì)監(jiān)聽父元素的value,所以這里只要清空this.formData的值,組件內(nèi)部的數(shù)據(jù)也會(huì)跟著清空。

 <template>
 <div>
  <el-form :inline="true" ref="form" :model="formData" class="demo-form-inline">
   <el-col :span="field.cols" v-for="(field, index) in config.fieldsConfig" v-bind:key="index">
    <component :key="index"
          :is="field.fieldType"
          :label="field.label"
          :value="formData[field.name]"
          :multiple="field.multiple"
          @input="updateForm"
          v-bind="field"
          :options="field.options"
          :ref="field.name"
    >
    </component>
   </el-col>
   <slot name="buttons">
    <el-button type="primary" @click="submit" size="small">{{onSubmitText}}</el-button>
    <el-button type="default" @click="reset" size="small">{{onResetText}}</el-button>
   </slot>
  </el-form>
 </div>
</template>
<script>
 import SelectList from './basicComponent/SelectList'
 import TextInput from './basicComponent/TextInput'
 import TimeSelector from './basicComponent/TimeSelector'
 import SelectTree from './basicComponent/SelectTree'
 import StaffSelectPopedit from './businessComponent/StaffSelectPopedit'
 export default {
  name: "FormGenerator",
  components: { SelectList, TextInput, TimeSelector, SelectTree, StaffSelectPopedit},
  props: ["config", "value"],
  data() {
   return {
    formData: this.value,
    onSubmitText: this.config.buttons.onSubmitText || '提交',
    onResetText: this.config.buttons.onResetText || '重置'
   }
  },
  methods: {
   updateForm(fieldName, value) {
    this.formData[fieldName] = value;
   },
   submit() {
    this.$emit("submit");
   },
   reset() {
    for(var name in this.formData) {
     if(typeof this.formData === "String") {
      this.formData[name] = "";
     } else {
      this.formData[name] = null;
     }
    }
   }
  }
 }
</script>

業(yè)務(wù)使用的地方

像下拉框的選擇數(shù)據(jù),這些應(yīng)該是后臺(tái)渲染的,所以我們暫時(shí)用setTimeout模擬一下。感覺這里this.config.fieldsConfig[4].options寫的不太優(yōu)雅,依賴于配置數(shù)據(jù)的順序肯定不是啥好事情。求大神指點(diǎn)。

<template>
 <div>
  <form-generator :config="config"
           @submit="getFormData"
           v-model="formData"
  >
  </form-generator>
 </div>
</template>
<script>
 import FormGenerator from '../components/form/FormGenerator'
 export default {
  name: "FormGeneratorDemo",
  components: { FormGenerator },
  created () {
   this.queryOrderType();
   this.queryAreaTree();
  },
  data() {
   return {
    formData: {
     orderCode: "",
     orderType: "",
     beginTime: "",
     endTime: "",
     area: [],
     staff:""
    },
    config: {
     fieldsConfig: [
      {
       name: 'orderCode',
       label: '定單編碼',
       fieldType: 'TextInput',
       cols: 8
      },
      {
       name: 'orderType',
       label: '定單類型',
       fieldType: 'SelectList',
       options: [],
       cols: 8
      },
      {
       name: 'beginTime',
       label: '開始時(shí)間',
       fieldType: 'TimeSelector',
       cols: 8
      },
      {
       name: 'endTime',
       label: '結(jié)束時(shí)間',
       fieldType: 'TimeSelector',
       cols: 8
      },
      {
       name: 'area',
       label: '區(qū)域',
       fieldType: 'selectTree',
       options: [],
       multiple: true,
       cols: 8
      },
      {
       name: 'staff',
       label: '人員選擇',
       fieldType: 'StaffSelectPopedit',
       cols: 8
      }
     ],
     buttons: {
      onSubmitText: '提交',
      onResetText: '重置'
     }
    }
   }
  },
  methods: {
   getFormData() {
    console.log(this.formData);
   },
   queryOrderType() {
    setTimeout(() => {
     this.config.fieldsConfig[1].options = [
      { label: 'select1', value: 'key1'},
      { label: 'select2', value: 'key2'},
      { label: 'select3', value: 'key3'}
     ];
     }, 100)
   },
   queryAreaTree() {
    this.config.fieldsConfig[4].options = [
     {
      id: 'a',
      label: 'a',
      children: [{
       id: 'aa',
       label: 'AA',
      }, {
       id: 'ab',
       label: 'AB',
      }],
     }, {
      id: 'b',
      label: 'B',
     }, {
      id: 'c',
      label: 'C',
     }
    ]
   }
  }
 }
</script>

大概就是這樣的思路,我們希望我們只要寫上面那樣子的配置數(shù)據(jù)就可以動(dòng)態(tài)生成各種這樣的表單組件,不用寫一大堆重復(fù)代碼。如果有更好的解決辦法,歡迎和我聯(lián)系。另外,代碼路徑https://github.com/supportlss/vue-dynamic-form

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論