最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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)文章

  • nuxt框架中對(duì)vuex進(jìn)行模塊化設(shè)置的實(shí)現(xiàn)方法

    nuxt框架中對(duì)vuex進(jìn)行模塊化設(shè)置的實(shí)現(xiàn)方法

    這篇文章主要介紹了nuxt框架中對(duì)vuex進(jìn)行模塊化設(shè)置的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • vue項(xiàng)目中使用bpmn-自定義platter的示例代碼

    vue項(xiàng)目中使用bpmn-自定義platter的示例代碼

    這篇文章主要介紹了vue項(xiàng)目中使用bpmn-自定義platter的實(shí)例代碼,本文通過代碼截圖相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Vue響應(yīng)式原理模擬實(shí)現(xiàn)原理探究

    Vue響應(yīng)式原理模擬實(shí)現(xiàn)原理探究

    這篇文章主要介紹了Vue響應(yīng)式原理,響應(yīng)式就是當(dāng)對(duì)象本身(對(duì)象的增刪值)或者對(duì)象屬性(重新賦值)發(fā)生了改變的時(shí)候,就會(huì)運(yùn)行一些函數(shù),最常見的示render函數(shù)
    2022-09-09
  • 關(guān)于vue單文件中引用路徑的處理方法

    關(guān)于vue單文件中引用路徑的處理方法

    這篇文章主要給大家介紹了關(guān)于vue單文件中引用路徑處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • Vue+Vux項(xiàng)目實(shí)踐完整代碼

    Vue+Vux項(xiàng)目實(shí)踐完整代碼

    本文給大家分享一段詳細(xì)的代碼給大家介紹Vue+Vux項(xiàng)目實(shí)踐思路,需要的朋友可以參考下
    2017-11-11
  • 基于uniapp+vue3自定義增強(qiáng)版table表格組件「兼容H5+小程序+App端」

    基于uniapp+vue3自定義增強(qiáng)版table表格組件「兼容H5+小程序+App端」

    uv3-table:一款基于uniapp+vue3跨端自定義手機(jī)端增強(qiáng)版表格組件,支持固定表頭/列、邊框、斑馬紋、單選/多選,自定義表頭/表體插槽、左右固定列陰影高亮顯示,支持編譯兼容H5+小程序端+App端,H5+小程序+App端,多端運(yùn)行一致
    2024-05-05
  • Vue.js中前端如何處理從后端返回的Excel文件流詳解

    Vue.js中前端如何處理從后端返回的Excel文件流詳解

    這篇文章主要介紹了如何在Vue項(xiàng)目中使用axios處理后端返回的Excel文件流,并提供下載功能,文中通過代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2025-01-01
  • vue2+elementui的el-table固定列會(huì)遮住橫向滾動(dòng)條及錯(cuò)位問題解決方案

    vue2+elementui的el-table固定列會(huì)遮住橫向滾動(dòng)條及錯(cuò)位問題解決方案

    這篇文章主要介紹了vue2+elementui的el-table固定列會(huì)遮住橫向滾動(dòng)條及錯(cuò)位問題解決方案,主要解決固定列錯(cuò)位后, 接下來就是把固定列往上提滾動(dòng)條的高度就不會(huì)影響了,需要的朋友可以參考下
    2024-01-01
  • Vite+TS+Vue開啟eslint和prettier規(guī)范及校驗(yàn)方式

    Vite+TS+Vue開啟eslint和prettier規(guī)范及校驗(yàn)方式

    這篇文章主要介紹了Vite+TS+Vue開啟eslint和prettier規(guī)范及校驗(yàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue項(xiàng)目中使用iconfont方式

    vue項(xiàng)目中使用iconfont方式

    這篇文章主要介紹了vue項(xiàng)目中使用iconfont方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評(píng)論

延庆县| 交城县| 太湖县| 同江市| 岑溪市| 江城| 抚顺县| 陵川县| 岳西县| 工布江达县| 桑植县| 温州市| 泾阳县| 凤冈县| 同江市| 禹州市| 冕宁县| 会泽县| 涟水县| 米易县| 安国市| 连江县| 紫金县| 册亨县| 兴安盟| 视频| 义乌市| 兰考县| 怀远县| 梁山县| 建湖县| 友谊县| 鄂温| 翼城县| 雷山县| 信宜市| 达拉特旗| 呼玛县| 蕉岭县| 巨鹿县| 清丰县|