中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

網(wǎng)易云外鏈wordpressseo服務商

網(wǎng)易云外鏈wordpress,seo服務商,可信賴的商城網(wǎng)站建設,安康市網(wǎng)站建設公司前言 在我們日常項目開發(fā)中,經(jīng)常會有表格跨頁多選的需求,接下來讓我們用 el-table 示例一步步來實現(xiàn)這個需求。 動手開發(fā) 在線體驗 https://codesandbox.io/s/priceless-mcclintock-4cp7x3?file/src/App.vue 常規(guī)版本 本部分只寫了一些重點代碼,心急的彥祖可以直接看 性…

前言

在我們日常項目開發(fā)中,經(jīng)常會有表格跨頁多選的需求,接下來讓我們用 el-table 示例一步步來實現(xiàn)這個需求。

動手開發(fā)

在線體驗

https://codesandbox.io/s/priceless-mcclintock-4cp7x3?file=/src/App.vue

常規(guī)版本

本部分只寫了一些重點代碼,心急的彥祖可以直接看 性能進階版

  1. 首先我們需要初始化一個選中的數(shù)組 checkedRows
this.checkedRows = []
  1. 在觸發(fā)選中的時候,我們就需要把當前行數(shù)據(jù) pushcheckedRows,否則就需要剔除對應行
<el-table ref="multipleTable" @select="handleSelectChange">
handleSelectChange (val, row) {const checkedIndex = this.checkedRows.findIndex(_row => _row.id === row.id)if (checkedIndex > -1) {// 選中剔除this.checkedRows.splice(checkedIndex, 1)} else {// 未選中壓入this.checkedRows.push(row)}
}
  1. 實現(xiàn)換頁的時候的回顯邏輯
this.data.forEach(row=>{const checkedIndex = this.checkedRows.findIndex(_row => _row.id === row.id)if(checkedIndex>-1) this.$refs.multipleTable.toggleRowSelection(row,true)
})

效果預覽

讓我們看下此時的效果

2023-08-08 20.03.52.gif

完整代碼

<template><div><el-tableref="multipleTable":data="tableData"tooltip-effect="dark"style="width: 100%"@select="handleSelectChange"@select-all="handleSelectAllChange"><el-table-columntype="selection"width="55"/><el-table-columnlabel="日期"width="120"prop="date"/><el-table-columnprop="name"label="姓名"width="120"/></el-table><el-paginationbackground:current-page.sync="currentPage"layout="prev, pager, next":total="1000"@current-change="currentChange"/></div>
</template><script>
export default {data () {return {currentPage: 1,checkedRows: [],pageSize: 10,totalData: Array.from({ length: 1000 }, (_, index) => {return {date: '2016-05-03',id: index,name: '王小虎' + index}})}},computed: {tableData () {const { currentPage, totalData, pageSize } = thisreturn totalData.slice((currentPage - 1) * pageSize, currentPage * pageSize)}},methods: {currentChange (page) {this.currentPage = pagethis.tableData.forEach(row => {const checkedIndex = this.checkedRows.findIndex(_row => _row.id === row.id)if (checkedIndex > -1) this.$refs.multipleTable.toggleRowSelection(row, true)})},handleSelectChange (val, row) {const checkedIndex = this.checkedRows.findIndex(_row => _row.id === row.id)if (checkedIndex > -1) {this.checkedRows.splice(checkedIndex, 1)} else {this.checkedRows.push(row)}},handleSelectAllChange (val) {this.tableData.forEach(row => {this.handleSelectChange(null, row)})}}
}
</script>

性能進階版

性能缺陷分析

優(yōu)秀的彥祖?zhèn)?應該發(fā)現(xiàn)以上代碼的性能缺陷了

1.handleSelectChange 需要執(zhí)行一個 O(n) 復雜度的循環(huán)

2.currentChange 的回顯邏輯內部, 有一個 O(n^2) 復雜度的循環(huán)

想象一下 如果場景中勾選的行數(shù)達到了 10000 行, 每頁顯示 100

那么我們每次點擊換頁 最壞情況就要執(zhí)行 10000 * 100 次循環(huán),這是件可怕的事…

重新設計數(shù)據(jù)結構

其實我們沒必要把 checkedRows 設計成一個數(shù)組, 我們可以設計成一個 map,這樣讀取值就只需要 O(1)復雜度

1.改造 checkedRows

this.crossPageMap = new Map()

2.修改選中邏輯(核心代碼)

handleSelectChange (val, row) {// 實現(xiàn)了 O(n) 到 O(1) 的提升const checked = this.crossPageMap.has(row.id)if (checked) {this.crossPageMap.delete(row.id)} else {this.crossPageMap.set(row.id, row)}
}

3.修改換頁回顯邏輯

currentChange (page) {this.currentPage = page// 實現(xiàn)了 O(n^2) 到 O(n) 的提升this.tableData.forEach(row => {const checked = this.crossPageMap.has(row.id)if (checked) this.$refs.multipleTable.toggleRowSelection(row, true)})
}

完整代碼

<template><div><el-tableref="multipleTable":data="tableData"tooltip-effect="dark"style="width: 100%;height:500px"@select="handleSelectChange"@select-all="handleSelectAllChange"><el-table-columntype="selection"width="55"/><el-table-columnlabel="日期"width="120"prop="date"/><el-table-columnprop="name"label="姓名"width="120"/></el-table><el-paginationbackground:current-page.sync="currentPage"layout="prev, pager, next":total="1000"@current-change="currentChange"/></div>
</template><script>
export default {data () {return {currentPage: 1,crossPageMap: new Map(),pageSize: 10,totalData: Array.from({ length: 1000 }, (_, index) => {return {date: '2016-05-03',id: index,name: '王小虎' + index}})}},computed: {tableData () {const { currentPage, totalData, pageSize } = thisreturn totalData.slice((currentPage - 1) * pageSize, currentPage * pageSize)}},methods: {currentChange (page) {this.currentPage = pagethis.tableData.forEach(row => {const checked = this.crossPageMap.has(row.id)if (checked) this.$refs.multipleTable.toggleRowSelection(row, true)})},handleSelectChange (val, row) {const checked = this.crossPageMap.has(row.id)if (checked) {this.crossPageMap.delete(row.id)} else {this.crossPageMap.set(row.id, row)}},handleSelectAllChange (val) {this.tableData.forEach(row => {this.handleSelectChange(null, row)})}}
}
</script>

抽象業(yè)務邏輯

以上就是完整的業(yè)務代碼部分,但是為了復用性。

我們考慮可以把其中的邏輯抽象成一個CrossPage

設計 CrossPage 類

接收以下參數(shù)

`data` - 行數(shù)據(jù)
`key` - 行數(shù)據(jù)唯一值
`max` - 最大選中行數(shù)
`toggleRowSelection` - 切換行數(shù)據(jù)選中/取消選中的方法

提供以下方法

`onRowSelectChange` - 外部點行數(shù)據(jù)點擊的時候調用此方法
`onDataChange` - 外部數(shù)據(jù)變化的時候調用此方法
`clear` - 清空所有選中行

構造器大致代碼 如下

constructor (options={}) {this.crossPageMap = new Map()this.key = options.key || 'id'this.data = options.data || []this.max = options.max || Number.MAX_SAFE_INTEGERthis.toggleRowSelection = options.toggleRowSelectionif(typeof this.toggleRowSelection !== 'function') throw new Error('toggleRowSelection is not function')
}

設置私有crossPageMap

彥祖?zhèn)?問題來了,我們把crossPageMap掛載到實例上,那么外部就可以直接訪問修改這個變量。

這可能導致我們內部的數(shù)據(jù)邏輯錯亂,所以必須禁止外部訪問。

我們可以使用 # 修飾符來實現(xiàn)私有屬性,具體參考

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes/Private_class_fields

完整代碼

  • CrossPage.js
/*** @description 跨頁選擇* @param {Object} options* @param {String} options.key 行數(shù)據(jù)唯一標識* @param {Array} options.data 行數(shù)據(jù)* @param {Number} options.max 最大勾選行數(shù)* @param {Function} options.toggleRowSelection 設置行數(shù)據(jù)選中/取消選中的方法,必傳*/
export const CrossPage = class {#crossPageMap = new Map();constructor (options={}) {this.key = options.key || 'id'this.data = options.data || []this.max = options.max || Number.MAX_SAFE_INTEGERthis.toggleRowSelection = options.toggleRowSelectionif(typeof this.toggleRowSelection !== 'function') throw new Error('toggleRowSelection is not function')}get keys(){return Array.from(this.#crossPageMap.keys())}get values(){return Array.from(this.#crossPageMap.values())}get size(){return this.#crossPageMap.size}clear(){this.#crossPageMap.clear()this.updateViews()}onRowSelectChange (row) {if(typeof row !== 'object') return console.error('row is not object')const {key,toggleRowSelection} = thisconst checked = this.#crossPageMap.has(row[key])if(checked) this.#crossPageMap.delete(row[key])else {this.#crossPageMap.set(row[key],row)if(this.size>this.max){this.#crossPageMap.delete(row[key])toggleRowSelection(row,false)}}}onDataChange(list){this.data = listthis.updateViews()}updateViews(){const {data,toggleRowSelection,key} = thisdata.forEach(row=>{toggleRowSelection(row,this.#crossPageMap.has(row[key]))})}
}
  • crossPage.vue
<template><div><el-tableref="multipleTable":data="tableData"tooltip-effect="dark"style="width: 100%"@select="handleSelectChange"@select-all="handleSelectAllChange"><el-table-columntype="selection"width="55"/><el-table-columnlabel="日期"width="120"prop="date"/><el-table-columnprop="name"label="姓名"width="120"/></el-table><el-button @click="clear">清空</el-button><el-button @click="keys">獲取 keys</el-button><el-button @click="values">獲取 values</el-button><el-paginationbackground:current-page.sync="currentPage"layout="prev, pager, next":total="1000"@current-change="currentChange"/></div>
</template><script>
import { CrossPage } from './CrossPage'
export default {data () {return {currentPage: 1,pageSize: 10,totalData: Array.from({ length: 1000 }, (_, index) => {return {date: '2016-05-03',id: index,name: '王小虎' + index}}),multipleSelection: []}},computed: {tableData () {const { currentPage, totalData, pageSize } = thisreturn totalData.slice((currentPage - 1) * pageSize, currentPage * pageSize)}},mounted () {this.crossPageIns = new CrossPage({key: 'id',max: 2,data: this.tableData,toggleRowSelection: this.$refs.multipleTable.toggleRowSelection})},methods: {clear () {this.crossPageIns.clear()},keys () {console.log('keys:', this.crossPageIns.keys)},values () {console.log('values:', this.crossPageIns.values)},currentChange (page) {this.currentPage = page// 調用實例 onDataChange 方法this.crossPageIns.onDataChange(this.tableData)},handleSelectChange (val, row) {// 調用實例 onRowSelectChange 方法this.crossPageIns.onRowSelectChange(row)},handleSelectAllChange (val) {this.tableData.forEach(row => {this.crossPageIns.onRowSelectChange(row)})}}
}
</script>

寫在最后

未來想做的還有很多

  • 利用requestIdleCallback 提升單頁大量數(shù)據(jù)的 toggleRowSelection 渲染效率
  • 提供默認選中項的配置
http://www.risenshineclean.com/news/1240.html

相關文章:

  • 新手做市場分析的網(wǎng)站抖音信息流廣告怎么投放
  • 不用淘寶客api如何做網(wǎng)站網(wǎng)站制作 網(wǎng)站建設
  • 銀川做企業(yè)網(wǎng)站合肥seo報價
  • 重慶網(wǎng)站建設設計網(wǎng)絡營銷十大成功案例
  • 娛樂網(wǎng)站開發(fā)福州外包seo公司
  • 榮耀手機商城官方網(wǎng)站入口西安seo排名外包
  • 蘇州網(wǎng)站建設的一般流程職業(yè)技能培訓網(wǎng)
  • 哪家做網(wǎng)站靠譜企業(yè)營銷策劃
  • 福清網(wǎng)站建設百度收錄批量提交入口
  • 海門做網(wǎng)站自動優(yōu)化句子的軟件
  • 數(shù)據(jù)分析師簡歷襄陽網(wǎng)站推廣優(yōu)化技巧
  • 北京住房城鄉(xiāng)建設部網(wǎng)站八大員千萬不要去電商公司上班
  • 可以在哪些網(wǎng)站做翻譯兼職建立企業(yè)網(wǎng)站步驟
  • 天津平臺網(wǎng)站建設推薦廣告營銷平臺
  • 成都旅游景點攻略自由行攻略關鍵詞優(yōu)化seo公司
  • 西安微網(wǎng)站建設百度一下 你就知道官網(wǎng)
  • 網(wǎng)站開發(fā)需要考什么證網(wǎng)絡營銷渠道有哪三類
  • 南陽做網(wǎng)站的公怎樣進行網(wǎng)絡營銷吸引顧客
  • 商標被注冊了做網(wǎng)站國外網(wǎng)站推廣公司
  • 建筑工程外架安全網(wǎng)西安的網(wǎng)絡優(yōu)化公司
  • 做算法題的 網(wǎng)站成品網(wǎng)站貨源1
  • 網(wǎng)站建設策劃實訓總結友情鏈接怎么連
  • 遵義新藍外國語學校網(wǎng)站建設臺州seo優(yōu)化
  • 郴州北湖區(qū)疫情最新消息網(wǎng)站優(yōu)化
  • 建設企業(yè)網(wǎng)站進去無法顯示怎么在百度上免費做廣告
  • 如何通過做網(wǎng)站月入上萬廣州seo公司品牌
  • 溫州建設網(wǎng)站百度上??偛?/a>
  • 天津企商網(wǎng)站建設公司關鍵詞優(yōu)化按天計費
  • 網(wǎng)站如何做銀聯(lián)在線支付大連中小企業(yè)網(wǎng)絡營銷
  • 一般做外貿(mào)上什么網(wǎng)站熱狗網(wǎng)站排名優(yōu)化外包