一個增刪改功能的表格小demo

項目中遇到的一個小功能,原來的開發的寫法可能有點冗餘了,擴展性不高,又出了點小bug,特此回來本身寫個相似的小demo,遇到的一些問題記錄一下。
大概這樣html

  • 一個操做保留在本地的一個小表格(簡化樣式了)
  • 請求的數據是全部的 name 列的數據
  • name列是個select,option會隨着表格數據的增長而改變,也就是option不會和列表數據重複
  • 三個主要方法,add,delete,change。由於最近想學習下lodash,深拷貝用的 _.cloneDeep()

    圖片描述

設計

開始前必定思考下這個怎麼實現會比較好,項目用的vue,拋棄本來的jquery,基於vue的數據驅動去作,響應式這塊vue幫咱們作好了。vue

下面是html的寫法,一個v-for去實現頁面jquery

<div>
       <div style="text-align:left">
          <button style="width:100px;margin-left: 50px;margin-bottom:20px;" @click="add">add</button>
      </div>
      <table class="v-table">
          <tr class='tr'>
              <th>
                name    
              </th>
              <th>
                  delete
              </th>
          </tr>
          <tr class='v-tr' v-for=" (msg,index) in dataList">
              <td>
                <select name="network" @change='change(msg,index)' v-model="msg.id">
                    <option v-for="text in msg.list" :value="text.id">{{text.name}}</option>
                </select>
              </td>
              <td>
                  <button @click='deleteTr(msg,index)'>delete</button>
              </td>
          </tr>
      </table>
  </div>

表格的數據是 dataList,數據結構這樣數組

dataList:[
         {
             id:'a',//作提交時須要,當前行數據的id
             list:[//name 列select的option數據
                {
                    name:'a',
                    id:'a'
                },
                {
                    name:'b',
                    id:'b'
                },
                {
                    name:'c',
                    id:'c'
                },
                {
                    name:'d',
                    id:'d'
                },
             ]
         }
     ]

這裏是最簡單的結構了數據結構

而後通常咱們在初始化的時候向後臺請求到初始的數據,就是dataList中的list,我這裏設定的假數據這樣性能

resource:[
            {
                name:'a',
                id:'a'
            },
            {
                name:'b',
                id:'b'
            },
            {
                name:'c',
                id:'c'
            },
            {
                name:'d',
                id:'d'
            },
        ]

初始化

init(){
        let resource=_.cloneDeep(this.resource)
        let obj={
            list:resource,
            id:resource[0].id
        };
        this.dataList=[];
        this.dataList.push(obj);
      }

這裏出現了深拷貝,由於咱們的數據結構是引用類型嵌套引用類型,這裏若是不深拷貝,那下面我對dataList中的項進行更改時,this.resource也會被更改。這個demo裏,this.resource是不能夠被污染更改的。這也是坑之一了學習

add

add(){
            let that=this;
            //新建條數限制
            if(that.dataList.length>=that.resource.length){
              return false
            }
            //深拷貝數據
            let allData=_.cloneDeep(that.resource);
            // 新增時,判斷已經建立的數據,而後先在對應的數據裏刪除  
            //這裏對allData進行了操做,splice操做會直接更改原數組,而且allData是外層循環,若是先splice後,再循環內層,在運行 [i].id這個操做時會報錯
            //allData是複製出來的源數組,dataList是表格內的數組
            for(let i=0;i<that.dataList.length;i++){
                for(let j =0;j<allData.length; j++){
                    if(that.dataList[i].id===allData[j].id){
                        allData.splice(j,1)
                    }
                };
            };
            //推入一組數據
            let obj={
                list:allData,
                id:allData[0].id
            };
            that.dataList.push(obj);
            //把全部已選的數據單獨放置到一個arr數組裏
            let arr=[];
            for(let k=0,len=that.dataList.length;k<len;k++){
                arr.push(that.dataList[k].id);
            };
            //在dataList的list項中刪除全部的已選數據
           for(let o =0; o<that.dataList.length; o++){
                for(let  u =0; u<arr.length; u++){
                    for(let  p=0; p<that.dataList[o].list.length; p++){
                        if(arr[u]==that.dataList[o].list[p].id){
                            that.dataList[o].list.splice(p,1);
                        }
                    };
                };
            };
            //dataList的list項中將自身的id對應的數據推入
            for(let  r =0; r<that.resource.length; r++){
                for(let  e =0; e<that.dataList.length; e++){
                    if(that.resource[r].id==that.dataList[e].id){
                        that.dataList[e].list.unshift(that.resource[r]);
                    }
                };
            };
        },

這裏除去深拷貝的坑,還有一個是 若是在嵌套循環中須要更改數組(例如splice方法),那麼須要被更改的數組必定最後一個被嵌套循環。不然在一些判斷條件裏會出錯.優化

delete

deleteTr(msg,index){
            let that=this;
            if(that.dataList.length<=1){
                return false;
            }
            //先直接刪除,去掉對應數據
            that.dataList.splice(index,1);
            //處理對應數據裏下拉框裏的數據
            //複製一份源數據
            let allData=_.cloneDeep(that.resource);
            let obj={};
            //遍歷找出刪掉的是數組裏的哪一個數據,而後吧他給obj
            for(let i=0,len=allData.length; i<len; i++){
                if(msg.id===allData[i].id){
                    obj=allData[i]
                }
            };
            //循環dataList,將刪除的數據推動dataList的list裏面
             for(let o =0; o<that.dataList.length; o++){
                that.dataList[o].list.push(obj);
            };
         },

這裏正常刪除再添加this

change

change(msg,index){
            let that=this;
            //更改dataList中的list
            //把全部已選的數據單獨放置到一個arr數組裏
            let arr=[];
            for(let k=0,len=that.dataList.length;k<len;k++){
                arr.push(that.dataList[k].id);
            };
             //在dataList的list項中刪除全部的已選數據
            for(let o =0; o<that.dataList.length; o++){
                that.dataList[o].list=_.cloneDeep(that.resource);
                for(let  u =0; u<arr.length; u++){
                    for(let  p=0; p<that.dataList[o].list.length; p++){
                        if(arr[u]==that.dataList[o].list[p].id){
                            that.dataList[o].list.splice(p,1);
                        }
                    };
                };
            };
            
            //dataList的list項中將自身的id對應的數據推入
            for(let  r =0; r<that.resource.length; r++){
                for(let  e =0; e<that.dataList.length; e++){
                    if(that.resource[r].id==that.dataList[e].id){
                        that.dataList[e].list.unshift(that.resource[r]);
                    }
                };
            };
      }

這裏我把select的v-model設置成msg.id,這樣每次切換時id會自動變化。spa

//         let allData=_.cloneDeep(that.resource);
            for(let  i =0,len=that.dataList.length; i<len; i++){
                that.dataList[i].list=_.cloneDeep(that.resource);
            };

這一段最開始也錯了,開始是註釋的那行。
dataList裏的每一個list都須要獨立的內存地址,因此這裏須要循環深拷貝。

總結

剛剛寫完代碼,測了下功能沒有問題就來記錄了,代碼尚未迭代優化,本身也沒有想到更好的處理數據的方法,可是總以爲本身這個嵌套着的循環性能有些低下了。
會優化一下代碼
剛回看一下就發現很多須要改的地方。不過須要休息了,下次編輯一下
平常鼓勵本身。。。

這樣的表格也的確不適合數據量大的狀況,數據量大的狀況須要換一下實現思路。

msl比賽1:1時開始寫功能,寫完看下朋友圈,md好像錯過了什麼。

相關文章
相關標籤/搜索