07_el-table 拖动改变列的展示顺序 _ 前端实现
1、动态渲染el-table
<template>
<div>
<!-- 表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column type="index" label="序号" width="50" align="center" />
<el-table-column v-for="(column, index) in columnsOrder" :custom="column.custom" :key="index"
:label="column.label" :width="column.width" :align="column.align" :prop="column.prop">
<template v-if="column.slotName" slot-scope="scope">
<el-tooltip effect="dark" :content="String(scope.row[column.prop])" placement="top">
<span :class="{ 'ellipsis-text': true, 'no-wrap': column.width && column.width !== 'auto' }"
style="display: block; overflow: hidden;">
{{ scope.row[column.prop] }}
</span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</div>
</template>
2、拖拽标题的模块(需要借助第三方工具 vuedraggable )
2.1 下载 vuedraggable
npm install vuedraggable
2.2 引入 vuedraggable
<script>
import draggable from 'vuedraggable';
export default {
components: { draggable },
}
</script>
2.3 列标题拖拽模块
<template>
<div>
<!-- 列标题拖拽 -->
<el-dropdown trigger="click" style="margin-bottom: 10px;">
<el-button size="mini">
列排序<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<draggable v-model="columnsOrder" tag="div" @end="onColumnDrop($event)">
<div v-for="column in columnsOrder" :key="column.prop">
{{ column.label }}
</div>
</draggable>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
3、拖拽的逻辑
data() {
return {
// 表格数据 可以从后端读取,这里仅作为演示
tableData: [
{ name: "张三", age: "18", address: '河北省石家庄市长安区xxx路xxx小区' },
{ name: "李四", age: "28", address: '北京市朝阳区110号楼110单元110室' }
],
columnsOrder: [],
}
},
methods: {
// 表格列拖拽
onColumnDrop(event) {
const { item, newIndex } = event;
if (newIndex !== undefined && newIndex !== null && newIndex >= 0 && newIndex < this.columnsOrder.length) {
localStorage.setItem('ColumnsOrder', JSON.stringify(this.columnsOrder));
}
},
}
这样拖拽以后,会自动将拖拽以后 得到的数据 存储到 localStorage,每次进入页面可以随时调取浏览器的缓存,实现 用户可以自定义列的排列顺序 的偏好设置
localStorage 和 sessionStorage的区别
localStorage 和 sessionStorage 都是Web存储API的一部分,用于在客户端(即用户的浏览器)存储数据。尽管
它们有相似之处,但也存在关键区别:生命周期:
localStorage: 数据具有持久性,除非用户手动清除浏览器数据或者通过JavaScript调用删除方法,否则数据会一直>存在,即使关闭浏览器或重启电脑。
sessionStorage: 数据仅在当前浏览器窗口或标签页的会话期间有效。一旦用户关闭了浏览器窗口或标签页,数据就>会被清除。刷新页面不会删除sessionStorage中的数据。
作用域:localStorage: 数据在同源策略下共享,意味着同一域名下的所有页面都可以访问到相同的localStorage数据。
sessionStorage: 同样遵循同源策略,但是它的数据存储是基于每个浏览器窗口或标签页独立的,也就是说,每个窗>口或标签页都有自己的sessionStorage实例,它们之间不共享数据。
存储容量:两者都受限于浏览器的存储空间限制,通常情况下这个限制大约是5MB,但具体大小可能因浏览器而异。
应用场景:localStorage 适合存储那些不敏感的、需要长期保留的信息,比如用户偏好设置。
sessionStorage 适用于存储敏感的短期信息,如用户登录状态、临时购物车等,这些信息不需要长期保留,并且在
会话结束后应该被清除。
综上所述,选择使用localStorage还是sessionStorage主要取决于数据的敏感性和持久性需求。
4、进入页面调取浏览器的缓存
created() {
//进入页面调用
this.tableOrderAssignment()
},
methods: {
tableOrderAssignment() {
// 获取localStorage中的值
const columnsOrderExists = localStorage.getItem('entertainColumnsOrder') !== null;
// 判断是否存在
// 如果存在,则证明用户设置过 那么直接调取就行
// 如果没有设置过 ,说明是 首次进入页面,那么就需要我们将默认的展示顺序以及数据给到 用户
if (!columnsOrderExists) {
this.columnsOrder = [
{ prop: 'name', label: '姓名', width: '120', align: 'center', slotName: true },
{ prop: 'age', label: '年龄', width: '130', align: 'center', slotName: true },
]
} else {
this.columnsOrder = JSON.parse(localStorage.getItem('ColumnsOrder'))
}
},
}
5、整体代码
<template>
<div>
<!-- 列标题拖拽 -->
<el-dropdown trigger="click" style="margin-bottom: 10px;">
<el-button size="mini">
列排序<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<draggable v-model="columnsOrder" tag="div" @end="onColumnDrop($event)">
<div v-for="column in columnsOrder" :key="column.prop">
{{ column.label }}
</div>
</draggable>
</el-dropdown-menu>
</el-dropdown>
<!-- 表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column type="index" label="序号" width="50" align="center" />
<el-table-column v-for="(column, index) in columnsOrder" :custom="column.custom" :key="index"
:label="column.label" :width="column.width" :align="column.align" :prop="column.prop">
<template v-if="column.slotName" slot-scope="scope">
<el-tooltip effect="dark" :content="String(scope.row[column.prop])" placement="top">
<span :class="{ 'ellipsis-text': true, 'no-wrap': column.width && column.width !== 'auto' }"
style="display: block; overflow: hidden;">
{{ scope.row[column.prop] }}
</span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import draggable from 'vuedraggable';
export default {
components: { draggable },
data() {
return {
// 表格数据 可以从后端读取,这里仅作为演示
tableData: [
{ name: "张三", age: "18", address: '河北省石家庄市长安区xxx路xxx小区' },
{ name: "李四", age: "28", address: '北京市朝阳区110号楼110单元110室' }
],
columnsOrder: [],
}
},
created() {
this.tableOrderAssignment()
},
methods: {
// 表格列拖拽
onColumnDrop(event) {
const { item, newIndex } = event;
if (newIndex !== undefined && newIndex !== null && newIndex >= 0 && newIndex < this.columnsOrder.length) {
localStorage.setItem('entertainColumnsOrder', JSON.stringify(this.columnsOrder));
}
},
tableOrderAssignment() {
// 获取localStorage中的值
const columnsOrderExists = localStorage.getItem('entertainColumnsOrder') !== null;
// 判断是否存在
// 如果存在,则证明用户设置过 那么直接调取就行
// 如果没有设置过 ,说明是 首次进入页面,那么就需要我们将默认的展示顺序以及数据给到 用户
if (!columnsOrderExists) {
this.columnsOrder = [
{ prop: 'name', label: '姓名', width: '500', align: 'center', slotName: true },
{ prop: 'age', label: '年龄', width: '500', align: 'center', slotName: true },
{ prop: 'address', label: '地址', width: '500', align: 'center', slotName: true },
]
} else {
this.columnsOrder = JSON.parse(localStorage.getItem('ColumnsOrder'))
}
},
}
}
</script>
<style>
.el-dropdown-menu {
padding: 10px;
cursor: pointer;
}
</style>