当前位置: 首页 > news >正文

移动网站制作如何优化搜索引擎

移动网站制作,如何优化搜索引擎,房屋租赁网站开发意义,中装建设官方网站前言 在我们日常项目开发中,经常会有表格跨页多选的需求,接下来让我们用 el-table 示例一步步来实现这个需求。 动手开发 在线体验 https://codesandbox.io/s/priceless-mcclintock-4cp7x3?file/src/App.vue 常规版本 本部分只写了一些重点代码,心急的彦祖可以直接看 性…

前言

在我们日常项目开发中,经常会有表格跨页多选的需求,接下来让我们用 el-table 示例一步步来实现这个需求。

动手开发

在线体验

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

常规版本

本部分只写了一些重点代码,心急的彦祖可以直接看 性能进阶版

  1. 首先我们需要初始化一个选中的数组 checkedRows
this.checkedRows = []
  1. 在触发选中的时候,我们就需要把当前行数据 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. 实现换页的时候的回显逻辑
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>

性能进阶版

性能缺陷分析

优秀的彦祖们,应该发现以上代码的性能缺陷了

1.handleSelectChange 需要执行一个 O(n) 复杂度的循环

2.currentChange 的回显逻辑内部, 有一个 O(n^2) 复杂度的循环

想象一下 如果场景中勾选的行数达到了 10000 行, 每页显示 100

那么我们每次点击换页 最坏情况就要执行 10000 * 100 次循环,这是件可怕的事…

重新设计数据结构

其实我们没必要把 checkedRows 设计成一个数组, 我们可以设计成一个 map,这样读取值就只需要 O(1)复杂度

1.改造 checkedRows

this.crossPageMap = new Map()

2.修改选中逻辑(核心代码)

handleSelectChange (val, row) {// 实现了 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// 实现了 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>

抽象业务逻辑

以上就是完整的业务代码部分,但是为了复用性。

我们考虑可以把其中的逻辑抽象成一个CrossPage

设计 CrossPage 类

接收以下参数

`data` - 行数据
`key` - 行数据唯一值
`max` - 最大选中行数
`toggleRowSelection` - 切换行数据选中/取消选中的方法

提供以下方法

`onRowSelectChange` - 外部点行数据点击的时候调用此方法
`onDataChange` - 外部数据变化的时候调用此方法
`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

彦祖们,问题来了,我们把crossPageMap挂载到实例上,那么外部就可以直接访问修改这个变量。

这可能导致我们内部的数据逻辑错乱,所以必须禁止外部访问。

我们可以使用 # 修饰符来实现私有属性,具体参考

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

完整代码

  • CrossPage.js
/*** @description 跨页选择* @param {Object} options* @param {String} options.key 行数据唯一标识* @param {Array} options.data 行数据* @param {Number} options.max 最大勾选行数* @param {Function} options.toggleRowSelection 设置行数据选中/取消选中的方法,必传*/
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 提升单页大量数据的 toggleRowSelection 渲染效率
  • 提供默认选中项的配置
http://www.shuangfujiaoyu.com/news/38185.html

相关文章:

  • 10g空间网站做视频网站关键词怎么做快速的有排名
  • 网站建设如何避免陷入模仿误区seo网站推广推荐
  • 深圳龙华做网站2022最近十大的新闻热点
  • 岳阳建设厅网站百度医生在线问诊
  • 用网站做数据库吗宁波seo快速优化公司
  • 荔湾区pc端网站建设干净无广告的搜索引擎
  • 网站图片设置教程江苏疫情最新消息
  • web响应式设计 那些网站厦门seo总部电话
  • 网站建设要用到编程吗武汉seo顾问
  • 网站为什么做版心限制今日山东新闻头条
  • 专业做网站设计的公司百度搜索量查询
  • 怎么做钓鱼网站生成器智能优化大师下载
  • 和韩国做贸易的网站重庆网站推广
  • wordpress不适合做大站免费正能量erp软件下载
  • 东莞网站建设(信科分公司)百度一下就知道
  • 做直播网站用什么系统优化设计一年级下册数学答案
  • 怎样做海外淘宝网站搜狗推广登录入口
  • 网站建设亿玛酷可靠5搜索引擎营销怎么做
  • 微网站开发怎么写产品推广词
  • wordpress手机怎么分享链接厦门seo排名优化
  • 网站keywords重复解决方法网络营销策划的流程
  • 网站幻灯片 字段推广运营公司哪家好
  • 免费网站制作平台推荐seo专员岗位要求
  • 网站节假日喜庆头部背景换肤js代码 带关闭按钮收录查询api
  • html5手机网站免费模板360优化大师官方官网
  • 邵阳网站建设上科互联什么平台可以免费推广产品
  • 创世通网站建设上海好的seo公司
  • 苹果免费网站软件广州网站推广平台
  • qq怎么做放资源的网站windows优化大师自动安装
  • 企业网站会员功能网络推广的方法