1.新建 scroll-to.js文件 代码如下
Math.easeInOutQuad = function (t, b, c, d) {
t /= d / 2;
if (t < 1) {
return (c / 2) * t * t + b;
}
t--;
return (-c / 2) * (t * (t - 2) - 1) + b;
};
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
let requestAnimFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
}
);
})();
/**
* Because it's so fucking difficult to detect the scrolling element, just move them all
* @param {number} amount
*/
function move(amount) {
document.documentElement.scrollTop = amount;
document.body.parentNode.scrollTop = amount;
document.body.scrollTop = amount;
}
function position() {
return (
document.documentElement.scrollTop ||
document.body.parentNode.scrollTop ||
document.body.scrollTop
);
}
/**
* @param {number} to
* @param {number} duration
* @param {Function} callback
*/
export function scrollTo(to, duration, callback) {
const start = position();
const change = to - start;
const increment = 20;
let currentTime = 0;
duration = typeof duration === "undefined" ? 500 : duration;
let animateScroll = function () {
// increment the time
currentTime += increment;
// find the value with the quadratic in-out easing function
let val = Math.easeInOutQuad(currentTime, start, change, duration);
// move the document.body
move(val);
// do the animation unless its over
if (currentTime < duration) {
requestAnimFrame(animateScroll);
} else {
if (callback && typeof callback === "function") {
// the animation is done so lets callback
callback();
}
}
};
animateScroll();
}
2.pagination页面代码
<template>
<div :class="{ hidden: hidden }" class="pagination-container">
<el-pagination
:background="background"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script setup>
import { computed } from "vue";
import { scrollTo } from "@/utils/scroll-to";
const emit = defineEmits(["pagination", "update:page", "update:limit"]);
const props = defineProps({
total: {
required: true,
type: Number
},
page: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 10
},
pageSizes: {
type: Array,
default: () => [10, 20, 30, 40, 50, 60, 100, 200, 300, 400]
},
layout: {
type: String,
default: "total, sizes, prev, pager, next, jumper"
},
background: {
type: Boolean,
default: true
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
}
});
const currentPage = computed({
get() {
return props.page;
},
set(val) {
emit("update:page", val);
}
});
const pageSize = computed({
get() {
return props.limit;
},
set(val) {
emit("update:limit", val);
}
});
function handleSizeChange(val) {
// console.log("==", val);
if (currentPage.value * val > props.total) {
currentPage.value = 1;
}
// console.log("currentPage", currentPage.value);
emit("pagination", { page: currentPage.value, limit: val });
if (props.autoScroll) {
scrollTo(0, 800);
}
}
function handleCurrentChange(val) {
// console.log("==1==", val);
emit("pagination", { page: val, limit: pageSize.value });
if (props.autoScroll) {
scrollTo(0, 800);
}
}
</script>
<style scoped lang="less">
.pagination-container {
// background: #fff;
padding: 20px 16px 0 16px;
display: flex;
justify-content: flex-end;
}
:deep(.el-pagination .el-select .el-input) {
width: 100px;
}
:deep(.el-pagination button) {
width: 28px;
height: 28px;
}
:deep(.el-pager li) {
width: 28px;
height: 28px;
}
:deep(.el-input__wrapper) {
height: 28px;
}
</style>
3.table封装的页面
<template>
<section class="table-box">
<!-- :default-sort="{ prop: 'name', order: 'descending' }" -->
<el-table
:data="tableData"
:height="height"
border
ref="multipleTableRef"
@selection-change="handleSelectionChange"
:header-cell-style="{
background: '#F0F0F0',
color: '#333333',
fontSize: '15px',
height: '45px',
lineHeight: '45px',
borderColor: '#E4E4E4'
}"
:row-style="{ cursor: 'pointer' }"
@row-click="fnRowClick"
>
<!-- :header-cell-style="{
background: '#F6F6F6',
color: '#333333',
fontSize: '14px',
height: '45px',
lineHeight: '45px'
}" -->
<el-table-column fixed type="selection" width="55" v-if="selection" />
<el-table-column
fixed
type="index"
label="序号"
width="120"
v-if="serialNumber"
/>
<el-table-column
:prop="item.prop"
:sortable="item?.sortable ?? false"
:label="item.label"
:width="item.width"
v-for="(item, i) in tableTitle"
:key="i"
>
<template #default="scope">
<!-- 图片 -->
<img
v-if="item.sign === 'pic'"
class="pic"
:src="scope?.row[item?.prop] || tool.getUrl('noCompany.png')"
/>
<!-- 时间 -->
<span v-else-if="item.sign === 'timer'">{{
// HH:mm:ss
item.hasShow
? dayjs(scope.row[item.prop]).format("YYYY-MM")
: dayjs(scope.row[item.prop]).format("YYYY-MM-DD")
}}</span>
<!-- 里面有嵌套的对象取值 -->
<section v-else-if="item.sign === 'children'">
<!-- 是数组 -->
<section v-if="Array.isArray(scope.row[item.arrayName])">
<span v-for="(v, j) in scope.row[item.arrayName]" :key="j">
{{ v[item.childrenKey]
}}{{ j !== scope.row[item.arrayName].length - 1 ? "," : "" }}
</span>
</section>
<!-- 是对象 -->
<span v-else>{{ scope.row[item?.sign]?.[item.prop] || "-" }}</span>
</section>
<!-- 过滤常量 -->
<span v-else-if="item.sign === 'filter'">{{
$commonFilter(scope.row[item.prop], item.spec)
}}</span>
<!-- 注册地址 -->
<span v-else-if="item.sign === 'area'">{{
scope.row.provinceCode != 0
? codeToText[scope.row.provinceCode] +
"," +
codeToText[scope.row.cityCode] +
"," +
codeToText[scope.row.countyCode]
: "-"
}}</span>
<!-- 对象里面名字 -->
<span v-else-if="item.sign === 'obj'">{{
scope.row[item.prop][item.objKey] || "-"
}}</span>
<span v-else>{{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
<slot></slot>
<!-- <el-table-column
fixed="right"
label="操作"
:width="operationWidth"
v-if="operation"
>
<template #default
><el-button v-if="operationObj.see" link type="primary" size="small"
>查看</el-button
>
<el-button v-if="operationObj.edit" link type="primary" size="small"
>编辑</el-button
>
<el-button v-if="operationObj.add" link type="primary" size="small"
>添加</el-button
>
<el-button v-if="operationObj.del" link type="danger" size="small"
>删除</el-button
>
</template>
</el-table-column> -->
</el-table>
<pagination
v-if="total > 0"
:total="total"
:page="currentPage"
:limit="limit"
@pagination="fnChangePage"
></pagination>
</section>
</template>
<script setup>
import { ref, defineProps, nextTick, watch, defineEmits } from "vue";
import tool from "@/utils/tool";
import { codeToText } from "element-china-area-data";
import dayjs from "dayjs";
// console.log(CodeToText(110000));
// const Pagination = defineAsyncComponent(() =>
// import("@c/Pagination/index.vue")
// );
const emit = defineEmits([
"handleSelectionChange",
"fnRowClick",
"fnChangePage"
]);
const props = defineProps({
tableTitle: {
type: Array,
default: () => {
return [];
}
},
tableData: {
type: Array,
default: () => {
return [];
}
},
height: {
type: String,
default: "auto"
},
//是否显示复选框
selection: {
type: Boolean,
default: false
},
//序号是否显示
serialNumber: {
type: Boolean,
default: false
},
operation: {
type: Boolean,
default: false
},
operationWidth: {
type: Number,
default: 120
},
total: Number, // 总数
currentPage: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 10
}
// 增删改查按钮 可增加
// operationObj: {
// type: Object,
// default: () => {
// return {
// add: {
// type: Boolean,
// default: false
// },
// edit: {
// type: Boolean,
// default: false
// },
// del: {
// type: Boolean,
// default: false
// },
// see: {
// type: Boolean,
// default: false
// }
// };
// }
// }
});
const multipleTableRef = ref([]);
// table数据
let tableData = ref(props.tableData);
let tableTitle = ref(props.tableTitle);
// 监听table数据变化,达到实时更新
watch(props, () => {
tableData.value = props.tableData;
if (props.selection) {
// 处理选中的
nextTick(() => {
props.tableData.map((v, i) => {
if (v.status && v.status == 20) {
multipleTableRef.value.toggleRowSelection(props.tableData[i], true);
}
});
});
}
});
const fnChangePage = (val) => {
emit("fnChangePage", val);
};
// 多选
const handleSelectionChange = (val) => {
emit("handleSelectionChange", val);
};
const fnRowClick = (row) => {
emit("fnRowClick", row);
};
</script>
<style lang="less" scoped>
.table-box {
// width: 100%;
// // margin: 20px auto;
// padding: 20px 0;
// margin-top: 20px;
}
.pic {
width: 100px;
height: 100%;
}
:deep(.el-table--enable-row-hover .el-table__body tr:hover > td) {
// background-color: #effff9 !important;
}
:deep(.el-scrollbar) {
background: #fff;
}
.el-table tr {
color: #333;
}
:deep(.el-table .cell) {
font-size: 14px !important;
}
// :deep(.el-table thead th) {
// border-bottom: 2px solid rgba(2, 165, 74, 0.5) !important;
// }
</style>