如何根據業務封裝自己的功能元件

木公呢發表於2019-04-18

查詢回顯input的封裝

最近有幸在做一個管理系統採用的是vue+element-ui, 表單頁面非常多, 而且都出奇的大,在多頁面開發的時候做大表單的優缺點我大概先說一下, 我們的任務是, 基於現在的工具, 使他更簡潔, 功能也不差, 而且更利於開發, 維護

直接進入正題

功能是這樣:

表單中常有的功能是一個input繫結一個按鈕, 當我點選按鈕的時候, 彈出查詢框, 裡面有個小列表, 查到資料後點一行再回顯, 很簡單的需求, 但是會有大量的應用地點, 所以肯定不能複製貼上, 輸入框我們每次都可以寫, 但是彈出來的小查詢如果每個表單, 每個獨立的彈框再去重複寫就麻煩了, 但是如果我們把它提出來我們就輕鬆很多, 通過資料去控制功能

如何根據業務封裝自己的功能元件

有些人可能覺得都是廢話, 而且就這麼個簡單的東西, 寫這麼多有必要麼(我想盡量的把我想到的說出來, 手動滑稽)

要做的就是這個查詢的小列表, 我們整理一下要做的事情, 先做規劃再寫程式碼, 避免邊寫邊改, 不然會讓程式碼越來越難維護, 寫到下面發現上面不該那麼寫, 再去改又懶的改, 然後就鬱悶著勉為其難的提交上去了, 雖然功能在但自己看著都......

1. 分析需求: 我們需要什麼元素?

a. 一個form表單, 一個table, 分頁(佈局)
b. n個條件框, 查詢按鈕, 重置按鈕, 其他功能按鈕(form內部)

通過整理元素我們知道, 有幾樣東西是固定的, 一個form, 一個不知道幾列的table, 一個分頁功能,查詢, 重置按鈕

整理出這個我們就可以第一步把元素構建全, 可能有n個的我們就用一個先佔個位置, 結構如下:

<div class="box">
  <div class="form">
    <form action="">
      <input type="text"> *n
    </form>
  </div>
  <div class="table">
    <table>
      <tr> *n
        <td></td>
      </tr>
    </table>
  </div>
  <div class="paging"></div>
  <div class="button">
    <button>查詢</button>
    <button>重置</button>
    <button>其餘功能</button> *n
  </div>
</div>
複製程式碼

*n的地方代表了接下來我們要用迴圈建立

2. 我們需要實現什麼方法並且那些是要外部傳遞的

a. 查詢
b. 點選分頁後查詢資料
c. 重置
d. 選中一行時拿到資料
e. 其餘功能的觸發

這樣一梳理, 就很清晰了, 因為我們的查資料和分頁在一個介面中我就講分頁查詢, 和普通查詢放到了一個函式裡, 所以methods中實現剩下的四個方法

methods: {
  searchData(pageNum = 0) {
    //查詢資料, ES6引數賦值預設為0頁
  },
  selectRowData(row) {
    //選中單行是觸發的函式, 在各個ui框架table中都應該有這個方法, 我們只要實現它就行了
  },
  resetSearchForm() {
    //重置form引數
  },
  doFunction(){
    //執行其他函式
  }
}
複製程式碼

好了, 接下來看看那些需要是外部傳入的方法, 以及為什麼要從外部傳入

i. 首先是一個查詢資料的方法

理由: 我們需要從外部傳入, 這是個查詢列表的元件, 我們肯定不是隻適用於一個介面, 而是儘量讓他各種各樣情形下都適用於我們

ii. 選中單行後要傳給父元件的方法

在vue中, 子元件是不能修改父元件的, 在框架封裝中大部分是作者自己封裝了dispatch 和 broadcast, 但是我們就應用於自己的專案, 所以我們不用那麼麻煩, 如果想用可以去ui框架原始碼中複製一份出來用, 我們就通過父元件傳一個函式給子元件, 然後子元件呼叫這個函式回撥給父元件就好了, 所以要傳一個函式

iii. 其他的執行函式

3. 我們要vue的data引數了, 並確定哪些是在元件中, 哪些是外部傳入

a. from表單的資料繫結(但是我們不確定要有幾個框所以這裡要多留一步)

沒錯就這一個就夠了, 我們要做的是可動態配置所以更多的來自於傳參

a. 傳入一個input陣列, 決定有幾個條件搜尋框
b. 傳入table的列的陣列, 附帶上每列寬度, 列名
c. 傳入其他功能按鈕列表陣列
d. 傳入查詢出來的分頁引數
e. 傳入查詢出來的資料列表陣列

4. 有了這些我們接下來就是一一實現這些東西就好了

還是先從結構開始

   <div class="searchAlert">
      <div class="inputBox">
        <el-form :inline="true" :model="searchForm" class="searchAlertForm" ref="searchForm">
        <!--迴圈建立條件搜尋框-->
          <el-form-item v-for="item in inputarr" :key="item.label" :prop="item.dataName">
            <el-tooltip :content="item.label" placement="top">
              <el-input v-model="searchForm[item.dataName]" :placeholder="item.label" size="mini"></el-input>
            </el-tooltip>
          </el-form-item>
        </el-form>
      </div>
      <div class="tableBox">
        <el-table :data="searchdatalist" style="width: 100%" size="mini" highlight-current-row
          @current-change="selectrowdata" :border="true">
          <!--迴圈建立table列-->
          <el-table-column v-for="item in coleumarr" :key="item.label" :prop="item.prop" :label="item.label"
            :width="item.width">
          </el-table-column>
        </el-table>
      </div>
      <!--判斷是否顯示頁碼條-->
      <div class="pagination" v-if="searchpaging">
        <el-pagination layout="prev, pager, next" :total="searchpaging.totalPage" :small="true"
          :page-size="searchpaging.pageSize" @current-change="searchdata">
        </el-pagination>
      </div>
      <div class="buttonBox">
        <el-button size="mini" @click="resetsearchform">重置</el-button>
        <el-button size="mini" @click="searchdata" type="primary">搜尋</el-button>
        <el-button size="mini" v-for="btn in buttonArr" :key="btn.name" size="mini" @click="doFunction(btn.name)" :type="btn.type">btn.name</el-button>
      </div>
    </div>
複製程式碼

5. 實現可供迴圈建立的陣列結構

a. form(先建立一個, 然後放到陣列中就好了)
{
  label:"輸入框的名稱"
  dataName:"作為雙向資料繫結的名字, 同時作為繫結prop的名字"
}
複製程式碼

現在來看我們是不能在這個元件中直接定義好form的model結構的, 我們就要動態建立, 在元件中我們只要建立一個空的物件就好了

b. table-col
{
  label:"列名稱"
  prop:"對應列內容的欄位名"
  width:"單列寬度"
}
複製程式碼
c. button
{
  name:"事件和按鈕名字",
  type:"按鈕型別"
}
複製程式碼

6. 接下來我們去實現我們要傳入的方法

    //回顯功能, 可以拿到單選資料
    searchCbFn(rowData) {
      console.log(rowData)
    },
    //查詢功能, 分頁等
    searchFn(formData, pageNum = 0) {
      api({formData:formData, pageData:pageNum}).then(res => {
        console.log(res.data)
        this.searchDataList = res.data.dataList
        //頁面展示 分頁大小控制
        this.searchPaging = { ...pagInfo, pageSize: 5 }
      }).catch(err => {
        throw err;
      })
    }
複製程式碼

7. 最後我們就要補齊所有傳入引數

    searchDataList:{}
    searchPaging:{}
複製程式碼

最後總結:

這是我第一次寫分享問, 所以應該還欠缺寫邏輯, 如果什麼不懂, 或者建議, 請多多告訴我, 程式碼我放在:https://github.com/wqliusong/happy有元件, 有可以直接執行的單頁面

再說一下我遇到的問題吧, 一個就是vue的雙向資料繫結是可以動態的,提醒一下大家, 物件後加動態的名字要用[], 不能用.的, 注意我的input那裡就懂了, data裡的引數也可以動態建立的, 有了這些我們可以解決很多問題, 所以我們不用很在意他的初始資料格式

接下來我還會寫一個多行編輯的元件, 雖然很多ui中也有, 但是功能都略顯單一, 可能我們程式設計師就是隻要會1+1=2, 就能解決所有數學難題了的一幫人, 我要嘗試讓他功能豐富一點, 在一個就是關於動態增加驗證條件的一些實現, 希望大家能有點收穫

相關文章