小程序模板網(wǎng)

小程序選人控件 - 仿企業(yè)微信實現(xiàn)多層級無規(guī)則嵌套

發(fā)布時間:2018-10-30 14:34 所屬欄目:小程序開發(fā)教程

在很多系統(tǒng)中都有選擇聯(lián)系人的需求,市面上也沒什么好的參照,產(chǎn)品經(jīng)理看企業(yè)微信的選人挺好用的,就說參照這個做一個吧。。。

 

 

算了,還是試著做吧,企業(yè)微信的選人的確做的挺好,不得不佩服。

先看看效果圖吧,多層級無規(guī)律的嵌套都能搞定

 

 

一、設(shè)計解讀

 

 

整個界面分為三部分:

  • 最上面的返回上一層按鈕
  • 中間的顯示部門、人員的列表
  • 最下面顯示和操作已選人員的 footer。

為什么加一個返回上一層按鈕呢?

我也覺得比較丑,但小程序無法直接控制左上角返回鍵(自定義 Title 貌似可以,沒試過),點左上角的返回箭頭的話就退出選人控件到上個頁面了。

我們的需求是點擊一個文件夾,通過刷新當(dāng)前列表進(jìn)入下一級目錄,感覺像是又進(jìn)了一個頁面,但其實并沒有,只是列表的數(shù)據(jù)變化了。由此實現(xiàn)不定層級、無規(guī)律的部門和人員嵌套的支持。

比如先點擊了首屏數(shù)據(jù)的第二個 item,它的 index 是 1 ,就將 1 存入 indexList ;返回上一層時將最后一個元素刪除。

當(dāng)勾選了某個人或部門時,會在底部的框中顯示所有已選人員或部門的名字,當(dāng)文字超過屏幕寬度時可以向右無限滑動,底部 footer 始終保持一行。

最終選擇的人以底部 footer 里顯示的為準(zhǔn),點擊確定時根據(jù)業(yè)務(wù)需要將已選人員數(shù)據(jù)發(fā)送給需要的界面。

二、功能邏輯分析

先看看數(shù)據(jù)格式

{
  id: TEACHER_ID,
  name: '教師',
  parentId: '',
  checked: false,
  isPeople: false,
  children: [
    {
      id: TEACHER_DEPARTMENT_ID,
      name: '部門',
      parentId: 'teacher',
      checked: false,
      isPeople: false,
      children: []
    },
    {
      id: TEACHER_SUBJECT_ID,
      name: '學(xué)科',
      parentId: 'teacher',
      checked: false,
      isPeople: false,
      children: []
    },
    {
      id: TEACHER_GRADECLASS_ID,
      name: '年級班級',
      parentId: 'teacher',
      checked: false,
      isPeople: false,
      children: []
    },
  ]
}

所有的數(shù)據(jù)組成一個數(shù)據(jù)樹,子節(jié)點嵌套在父節(jié)點下。

id, name 不說了,parentId 指明它的父節(jié)點,children 包含它的所有子節(jié)點,checked 用來判斷勾選狀態(tài),isPeople 判斷是部門還是人員,因為兩者的圖標(biāo)不一樣。

注意:

本控件采用了數(shù)據(jù)分步加載的模式,除了最上層固定的幾個分類,其他的每層數(shù)據(jù)都是點擊具體的部門后才去請求服務(wù)器加載本部門下的數(shù)據(jù)的,然后再拼接到原始數(shù)據(jù)樹上。這樣可以提高加載速度,提升用戶體驗。

我也試了一次性把所有數(shù)據(jù)都拉下來,一是太慢,得三五秒,二是數(shù)據(jù)量太大的話(我這里應(yīng)該是超過1000,閾值多少沒測過),setData() 的時候就會報錯:

 

 

超過最大長度了。。。所以只能分步加載數(shù)據(jù)。

當(dāng)然如果你的數(shù)據(jù)量小,幾十人或幾百人,也可以選擇一次性加載。

這個控件邏輯上還是比較復(fù)雜的,要考慮的細(xì)節(jié)太多……下面梳理一下主要的邏輯點

主要邏輯點

1. 需要一個數(shù)組存儲所有被點擊的部門在當(dāng)前列表的索引 index ,這里用 indexList 表示

點擊某個部門進(jìn)入下一層目錄時,將被點擊部門的 index 索引 push 進(jìn) indexList 中。點擊返回上一層按鈕時,刪除 indexList 中最后一個元素。

2. 要動態(tài)的更新當(dāng)前列表 currentList

每進(jìn)入新的一層,或返回上一層,都需要刷新 currentList 來實現(xiàn)頁面的更新。知道下一層數(shù)據(jù)很容易,直接取被點擊 item 的 children 賦值給 currentList 即可。

但如何還原上一層的數(shù)據(jù)呢?

第一點記錄的 indexList 就發(fā)揮作用了,原始數(shù)據(jù)樹為 originalList,循環(huán)遍歷 indexList ,根據(jù)索引依次取出每層的 currentList 直到 indexList 的最后一個元素,就得到了返回上一層需要顯示的數(shù)據(jù)。

3. 每一次勾選或取消選中都要更新原始的數(shù)據(jù)樹 originalList

頁面是根據(jù)每個 item 的 checked 屬性判斷是否選中的,所以每次改變勾選狀態(tài)都要設(shè)置被改變的 item 的 checked 屬性,然后更新 originalList。這樣即使返回上一層了,再進(jìn)到當(dāng)前層級選中狀態(tài)還會被保留,否則刷新 currentList 后已選狀態(tài)將丟失。

4. 列表中選擇狀態(tài)的改變與底部 footer 的雙聯(lián)動

我們期望的效果是,選中currentList 列表的某一項,底部 footer 會自動添加被選人的名字。取消選中,底部 footer 也會自動刪除。

也可以通過 footer 來刪除已選人,點擊 footer 中人名,會將此人從已選列表中刪除,currentList 列表中也會自動取消勾選狀態(tài)。

嗯,這個功能比較耗性能,每一次都需要大量的計算??紤]到性能和速度因素,本次只做了從 footer 刪除只更新 currentList 的勾選狀態(tài)。

什么意思呢?假如有兩層,A 和 B,B 是 A 的下一層數(shù)據(jù),即 A 是 B 的父節(jié)點。在 A 中選中了一個部門 校長室,點擊下一層到 B,在 B 中又選了兩個人 張三 和 李四,這時底部 footer 里顯示的應(yīng)該是三個: 校長室、 張三 、 李四。此時點擊 footer 的 張三 , footer 會把 張三 刪除,中間列表中 張三 會被置為未選中狀態(tài),這沒問題。但點擊 footer 的 校長室 , 在 footer 中是把 校長室 刪除了,但再返回到上一層時,中間列表中的 校長室 依然是勾選狀態(tài),因為此時沒有更新原始數(shù)據(jù)樹 originalList。如果覺得這是個 bug, 可以加個更新 originalList 的操作。這樣就要遍歷 originalList 的每個元素判斷與本次刪除的 id 是否相等,然后改變 checked 值,如果數(shù)據(jù)量很大,會非常慢。我做了妥協(xié)……

關(guān)鍵的邏輯就這四塊了,當(dāng)然還有很多小細(xì)節(jié),直接看代碼吧,注釋寫的也比較詳細(xì)。

三、代碼

目錄結(jié)構(gòu):

 

 

footer 文件夾下是抽離出的 footer 組件,userSelect 是選人控件的主要邏輯。把這幾個文件復(fù)制過去就可以用了。

把 userSelect.js 里網(wǎng)絡(luò)請求的代碼替換為你的請求代碼,注意數(shù)據(jù)的字段名是否一致。

userSelect 的代碼

userSelect.js


import API from '../../../utils/API.js'
import ArrayUtils from '../../../utils/ArrayUtils.js'
import EventBus from '../../../components/NotificationCenter/WxNotificationCenter.js'

let TEACHER_ID = 'teacher';
let TEACHER_DEPARTMENT_ID = 't_department';
let TEACHER_SUBJECT_ID = 't_subject';
let TEACHER_GRADECLASS_ID = 't_gradeclass';
let STUDENT_ID = 'student';
let PARENT_ID = 'parent'

let TEACHER = {
  id: TEACHER_ID,
  name: '教師',
  parentId: '',
  checked: false,
  isPeople: false,
  children: [
    {
      id: TEACHER_DEPARTMENT_ID,
      name: '部門',
      parentId: 'teacher',
      checked: false,
      isPeople: false,
      children: []
    },
    {
      id: TEACHER_SUBJECT_ID,
      name: '學(xué)科',
      parentId: 'teacher',
      checked: false,
      isPeople: false,
      children: []
    },
    {
      id: TEACHER_GRADECLASS_ID,
      name: '年級班級',
      parentId: 'teacher',
      checked: false,
      isPeople: false,
      children: []
    },
  ]
}
let STUDENT = {
  id: STUDENT_ID,
  name: '學(xué)生',
  parentId: '',
  checked: false,
  isPeople: false,
  children: []
}
let PARENT = {
  id: PARENT_ID,
  name: '家長',
  parentId: '',
  checked: false,
  isPeople: false,
  children: []
}
let ORIGINAL_DATA = [
  TEACHER, STUDENT, PARENT
]

Page({
  data: {
    currentList: [], //當(dāng)前展示的列表
    selectList: [],  //已選擇的元素列表
    originalList: [], //最原始的數(shù)據(jù)列表
    indexList: [],  //存儲目錄層級的數(shù)組,用于準(zhǔn)確的返回上一層
    selectList: [],  //已選中的人員列表
  },

  onLoad: function (options) {
    wx.setNavigationBarTitle({
      title: '選人控件'
    })
    this.init();
  },

  init(){
    //用戶的單位id
    this.unitId = getApp().globalData.userInfo.unitId;
    //用戶類型
    this.userType = 0;
    //上次選中的列表,用于判斷是不是取消選中了
    this.lastTimeSelect = []

    this.setData({
      currentList: ORIGINAL_DATA, //當(dāng)前展示的列表
      originalList: ORIGINAL_DATA, //最原始的數(shù)據(jù)列表
    })
  },

  clickItem(res){
    console.log(res)
    let index = res.currentTarget.id;
    let item = this.data.currentList[index]

    console.log("item", item)

    if (!item.isPeople) {
      //點擊教師,下一層數(shù)據(jù)是寫死的,不用請求接口
      if (item.id === TEACHER_ID) {
        this.userType = 2;
        this.setData({
          currentList: item.children
        })
      } else if (item.id === TEACHER_SUBJECT_ID) {
        if (item.children.length === 0){
          this._getTeacherSubjectData()
        }else{
          //children的長度不為0時,更新 currentList
          this.setData({
            currentList: item.children
          })
        }
      } else if (item.id === TEACHER_DEPARTMENT_ID) {
        if (item.children.length === 0) {
          this._getTeacherDepartmentData()
        } else {
          //children的長度不為0時,更新 currentList
          this.setData({
            currentList: item.children
          })
        }
      } else if (item.id === TEACHER_GRADECLASS_ID) {
        if (item.children.length === 0) {
          this._getTeacherGradeClassData()
        } else {
          //children的長度不為0時,更新 currentList
          this.setData({
            currentList: item.children
          })
        }
      } else if (item.id === STUDENT_ID) {
        this.userType = 1;
        if (item.children.length === 0) {
          this._getStudentGradeClassData()
        } else {
          //children的長度不為0時,更新 currentList
          this.setData({
            currentList: item.children
          })
        }
      } else if (item.id === PARENT_ID) {
        this.userType = 3;
        if (item.children.length === 0) {
          this._getParentGradeClassData()
        } else {
          //children的長度不為0時,更新 currentList
          this.setData({
            currentList: item.children
          })
        }
      } else{
        //children的長度為0時,請求服務(wù)器
        if(item.children.length === 0){
          this._getUserByGroup(item)
        }else{
          //children的長度不為0時,更新 currentList
          this.setData({
            currentList: item.children
          })
        }
      }

      //將當(dāng)前的索引存入索引目錄中。索引多一個表示目錄多一級
      let indexes = this.data.indexList
      indexes.push(index)
      //是目錄不是具體的用戶
      this.setData({
        indexList: indexes
      })
      //清空上次選中的元素列表,并設(shè)置上一層的選中狀態(tài)給lastTimeSelect
      this.setLastTimeSelectList();
    }
  },


  //返回按鈕
  goBack() {
    let indexList = this.data.indexList
    if (indexList.length > 0) {
      //返回時刪掉最后一個索引
      indexList.pop()
      if (indexList.length == 0) {
        //indexList長度為0說明回到了最頂層
        this.setData({
          currentList: this.data.originalList,
          indexList: indexList
        })
      } else {
        //循環(huán)將當(dāng)前索引的對應(yīng)數(shù)組賦值給currentList
        let list = this.data.originalList
        for (let i = 0; i < indexList.length; i++) {
          let index = indexList[i]
          list = list[index].children
        }
        this.setData({
          currentList: list,
          indexList: indexList
        })
      }
      //清空上次選中的元素列表,并設(shè)置上一層的選中狀態(tài)給lastTimeSelect
      this.setLastTimeSelectList();
    }
  },

  //清空上次選中的元素列表,并設(shè)置上一層的選中狀態(tài)給lastTimeSelect
  setLastTimeSelectList(){
    this.lastTimeSelect = []
    this.data.currentList.forEach(item => {
      if (item.checked) {
        this.lastTimeSelect.push(item)
      }
    })
  },

  //獲取教師部門數(shù)據(jù)
  _getTeacherDepartmentData() {
    this._commonRequestMethod(2, 'department')
  },

  //請求教師的學(xué)科數(shù)據(jù)
  _getTeacherSubjectData(){
    this._commonRequestMethod(2, 'subject')
  },

  //請求教師的年級班級
  _getTeacherGradeClassData() {
    this._commonRequestMethod(2, 'gradeclass')
  },

  //請求學(xué)生的年級班級
  _getStudentGradeClassData() {
    this._commonRequestMethod(1, 'gradeclass')
  },

  //請求家長的年級班級
  _getParentGradeClassData() {
    this._commonRequestMethod(3, 'gradeclass')
  },

  //根據(jù)部門查詢?nèi)?
  _getUserByGroup(item){
    let params = {
      userType: this.userType,
      unitId: this.unitId,
      groupType: item.type,
      groupId: item.id
    }
    console.log('params', params)
    getApp().get(API.selectUserByGroup(), params, result => {
      console.log('result', result)
      let list = this.transformData(result.data.data, item.id)
      this.setData({
        currentList: list
      })
      this.addList2DataTree()
      //清空上次選中的元素列表,并設(shè)置上一層的選中狀態(tài)給lastTimeSelect。寫在這里防止異步請求時執(zhí)行順序問題
      this.setLastTimeSelectList();
    })
  },

  //通用的請求部門方法
  _commonRequestMethod(userType, groupType){
    wx.showLoading({
      title: '',
    })
    let params = {
      userType: userType,
      unitId: this.unitId,
      groupType: groupType
    }
    console.log('params', params)
    getApp().get(API.selectUsersByUserGroupsTree(), params, result => {
      console.log('result', result)
      wx.hideLoading()
      let data = result.data.data
      this.setData({
        currentList: data
      })
      this.addList2DataTree();
      //清空上次選中的元素列表,并設(shè)置上一層的選中狀態(tài)給lastTimeSelect。寫在這里防止異步請求時執(zhí)行順序問題
      this.setLastTimeSelectList();
    })
  },

  //將請求的數(shù)據(jù)轉(zhuǎn)化為需要的格式
  transformData(list, parentId){
    //先將數(shù)據(jù)轉(zhuǎn)化為固定的格式
    let newList = []
    for(let i=0; i<list.length; i++){
      let item = list[i]
      newList.push({
        id: item.id,
        name: item.realName,
        parentId: parentId,
        checked: false,
        isPeople: true,
        userType: item.userType,
        gender: item.gender,
        children: []
      })
    }
    return newList;
  },

  //將當(dāng)前列表掛載在原數(shù)據(jù)樹上, 目前支持5層目錄,如需更多接著往下寫就好
  addList2DataTree(){
    let currentList = this.data.currentList;
    let originalList = this.data.originalList;
    let indexes = this.data.indexList
    switch (indexes.length){
      case 1: 
        originalList[indexes[0]].children = currentList
        break;
      case 2:
        originalList[indexes[0]].children[indexes[1]].children = currentList
        break;
      case 3:
        originalList[indexes[0]].children[indexes[1]].children[indexes[2]].children = currentList
        break;
      case 4:
        originalList[indexes[0]].children[indexes[1]].children[indexes[2]].children[indexes[3]].children = currentList
        break;
      case 5:
        originalList[indexes[0]].children[indexes[1]].children[indexes[2]].children[indexes[3]].children[indexes[4]].children = currentList
        break;
    }

    this.setData({
      originalList: originalList
    })
    console.log("originalList", originalList)
  },

  //選框變化回調(diào)
  checkChange(res){
    console.log(res)
    let values = res.detail.value
    let selectItems = []
    //將值取出拼接成 id,name 格式
    values.forEach(value => {
      let arrs = value.split(",")
      selectItems.push({id: arrs[0], name: arrs[1]})
    })
    console.log("selectItems", selectItems)
    console.log("lastTimeSelect", this.lastTimeSelect)
    
    //將本次選擇的與上次選擇的比對,本次比上次多說明新增了,本次比上次少說明刪除了,找出被刪除的那條數(shù)據(jù),在footer中也刪除
    if (selectItems.length > this.lastTimeSelect.length){
      //將 selectList 與 selectItems 拼接并去重
      let newList = this.data.selectList.concat(selectItems)
      newList = ArrayUtils.checkRepeat(newList)
      this.setData({
        selectList: newList
      })
    }else{
      //找出取消勾選的item,從selectList中刪除
      //比對出取消勾選的是哪個元素
      let diffItem = {}
      this.lastTimeSelect.forEach(item => {
        let flag = false;
        selectItems.forEach(item2 => {
          if(item.id === item2.id){
            flag = true
          }
        })
        if(!flag){
          diffItem = item
          console.log("diff=", item)
        }
      })
      //找出被刪除的元素在 selectList 中的位置
      let list = this.data.selectList
      let delIndex = 0;
      for(let i=0; i<list.length; i++){
        if (list[i].id === diffItem.id){
          delIndex = i;
          break;
        }
      }
      //從list中刪除這個元素
      list.splice(delIndex, 1)
      this.setData({
        selectList: list
      })
    }
    console.log("selectList", this.data.selectList)
    //更新 currentList 選中狀態(tài)并重新掛載在數(shù)據(jù)樹上,以保存選擇狀態(tài)
    this.updateCurrentList(this.data.currentList, this.data.selectList)
  },

  //footer點擊刪除回調(diào)
  footerDelete(res){
    console.log(res)
    this.setData({
      selectList: res.detail.selectList
    })

    console.log('selectList', this.data.selectList)
    this.updateCurrentList(this.data.currentList, res.detail.selectList)
  },

  //點擊 footer 的確定按鈕提交數(shù)據(jù)
  submitData(res){
    let selectList = this.data.selectList
    //通過 WxNotificationCenter 發(fā)送選擇的結(jié)果通知
    EventBus.postNotificationName("SelectPeopleDone", selectList)
    //將選擇結(jié)果存入 app.js 的 globalData
    getApp().globalData.selectPeopleList = selectList
    //返回
    wx.navigateBack({
      delta: 1
    })
    console.log("selectdone", selectList)
  },

  //更新 currentList 并將更新后的列表掛載在數(shù)據(jù)樹上
  updateCurrentList(currentList, selectList){
    let newList = []
    currentList.forEach(item => {
      let flag = false;
      selectList.forEach(item2 => {
        if (item.id === item2.id) {
          flag = true
        }
      })
      if (flag) {
        item.checked = true
      } else {
        item.checked = false
      }
      newList.push(item)
    })
    this.setData({
      currentList: newList
    })
    this.addList2DataTree()
    this.setLastTimeSelectList()
  }
})
復(fù)制代碼

userSelect.wxml

<view class='container'>
  <view class='btn-wrapper'>
    <button bindtap='goBack'>返回上一層</button>
  </view>

  <view class='people-wrapper'>
    <scroll-view scroll-y class='scrollview'>
      <checkbox-group bindchange="checkChange">
        <view class='item' wx:for='{{currentList}}' wx:key='{{item.id}}'>
          <checkbox checked='{{item.checked}}' value='{{item.id + "," + item.name}}'>
          </checkbox>
          <view id='{{index}}' class='item-content' bindtap='clickItem'>
            <image class='img' wx:if='{{!item.isPeople}}' src='../../../assets/file.png'></image>
            <image class='avatar' wx:if='{{item.isPeople}}' src='../../../assets/avatar.png'></image>
            <text class='itemtext'>{{item.name}}</text>
          </view>
        </view>
      </checkbox-group>
      <view class='no-data' wx:if='{{currentList.length===0}}'>暫無數(shù)據(jù)</view>
    </scroll-view>
  </view>
  <view class='footer'>
    <footer list='{{selectList}}' binddelete='footerDelete' bindsubmit="submitData"/>
  </view>
</view>
復(fù)制代碼
userSelect.wxss

.container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 20rpx;
  overflow-x: hidden;
  box-sizing: border-box;
  background-color: #fff;
}

.btn-wrapper {
  width: 100%;
  padding: 0 20rpx;
  box-sizing: border-box;
}

.btn {
  font-size: 24rpx;
  width: 100%;
}

.people-wrapper {
  width: 100%;
  margin-top: 10rpx;
  margin-bottom: 100rpx;
}

.scrollview {
  width: 100%;
  display: flex;
  flex-direction: column;
}

.item {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 30rpx 0;
  margin: 0 20rpx;
  border-bottom: 1rpx solid rgba(7, 17, 27, 0.1);
}

.item-content {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-left: 20rpx;
}

.itemtext {
  font-size: 36rpx;
  color: #333;
  margin-left: 20rpx;
  text-align: center;
}

.img {
  width: 50rpx;
  height: 40rpx;
}

.avatar {
  width: 50rpx;
  height: 50rpx;
}

.footer {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
}

.no-data{
  width: 100%;
  font-size: 32rpx;
  text-align: center;
  padding: 40rpx 0;
}

userSelect.json

{
  "usingComponents": {
    "footer": "footer/footer"
  }
}

footer 的代碼

footer.js


Component({
  /**
   * 組件的屬性列表
   */
  properties: {
    list: {
      type: Array
    }
  },

  /**
   * 組件的初始數(shù)據(jù)
   */
  data: {
    
  },

  /**
   * 組件的方法列表
   */
  methods: {
    delete(res){
      console.log(res)
      let index = res.currentTarget.id
      let list = this.data.list
      list.splice(index,1)
      this.setData({list: list})
      this.triggerEvent("delete", {selectList: list})
    },

    /**
     * 點擊確定按鈕
     */
    confirm(){
      this.triggerEvent("submit", "")
    }
  }
})
復(fù)制代碼

footer.wxml

<view class='container'>
  <view class='scroll-wrapper'>
    <scroll-view scroll-x style='scroll'>
      <text id='{{index}}' class='text' wx:for='{{list}}' wx:key='{{index}}' bindtap='delete'>{{item.name}}</text>
    </scroll-view>
  </view>
  <text class='btn' bindtap='confirm'>確定</text>
</view>

footer.wxss

.container {
  width: 100%;
  height: 100rpx;
  display: flex;
  flex-direction: row;
  padding: 20rpx;
  box-sizing: border-box;
  background-color: #fff;
  align-items: center;
  overflow-x: hidden;
  white-space: nowrap;
  border-top: 2rpx solid rgba(7, 17, 27, 0.1)
}

.scroll-wrapper {
  flex: 1;
  overflow-x: hidden;
  white-space: nowrap;
}

.scroll {
  width: 100%;

}

.text {
  font-size: 32rpx;
  color: #333;
  padding: 40rpx 20rpx;
  margin-right: 10rpx;
  background-color: #f5f5f5;
}

.btn {
  padding: 10rpx 20rpx;
  background-color: rgb(26, 173, 25);
  border-radius: 10rpx;
  font-size: 32rpx;
  color: #fff;
}
復(fù)制代碼

footer.json

{
  "component": true,
  "usingComponents": {}
}
復(fù)制代碼

再補(bǔ)一個用到的 ArrayUtils 的代碼

export default{

  /**
     * 給數(shù)組去重
     */
  checkRepeat(list) {
    let noRepList = [list[0]]
    for (let i = 0; i < list.length; i++) {
      let repeat = false
      for (let j = 0; j < noRepList.length; j++) {
        if (noRepList[j].id === list[i].id) {
          repeat = true
          break
        }
      }
      if (!repeat) {
        noRepList.push(list[i])
      }
    }
    return noRepList
  },

  //刪除list中id為 delId 的元素
  deleteItemById(list, delId){
    for (let i = 0; i < list.length; i++) {
      if (list[i].id == delId) {
        list.splice(i, 1)
        return list;
      }
    }
    return list;
  }

}
復(fù)制代碼

由于時間緊張,還沒有把這個控件單獨從項目中抽出來寫個 Demo,有時間了會給 github 地址的。

代碼還有很多可以優(yōu)化的地方,比如有幾個方法太長了,不符合單一職責(zé)原則等等,不想改了,以后再優(yōu)化吧。。

水平有限,各位大俠請輕噴~

有問題或發(fā)現(xiàn) Bug 請在評論區(qū)留言,畢竟剛寫完就分享出來了,還沒經(jīng)過嚴(yán)格的測試。不過應(yīng)該沒什么大的問題。。。有些細(xì)節(jié)可能沒注意到。



易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://u-renovate.com/wxmini/doc/course/24921.html 復(fù)制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢