写在最前
需求:有个表格列出了一些行数据,每个行数据点击后会加载出对应的详细数据,想要在点击了某一行后,能够将该点击反应到URL中,这样我复制这个URL发给其他人,他们打开时也能看到同样的行数据。
url会根据点击动态更新,大概是这样 xxx.com?param1=var1¶m2=var2
主要版本:vue3,element-plus 2.3 (element-plus版本2.0就不行,已踩坑issue)
实现
URL参数的动态更新与访问加载
下面封装了更新URL参数和获取URL参数的方法
// 更新URL参数
function updateURLWithParams(paramsObj: any) {
// 入参检查
if (typeof paramsObj !== 'object' || paramsObj === null) {
console.error('Invalid input. params must be an object.');
return;
}
// 获取当前URL
const url = new URL(window.location.href);
// 创建基于当前URL的不含参数的URL对象
const newUrl = new URL(url.origin + url.pathname);
// 创建新的URLSearchParams
const params = new URLSearchParams();
// 添加搜索参数
for (const key in paramsObj) {
params.set(key, paramsObj[key]);
}
// 更新到新URL对象
newUrl.search = params.toString();
// 更新到浏览器history(地址栏改变)
window.history.pushState('', '', newUrl.toString());
}
// 获取URL参数
function getQueryParamsFromURL() {
const urlObj = new URL(window.location.href);
const queryParams = urlObj.searchParams;
const params: { [key: string]: string } = {};
for (const [key, value] of queryParams.entries()) {
params[key] = value;
}
return params;
}
然后在监听点击行数据的方法中调用即可。
handleRowClick(row: any, event: any, column: any) {
// 加载数据的code...
// 更新参数到URL,这里假设把row的id放到参数里面
updateURLWithParams({ "row_id": row.id});
},
在初始化页面后,需要根据URL中参数加载出对应的行数据。对应的代码如下:
created() {
// 从URL中拿到搜索参数
const row_id = getQueryParamsFromURL()["row_id"];
// 如果参数不为空,遍历表格数据找到对应的行
if (!!row_id) {
// tableData是el-table绑定的表格数据,tableRef是绑定的引用对象
// <el-table :data="tableData" ref="tableRef">
for (let index = 0; index < this.tableData.length; index++) {
if (this.tableData[index].id==row_id) {
// 设置表格当前行为参数中指定的行,如果表格设置了高亮,则同时会高亮当前行
this.$refs.tableRef.setCurrentRow(this.tableData[index]);
// 然后可以加载对应的行数据
// coding...
break;
}
}
}
至此已经实现了,点击行数据更新URL参数,访问带参的URL会选中指定的行并加载对应数据。
但是如果表格数据过多,有滚动条了,这时候还不能自动滚动到当前选中的行。
所以需要手动实现。
获取选中行的偏移高度并滚动到该处
el-table提供了滚动到指定位置的方法,但是需要输入坐标或者偏移量。
Table 表格 | Element Plus (element-plus.org)
这里使用setScrollTop方法,所以我们需要获取当前已选中行的偏移高度并设置为滚动位置,代码如下:
// 获取偏移高度, tableRef是table的引用对象,index是行的索引
const offsetTop = this.$refs.tableRef.$el.getElementsByClassName('el-table__row')[index].offsetTop;
// 设置滚动位置
this.$refs.tableRef.setScrollTop(offsetTop);
结合上面找到并选中参数中指定行的代码,最终实现如下:
created() {
// 从URL中拿到搜索参数
const row_id = getQueryParamsFromURL()["row_id"];
// 如果参数不为空,遍历表格数据找到对应的行
if (!!row_id) {
// tableData是el-table绑定的表格数据,tableRef是绑定的引用对象
// <el-table :data="tableData" ref="tableRef">
for (let index = 0; index < this.tableData.length; index++) {
if (this.tableData[index].id==row_id) {
// 设置表格当前行为参数中指定的行,如果表格设置了高亮,则同时会高亮当前行
this.$refs.tableRef.setCurrentRow(this.tableData[index]);
// 获取偏移高度, tableRef是table的引用对象,index是行的索引
const offsetTop = this.$refs.tableRef.$el.getElementsByClassName('el-table__row') [index].offsetTop;
// 设置滚动位置
this.$refs.tableRef.setScrollTop(offsetTop);
// 然后可以加载对应的行数据
// coding...
break;
}
}
}
总结
element-plus虽然很方便,但有时候不能直接满足需求,需要多查资料多摸索。另外本人不是专业前端,这里只是记录了一次有趣的解决问题的过程,如果有更优雅的解决方案,欢迎分享噢。