從後端到前端之Vue(六)表單組件

表單組件

做項目的時候會遇到一個比較頭疼的問題,一個大表單裡面有好多控制項,一個一個做設置太麻煩,更頭疼的是,需求還總在變化,一會多選、一會單選、一會下拉的,變來變去的煩死寶寶了。
那麼怎麼解決這個問題呢?我們可以做一個組件來搞定這些煩人的事情。我們使用Vue.js基於原生HTML來做一套表單控制項!
前端不管是哪種框架、類庫,其基礎都是HTML、CSS和JavaScript,不管用什麼方式寫項目,我們都有必要先了解一下基礎知識。所以呢我們先來看看HTML5的表單和表單元素都有哪些屬性以及功能。

HTML5原生的表單和表單元素

  要想做好表單組件,必須先知道HTML5裡面的表單和表單元素都有哪些屬性,以及屬性的效果和作用,否則的話可能折騰半天才發現,原來HTML5已經自帶了這個功能!
  比如要實現這樣一個功能:文本框只能輸入數字,然後要加上兩個按鈕,按一個數值+1,按另一個數值-1。以前要寫js程式碼實現,現在只需要把type改成number就可以了。而且可以對輸入的文字做攔截,非數字根本輸入不進去,這樣就不用我們自己再去寫程式碼實現了。所以磨刀不誤砍柴工,我們先來整理一下,表單和表單屬性都有哪些屬性。

表單屬性

表單屬性的圖片

  首先是表單(<form>)的屬性,<form>的屬性主要是對錶單元素做一個統一設定,比如表單里的元素是否需要自動完成的功能,以及提交的時候是否需要做驗證等。如果某個表單元素不符合這個統一設定的話,可以給表單元素單獨設置屬性進行說明。這樣就更靈活和方便了。
  其他的就是通過submit按鈕對錶單進行一些控制的屬性了。不過這些都是針對錶單提交的,我們現在基本都是ajax,所以這些屬性基本都用不上了。

表單元素的分類

  表單元素都有哪些?說到分類就有點頭疼,<intut>一開始理解是文本類的,輸入嘛,結果現實卻很豐滿,提交按鈕也用這個,還有單選和多選也是這個input。多行文本反倒不是這個了,而是單獨的一個。不過不管那麼多了,還是從使用的角度來分類:文本框類和選擇類。
  <intut>的type增加了一些新的類型,在PC機的瀏覽器裡面看,區分不是很大,但是到了手機瀏覽器裡面,區分就比較大了,主要是可以控制打開的輸入法的默認模式。比如number,打開輸入法之後,直接就是數字方式,這個就很人性化,方便用戶操作。
  我們先看一下分類:
表單元素的分類

HTML5新增特性

  新增的特性(好吧也不算新了,都好多年了),主要是對文本框的增強,增加了一些類型以及輔助功能,比如增加了一個備選框(<datalist>)的功能,這個還是比較實用的吧。
HTML5新增特性

在手機網頁里的展現效果

  表單元素在PC瀏覽器里是什麼樣子的,大家很容易看到,那麼在手機瀏覽器里是什麼樣子的呢?先看一下表單整體效果:
整體效果

  注意看那幾個帶下三角的,那個不是下拉列表框,而是日期相關的,可以選擇日期時間等。具體效果我們一個一個看。

  1. 單行文本type=”text”
      還是老樣子的文本框,也是使用最多的表單元素。還是原來的樣子,不貼圖了。

  2. 多行文本<textarea > </textarea>
      一般會被富文本編輯器代替。還是不貼圖了。

  3. 密碼 type=”password”
      這個就不一樣了,系統不同表現也不同,比如某系統會變成系統特定的輸入法,而不是用戶設定的輸入法,並且不讓截屏,所以我只好拍照片了。
    密碼

  4. 日期 type=”date”
      手機瀏覽器裡面,如何方便的輸入日期?很簡單,只需要設置type=」date」就可以了,至於效果如何嗎,就要看手機系統、版本、瀏覽器、輸入法的了。我手頭測試設備很少,不能全面測試,舉一個作為例子,大家看一下效果圖:
    日期

  5. 日期時間 type=”datetime-local”
      這個不僅可以選擇日期,還可以選擇時間。不過要注意type=”datetime”是不行的(各大瀏覽器都不支援),要用type=”datetime-local”才行。不多說了,看圖。
    整體效果

  6. 時間 type=”time”
      單獨選擇時間的。
    時間

  7. 月份 type=”month”
      選擇年和月的,不是只有月份。
    整體效果

  8. 周 type=”week”
      同理,也是選擇年和周,一年內第多少周。
    周

  9. 上傳文件和圖片 type=”file”
      上傳功能,有一個特性,可以調用手機攝影機(後攝)拍照,然後還可以訪問拍下來的照片,於是就產生了一種功能,掃碼二維碼。在網上找了半天,已經有測試成功的了。以前以為手機瀏覽器無法掃二維碼呢,現在看來也是可以的。悄悄的透露一下地址://blog.csdn.net/yisuowushinian/article/details/50548742
    上傳文件和圖片

  10. 選擇顏色 type=”color”
      可以調用系統的調色板,選擇顏色,不過對於我這樣沒有藝術細胞的人,只能是瞎點。
    選擇顏色1
    選擇顏色2

  11. 數字 type=”number”
      這個首先可以設定輸入法為數字狀態,不用再從中文改成數字了,省去用戶的一個步驟,有些版本還可以限制用戶更換狀態。想輸入英文、漢字是沒戲了,不過還是有點小問題,因為小數點、正負號、e都屬於合法字元,所以可以輸入,但是卻沒有判斷數量和位置。
      比如小數點可以輸入n個,+-號可以任意位置輸入。這就有點鬱悶了。還有科學計數法的e,這個我都忽略了,看到能輸入e想了半天才想起來想的很周到,但是我輸入eeee,也是可以的。既然都做了限制,為啥不順便限制一下數量呢?
    數字

  12. 電話號碼 type=”tel”
      這個嘛,有些版本會設定輸入法為數字狀態,有些版本就沒啥效果了,如果電話號裡面只有數字的話,建議用number的方式。
    電話號碼

  13. 電子郵件 type=”email”
      這個也基本沒啥效果。輸入法應該出現@、 .com、 163.com 這類的快捷輸入的,可是沒有發現。不知道其他系統或者輸入法有沒有。
    電子郵件

  14. 網址 type=”url”
      可以設定輸入法為英文狀態,但是沒有出現// 、.com、.cn、www 這類的快捷輸入。
    網址

  15. 滑塊 type=”range”
      這個好像以前就有,只是不常用。不貼圖了,也沒啥彈出效果,直接拽就好。

  16. 查詢 type=”search”
      這個唯一特點就是輸入資訊後,右側可以出現一個「X」,按一下就會清空文本框。
    查詢

  17. datalist
      這個是給文本框提供一個像下拉列表框那樣的備選項,還是比較實用的,只是有一個小問題,他自帶過濾功能,比如輸入 a 那麼只會保留a開頭的備選項,其他的 就都消失了。如果輸入了資訊只會,想換成其他備選項的話,就需要先清空才行,否則其他選項是不會出現了。不過好在我們有search,還記得他有什麼功能嗎?那個x。好了這兩個似乎是絕配了。
    備選

Vue組件的基礎知識

  表單這一塊為啥要做成組件呢?因為要復用呀。一個表單裡面有很多很多文本框、下拉列表框,一個項目又有很多很多的表單?如果一個一個的設置屬性,是不是太麻煩。如果需求變化了,要先找到這個*.vue,然後再去修改對應的屬性。好麻煩的說。如果做成組件,不僅僅可以達到復用的效果,還可以做到業務需求和程式碼的分離!

組件之hello word

  先做一個簡單的組件看看組件到底是啥樣子的。下面是官網的例子(加了一個props),我們來分析一下。

Vue.component('button-counter', {
        props:["value"],
        data: function() {
            return {
                count: 0
            }
        },
        template: `<button v-on:click="count++">
You clicked me {{ count }} times.{{value}}</button>`
    });

    new Vue({ el: '#components-demo' });
<div id="components-demo">
    <button-counter value="3"></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
    <button-counter></button-counter>
</div>

  首先使用Vue.component(‘button-counter’, {}) 註冊一個組件。第一個參數就是組件的名稱,後面的參數是組件的實現程式碼,其中包括屬性(props)、內部變數(data)、模板(template)、方法(methods)等。其實組件和vue的實例還是很像的,最明顯的就是多了個屬性(props)和模板。
  屬性(props)是把組件外部的數據傳遞到組件內部,是一個很基礎的數據傳遞方式。可以傳遞的數據類型也沒有限制。數字、文本、對象都可以。
  模板呢,就是組件內部的結構,編寫方式和vue的實例是很像的。這裡有個主意的地方,一開始我沒注意看,「template:」後面跟的是啥?不是單引號哦,而是鍵盤左上角esc鍵下面的那個。這個符號終於派上用場了。是不是一直沒按過?
  用這個符號框起來的可以直接換行,這樣就不用一行一行的「+』」了。
  頁面里使用的方式來引用,相當於我們自己定義了一個dom。當然這個dom是需要vue來解析的,沒有vue解析的話瀏覽器是不會識別。運行的時候也是沒有的,直接就是我們寫的模板(綁定數據後)的內容。
  data使用了function的形式,這個是在組件復用的時候區分多個組件的內部數據的。如果不用function的形式,復用的多個組件,將會共用同一個data值。
  然後就是做一個vue的實例,對div進行託管。

  表單是使用率最高的一個地方了,項目再小也要有個表單,那麼如何更好的做好表單呢?我們思路就是————依賴注入。這個可不是sql注入攻擊,大家不要弄混淆了。那麼如何實現呢?讓我們一一分析。

組件的特點和優勢

  我們為啥要做表單組件呢?首先要看看組件的優勢了,優勢都有哪些呢?封裝和復用、切換表單元素的形式、適配各種UI。

  1. 復用和封裝
      等等,原生的表單元素不是也可以復用嗎?為啥還要弄個組件?這個就要做一個對比了。用原生的方式做一個下拉列表框是啥樣的呢?
<select>
  <option value ="1">男</option>
  <option value ="0">女</option>
</select>

  要寫好幾行太麻煩了,如果封裝一下,各種設置由組件內部解決,外部傳參數就可以了,那麼是不是可以很方便呢?
  不管多複雜的表單元素,一行搞定,其他的交給組件內部處理。

  1. 可以隨意切換「形態」

經理說,這個下拉列表框改成單選的形式吧,這樣用戶選著方便。

  於是我們只好改成這樣:

<input type="radio" checked="checked" name="Sex" value="1" />男性
<input type="radio" name="Sex" value="0" />女性

過兩天經理又說了:哎呀,還是下拉列表框好看,你再改回去吧。

  。。。。。。
  真的嗎?算了,經理說啥就是啥。看在工資的份上我忍!
  經理的要求必須做到,沒有討論的餘地。那麼怎麼辦呢?只能改自己了。當然不是翻來覆去的手敲,而是做成組件!
  比如:複選改單選,單選改下拉列表框。通過表單元素組件,改一下就可搞定。

  1. 適配器

  現在vue有好多好多UI組件,用哪個好呢?現在我們可以基於原生html封裝一個表單控制項,那麼以後呢?是不是可以針對其他UI組件封裝一個表單元素控制項呢?然後只要能夠保證介面不變,那麼我們依賴這個組件寫的程式碼就不需要改變。
  最終要實現——換UI就換UI,不影響業務邏輯的程式碼。

  現在看看寫表單組件是不是很有必要了呢?

組件的雙向綁定

  對於表單元素,還有一個需要注意的地方,那就是數據的雙向綁定!我們先來個簡單的練練手,對 input 封裝一下。

Vue.component('my-input', {
        props:["value"],
        template: `<input type="text" 
        :value="value" 
        @input="$emit('input',$event.target.value)"  
        :key="1">`
    });
var form = new Vue({ 
        el: '#components-demo',
        data:{
            formValue:{
                v1:'22'
            }
        }
    });

<div id="components-demo">
    <my-input v-model="formValue.v1"></my-input>
     {{formValue.v1}}
</div>

  先看一下頁面里的使用方法,是不是很熟悉的味道,熟悉的v-model,熟悉的大括弧。
  然後再看組件內部實現。
  首先定義一個屬性(props)value,用於接收組件外面傳遞的數據,然後模板裡面要做兩件事情:接收參數、返回用戶輸入的數據。
  v-model是一個語法糖,外面可以直接用,但是組件內部就不能直接用了,必須拆成兩塊才行:一個是 :value給文本框賦值;另一個是監聽input事件(程式碼第五行),然後使用$emit向組件外部傳遞值。$emit有兩個參數,第一個參數是外部監聽的事件,第二個參數(含後面的參數)是要傳遞出去的數值。
  可能大家看著有點暈,兩個input是咋回事,我們來改變一下,就都明白了。
@change="$emit('event1',Date.now())"
  模板里加入這樣一行。change是文本框的原生change事件,這裡必須用原生的,不能用自定義的。
@change是讓vue監聽這個事件。
  $emit 是向組件外面傳遞消息,第一個參數event1,是外部vue監聽的事件,這個可以自定義,寫啥都行。
  第二個參數是要傳遞的值,這裡Date.now()是當前時間,寫$event.target.value 的話,就是文本框的值。也就是說,寫啥都行,都可以傳遞出去。
<my-input v-model="formValue.v1" @event1="fun"></my-input>

methods:{
            fun:function(data) {
                alert(data);
            }
        }

  外部監聽自定義event1事件,然後調用methods里的方法fun。
  如果理解了,那麼組件的消息傳遞算是基本掌握了。

表單元素組件

  1. 需要哪些屬性
      表單元素組件需要設置多少屬性呢?這就是苦力活了,既然把input封裝進來了,那麼他的原生屬性都應該能夠支援,就是說要在外部可以設置。那麼怎麼辦呢,如果一個個傳遞那還不如用原生的呢,所以我們設置一個對象屬性,直接傳遞一個對象過來,這樣就簡單了。
      熟悉了表單元素的屬性之後,我們可以定義一個json來保存這些屬性:
c1:{
    //輔助
    controlId: '150', // 編號,區別同一個表單里的其他控制項
    controlType: 101, // 用類型編號表示type
    colName: '姓名', //中文名稱 
    isClear: false, //isClear  連續添加時是否恢復默認值
    
    //通用
    disabled: false,  // 是否禁用
    required: true, //必填 
    pattern: '', //用正則做驗證。 
    tabIndex:0, // tab 鍵順序
    class:'cssTxt input_t1',
    title: '',  //提示資訊

    //多行文本
    rows:5,  //行數
    cols:100, //列數

    //文本框類
    name:'',  
    value: '',  
    placeholder: '請輸入姓名',  
    readonly: false, //只讀  
    size: 10, // 字元寬度
    maxlength: 20, //最大字元數
    autocomplete: 'on', //off
    min: 1, // 最小值
    max: 100, // 最大值
    step: 1, // 步長
    multiple: false, //是否可以有多個值,用於上傳文件
    
    listKey:'browsers', //備選文字標識
     
    //選擇類和備選文字的選項
    list: [{
            "id": "1",
            "name": "北京",
            "check": false
        }
        , {
            id: '2',
            name: '上海',
            check: false
        }, {
            id: '3',
            name: '廣州',
            check: false
        }
    ]
}

  因為json的結構可以非常靈活的組合,所以這裡設計一個大而全的結構,把所有需要的屬性都放在一起,使用的時候,可以根據元素類型靈活取捨。
  看到這裡大家可能想,這樣太複雜了,還不如直接使用原生的呢。大家先別急,看完下面這三點然後在下結論。

  • 不是所有類型都需要這些屬性,每一個類型用到的並不多。
  • 可以寫一個輔助工具來生成這個json,並不需要我們手擼程式碼。
  • 可以根據文檔自動生成這個json。

  比如純文本框(type=」text」)可以簡化為:

colName:{
        controlId: 'colName', //ColumnID
        controlType: 116,  
        class:'cssTxt input_t1',
        placeholder: '請填寫標題',  
        size: 30,  
        maxlength: 50
}

  這樣是不是簡單多了呢?其實最簡單的設置只需要 controlType 即可,其他的都可以不設置,但是也就意味著只能用默認的文本框,沒有辦法進行其他的設置。總之還是要看你要對錶單進行多少設置。

文本框類的表單元素組件

  說了這麼多,還沒看到程式碼,是不是等不急了呢?其實程式碼也沒啥好說的,就是用了最笨的方法,一點一點設置屬性。

 Vue.component('my-input', {
    props:["value","meta"],
    data:function(){
        return {
            type:{  //把編號變成文本的形式
            100:'textarea',         //多行文本框
            101:'text',             //單行文本框
            102:'password',         //密碼
            103:'date',             //日期
            //其他略。。。。。。
            }
        }
     },
    methods:{
        //text
        textInput:function(event, meta){
            var returnValue = event.target.value;
            //添加自己的監聽事件。本來想寫在一起的,但是不好用,只好分開了。
            //vue的回調
            this.$emit('input',returnValue);
            
        },
        textChange:function(event, meta){
            var returnValue = event.target.value;
            //添加自己的監聽事件
            this.$emit('change', returnValue,event.target, meta);  
        } 
    },
    template: `<span>
        <span v-if="meta.controlType===100">
            <!--多行文本框-->
            <textarea :id="'c'+meta.controlId" 
            :name="'c'+meta.controlId"  
            :class="meta.class" 
            :readonly="meta.readonly"
            :rows="meta.rows" 
            :cols="meta.cols" 
            @input="$emit('input',$event.target.value)"  
            @onkeyup="textChange($event,meta)"
            :placeholder="meta.placeholder"
            >
            </textarea>
        </span>
        <span v-else-if="meta.controlType>100 && meta.controlType<130 ">
            <!--文本框類-->
            <input  :id="'c'+meta.controlId" 
            :name="'c'+meta.controlId"  
            :disabled="meta.disabled"
            :class="meta.class" 
            :type="type[meta.controlType]" 
            :value="value" 
            :placeholder="meta.placeholder"
            :readonly="meta.readonly"
            :size="meta.size"
            :maxlength="meta.maxlength"
            :autocomplete="meta.autocomplete"
            :min="meta.min"
            :max="meta.max"
            :step="meta.step"
            :multiple="meta.multiple"
            :list="meta.listKey"
            :title="meta.title"
            
            @input="textInput($event,meta)"
            @change="textChange($event,meta)"
             
            :key="'ckey_'+meta.controlId">

            <!--文本框的備選項-->
            <datalist v-if="typeof(meta.listKey)!=='undefined'" :id="meta.listKey">
                <option v-for="item in meta.list" :label="item.id" :value="item.name" />
            </datalist>
        </span>
});

  1. 屬性
      value用於雙向綁定,這個要單獨設置,其他的屬性統統放在meta裡面。這樣介面就固定了,以後需要新的屬性也不用修改介面。

  2. 內部變數
      這個是為了做個替換,因為外部設置的是類型編號,而不是類型名稱,所以內部需要做一個替換,這樣瀏覽器才能識別。
      那麼為啥用編號,而不直接用瀏覽器支援的類型呢?因為有些類型要做兩種用途,比如file上傳文件和上傳圖片。兩種方式要做個區分的,比如上傳圖片,可以做個圖片預覽,圖片處理等功能,上傳文件的話,就沒有這些了。所以要做個編號加以區分。另外像多行文本框和下拉列表框用的不是input,沒有type。

  3. 模板
      這裡就很笨了,用v-if根據controlType做判斷,是哪種控制項就渲染對應的模板。然後把屬性一一綁定上就可以了。
      然後就是事件的綁定。因為用戶輸入內容後,要通知上層調用者,所以需要加個事件返回用戶輸入值。第一個input是給Vue準備的,加上這個才能實現Vue的雙向綁定。
      那麼第二個事件是幹啥的?有的時候我們自己需要知道用戶的輸入操作,依據輸入做些操作,比如聯動下拉列表框。我們要知道第一個下拉列表框的change,然後設置第二個下拉列表框。這個時候就需要我們自己的事件通知。一開始想在一個函數里通知兩個上層事件的,但是沒有成功。所以只好分開了。Emmm,也許可以改成數據驅動的方式,這個還沒太想好。

  4. 方法
      寫了兩個方法,一個是返回給Vue的,實現數據雙向綁定。另一個是給我們自己用的。

選擇類的表單元素組件

  選擇類指的是多選組(checkbox)、單選組(radio)、複選框(checkbox)以及下拉列表框。

Vue.component('my-input', {
    props:["value","meta"],
    methods:{
        //select
        selectChange:function(event, meta){
            var returnValue = '';

            var items = event.target.selectedOptions; //選中項的集合
            var arr = [];
            for (var i=0;i<items.length;i++) {
                var item = items[i];
                arr.push(item.value);
            }
            returnValue = arr.join(',');

            //添加聯動事件
            this.$emit('select', returnValue, meta.nextSelect);  
            //vue的回調
            this.$emit('input',returnValue);

            return returnValue;
        },

        //CheckBox
        checkChange: function (event) {
            var returnValue = event.target.value;

            if (this.meta.controlType === 155) {
                //複選框
                returnValue = event.target.checked;
            }
            else{
                //修改綁定情況
                var selectValue = returnValue;
                var arr = [];
                for (var key in this.meta.list) {
                    var item = this.meta.list[key];
                    if (item.id === selectValue) {
                        this.meta.list[key].check = event.target.checked;
                    }
                    if (item.check) {
                        arr.push(item.id);
                    }
                }
                returnValue = arr.join(',');
            }
            
            //調用上級的input事件
            this.$emit('input',returnValue);

            return  returnValue;
        },

        //radio
        radioChange: function (event, meta) {
            //單選
            var returnValue = '';

            var items = event.target.selectedOptions; //選中項的集合
            var arr = [];
            for (var i=0;i<items.length;i++) {
                var item = items[i];
                arr.push(item.id);
            }
            returnValue = arr.join(',');
            this.$emit('select', returnValue, meta.nextSelect);  //添加聯動事件
            return returnValue;
        }
    },
    template: `<span>
        <span v-else-if="meta.controlType >= 150 && meta.controlType <= 152  ">
        <!--下拉列表框-->
            <select  :id="'c'+meta.controlId" 
            :name="'c'+meta.controlId"  
            :class="meta.class" 
            :multiple="meta.controlType === 151"
            @change="selectChange($event,meta)" 
            >
                <option :key="-2" value="-2" >請選擇</option>
                <option  
                 v-for="(item,index) in meta.list" 
                 :key="index"  
                 :value="item.id" 
                 :selected="item.check">
                    {{item.name}}
                </option> 
            </select>
        </span> 

        <span v-else-if="meta.controlType === 153 ">
            <!--單選組 -->
            <label role="radio" v-for="item in meta.list" >
                <input 
                    type="radio" 
                    :class="meta.class"  
                    :checked="item.check" 
                    :name="'c'+meta.controlId" 
                    :value="item.id"
                    @input="$emit('input',$event.target.value)"  
                >
                <span>{{item.name}}</span>
            </label> 

        </span>

        <span v-else-if="meta.controlType === 154 ">
            <!--多選組-->
            <label role="checkbox" 
            v-for="item in meta.list" 
            class="checkbox_g_t" 
            :key="'lblchks'+item.id"  > 
                <input  :id="'c'+meta.controlId" 
                type="checkbox"
                :name="'c'+meta.controlId"  
                :class="meta.class" 
                :value="item.id"
                :readonly="meta.readonly"
                :key="'chks'+item.id"
                @input="checkChange($event)"
                >
                <span>{{item.name}}</span>
            </label> 

        </span> 

        <span v-else-if="meta.controlType === 155 ">
            <!--複選框-->
            <label role="checkbox" 
            v-for="item in meta.list" 
            class="checkbox_g_t" 
            :key="'lblchk'+item.id"  > 
                <input  :id="'c'+meta.controlId" 
                type="checkbox"
                :name="'c'+meta.controlId"  
                :class="meta.class" 
                :value="item.id"
                :readonly="meta.readonly"
                :key="'chk'+item.id"
                @input="checkChange($event)"
                >
                <span>{{item.name}}</span>
            </label> 
        </span>
    </span>`
});

  1. 模板
      還是老辦法,用v-if判斷渲染哪個模板,然後還是一個一個賦值,然後選項有一個循環,v-for一下就可以了。這裡的選項格式和文本框的備選項格式採用了相同的設置。這樣統一一下比較方便。
  2. 方法
      每類控制項都做一個方法,對應不同的取值方式。不知道有沒有更好的方式,現在用的比較麻煩,期待更好的方法。如果發現了肯定會更新的。
      還有個返回值類型的問題,我是習慣返回字元串的形式,比如1,2,3 。而不是數組。因為資料庫里保存的是字元串而不是數組。當然這塊應該能夠靈活一些,打算加一個返回值類型的設置。

輔助工具

  這麼複雜的json要怎麼弄?不會告訴我要手擼吧!當然不是,我這麼懶怎麼能手寫呢,當然是弄個工具來輔助了。
  輔助工具的思路,首先確定要哪種類型的表單元素,然後根據類型顯示需要設置的屬性,然後就可以點點點了(當然有些屬性需要打幾個字),就可以生成json文件,同時還可以預覽效果。
  這個只是第一步哦,後面的還會有根據文檔生成的輔助工具。
  文檔在哪裡?做項目總會有個資料庫文檔吧,文檔會描述都有啥表,啥欄位。會介紹一下欄位名稱、欄位類型、欄位大小吧。這樣我們就可以根據這些資訊設置默認的json了。然後不能默認的再點點點一下就可以了。
  這個輔助工具就是用的這個表單元素組件寫的,也算是一個實際應用,程式碼比較多,就不貼了。感興趣的話,看下面開源介紹。
輔助工具

開源

  源碼下載:Vue表單組件

  在線演示:Vue表單組件在線演示

  這裡是表單元素組件源碼和demo,還有那個輔助工具。
  另外會保持持續更新的,畢竟現在還只是初步學習vue實現的也只是簡單的功能。
  下圖是輔助工具的頁面,首先選擇類型,然後預留會有變化,然後按照下面的屬性選擇即可,同時預覽也會有對應的變化。

最後感謝大家的支援!
![感謝感謝]