PC端横向滚动之回到指定位置—Vue3
步骤
1.页面加载就需要指定到指定的位置
大盒子的ref.value.scrollLeft = 小盒子ref数组.value[指定位置的索引].offsetLeft - 小盒子ref数组.value[第0项].offsetLeft;
因为第0项一般都会距离左侧还有一部分需要剪掉,不要把减去的写死了,因为在不同分辨率的电脑下的距离也是不一样的
2.绑定回到某个位置的按钮,这个自己绑定一个点击事件,触发第一点即可
3.监听与销毁视图变化,视图变大或变小,都会影响你指定的位置变化,因为你的没位置未能跟着一起变化,记得销毁
onMounted(function () {
window.addEventListener('resize', ()=>{第一点}); //缩放即会将原有的位置出现偏移,因此监听视图变化
});
onBeforeUnmount(() => {
window.removeEventListener('resize',()=>{
第一点
}) //销毁事件
})
示例
<template>
<div class="UserHome box-border">
<a-row :gutter="[0, 20]">
<a-col :span="24" :order="1">
<div class="BoxBorder px-[20rem] pt-[20rem] pb-[10rem] min-h-[272rem] box-border">
<div style="display: flex;justify-content: space-between;">
<div class="FontBlack pb-[13rem]">糖尿病服务方案</div>
<app-button @click="goToday">回到今日</app-button>
</div>
<div class="flex box" @mousedown="startDrag" @mousemove="onDrag" @mouseup="mouseup" @mouseleave="stopDrag">
<div class="flex scrollBox" ref="scrollContent" v-show="newData?.length">
<div class="flex mr-[30px]" v-for="(item, index) in newData" :ref="(item:any) => setItemRef(item,index)" :key="index">
<!--......每一项-->
</div>
</div>
<div class="flex justify-center flex-1" v-if="!newData?.length">
<a-empty description="暂无数据" />
</div>
</div>
</div>
</a-col>
</a-row>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, watch, shallowRef, computed, nextTick, onBeforeUnmount } from "vue";
import { defineComponent } from "vue";
import diseaseLable from "./disease-lable.vue";
import { throttle } from "lodash";
import { getNewUserHealthPathExecuteList, getHistoryUserHealthPathExecuteList } from "@/services/api/360";
import { useRoute } from "vue-router";
const route = useRoute();
onMounted(async function () {
await getNewList(true);
await getOldList(true);
tableList();
window.addEventListener('resize', onSizeMt); //缩放即会将原有的位置出现偏移,因此监听视图变化
});
onBeforeUnmount(() => {
window.removeEventListener('resize', onSizeMt) //销毁事件
})
defineComponent({
components: {
diseaseLable,
},
props: {
data: {
type: Object,
default: () => new Object(),
},
},
});
// 整个大盒子的ref初始化
const scrollContent = ref();
// 判断是否松开鼠标按键
let isDragging = false;
// 事件对象的x轴距离减去大盒子距离左部的距离
let startX = 0;
// 距离左边
let scrollLeft = 0;
// 左滑右滑
let startZY = ref(0);
let startSX = ref(0);
// 判断是否左滑还是右滑
let swipeDirection = ref();
const dataFlag = ref(true);
const oldPageIndex = ref(1);
const oldPageSize = ref(1000);
const dataOldFlag = ref(true);
// 定位数据长度
const nowIndex = ref(0)
// 新数据
const newData = shallowRef<any[]>([]);
const pageIndex = ref(1);
const pageSize = ref(1000);
// 鼠标按下
const startDrag = (e: any) => {
//console.dir(scrollContent.value.offsetLeft);
//console.log(e);
isDragging = true;
startX = e.pageX - scrollContent.value.offsetLeft;
scrollLeft = scrollContent.value.scrollLeft;
// startZY.value = e.clientX;
// startSX.value = e.clientY;
};
// 定位到指定的位置
const onSizeMt = () => {
scrollContent.value.scrollLeft = itemRefs.value[nowIndex.value]?.offsetLeft - itemRefs.value[0]?.offsetLeft;
}
// 鼠标移动
const onDrag = (e: any) => {
if (!isDragging) return; //如果没按下鼠标就移动,则失效
e.preventDefault();
const x = e.pageX - scrollContent.value.offsetLeft;
const walk = (x - startX) * 3; // Scroll-fast
scrollContent.value.scrollLeft = scrollLeft - walk;
/*
const currentX = e.clientX;
const currentY = e.clientY;
const diffX = startZY.value - currentX;
const diffY = startSX.value - currentY;
if (Math.abs(diffX) > Math.abs(diffY)) {
swipeDirection.value = diffX > 0 ? "Right" : "Left";
} 这里是监听左滑右滑,不用管*/
};
// 鼠标抬起
const mouseup = throttle(() => {
if (!isDragging) return;
nextTick(() => {
isDragging = false;
});
}, 500);
// 鼠标离开
const stopDrag = () => {
isDragging = false;
};
// 新列表
const getNewList = (flag?: boolean) => {
getNewUserHealthPathExecuteList({
pageIndex: pageIndex.value,
pageSize: pageSize.value,
userIdentityId: route.query.userIdentityId as string,
}).then((res: any) => {
if (!res.data) return;
if (res.data?.data.length === 0) {
dataFlag.value = false;
}
res.data?.data.forEach((item: any) => {
item.items.forEach((row: any) => {
if (row.status === 0 || row.status === 1) {
row.img = require("../images/img3.png");
} else if (row.status === 2) {
row.img = require("../images/img4.png");
}
});
});
if (flag) {
newData.value = [...newData.value, ...res.data?.data];
}
});
};
const itemRefs = ref<any[]>([]); // ref数组
// 动态绑定ref
const setItemRef = (item: any, index: number) => {
if (item) {
itemRefs.value[index] = item;
}
};
// 历史数据接口
const getOldList = (flag?: boolean) => {
getHistoryUserHealthPathExecuteList({
pageIndex: oldPageIndex.value,
pageSize: oldPageSize.value,
userIdentityId: route.query.userIdentityId as string,
}).then((res: any) => {
if (!res?.data || res.data?.data.length === 0) {
dataOldFlag.value = false;
return
}
res.data?.data.forEach((item: any) => {
item.items.forEach((row: any) => {
if (row.status === 99) {
row.img = require("../images/img2.png");
}
});
});
newData.value = [...res.data?.data, ...newData.value]; // 合并新老数据
nowIndex.value = res.data?.data.length //拿到回到新数据的第一条,即老数据的长度
if (flag && itemRefs.value.length) {
nextTick(() => {
scrollContent.value.scrollLeft = itemRefs.value[res.data?.data.length].offsetLeft - itemRefs.value[0].offsetLeft;
});
console.log(itemRefs.value[0].offsetLeft)
}
});
};
// 回到指定位置
const goToday = ()=>{
scrollContent.value.scrollLeft = itemRefs.value[nowIndex.value].offsetLeft - itemRefs.value[0].offsetLeft;
}
</script>