vue实现鼠标滚轮控制页面横向滑动
先看效果
20240919_095531
1.首先创建一个xScroll.vue组件
<template>
<div class="main" v-size-ob="mainSize">
<div class="v-scroll">
<div class="content">
<slot></slot>
</div>
</div>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped lang="less">
.main {
width: 100%;
height: 100%;
}
</style>
在页面中使用
<div class="zlcXScroll">
<xScroll>
<div class="imgs">
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
<div>
<img src="https://picsum.photos/200/300" alt="" />
</div>
</div>
</xScroll>
</div>
效果:
将容器内的内容横向排列
.zlcXScroll {
width: 100%;
height: 300px;
.imgs {
display: flex;
flex-direction: row;
align-items: center;
img {
margin-right: 10px;
}
}
}
效果:(目前需要按住shift再滑动滚轮)
2.利用盒子纵向滚动条默认不需要shift键
绿色盒子就是v-scroll,v-scroll网上转90之前,需要将内容(照片盒子content)向下旋转90°
3.获取红色盒子的宽高,赋值给绿色盒子的高宽
<template>
<div class="main" v-size-ob="mainSize">
<div class="v-scroll">
<div class="content">
<slot></slot>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive } from "vue";
let mainMes = reactive({
w: 0,
h: 0,
});
interface Eobj {
width: number;
height: number;
}
let mainSize = (e: Eobj) => {
let { width, height } = e;
mainMes.w = width;
mainMes.h = height;
};
</script>
<style scoped lang="less">
.main {
width: 100%;
height: 100%;
outline: 1px solid red;
.v-scroll {
outline: 1px solid rgb(17, 0, 255);
--w: calc(v-bind(mainMes.w) * 1px);
--h: calc(v-bind(mainMes.h) * 1px);
width: var(--h);
height: var(--w);
.content{
height: var(--h);
}
}
}
</style>
4.将content盒子向下旋转90°
按照左上角为中心,直接旋转,会跑到最大容器外面去,可以往右移一点距离(红色容器的高度),然后再旋转
<template>
<div class="main" v-size-ob="mainSize">
<div class="v-scroll">
<div class="content">
<slot></slot>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive } from "vue";
let mainMes = reactive({
w: 0,
h: 0,
});
interface Eobj {
width: number;
height: number;
}
let mainSize = (e: Eobj) => {
let { width, height } = e;
mainMes.w = width;
mainMes.h = height;
};
</script>
<style scoped lang="less">
.main {
width: 100%;
height: 100%;
outline: 1px solid red;
.v-scroll {
outline: 1px solid rgb(17, 0, 255);
--w: calc(v-bind(mainMes.w) * 1px);
--h: calc(v-bind(mainMes.h) * 1px);
width: var(--h);
height: var(--w);
position: relative;
.content {
height: var(--h);
position: absolute;
left: var(--h);
transform-origin: left top;
transform: rotate(90deg);
}
}
}
</style>
效果:
5.content旋转完后,再将v-scroll向上旋转90°即可
<template>
<div class="main" v-size-ob="mainSize">
<div class="v-scroll">
<div class="content">
<slot></slot>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive } from "vue";
let mainMes = reactive({
w: 0,
h: 0,
});
interface Eobj {
width: number;
height: number;
}
let mainSize = (e: Eobj) => {
let { width, height } = e;
mainMes.w = width;
mainMes.h = height;
};
</script>
<style scoped lang="less">
.main {
width: 100%;
height: 100%;
outline: 1px solid red;
.v-scroll {
outline: 1px solid rgb(17, 0, 255);
--w: calc(v-bind(mainMes.w) * 1px);
--h: calc(v-bind(mainMes.h) * 1px);
width: var(--h);
height: var(--w);
position: relative;
overflow: hidden scroll;
transform-origin: 0 0;
transform: translateY(var(--h)) rotate(-90deg);
&::-webkit-scrollbar {
width: 0;
height: 0;
}
.content {
height: var(--h);
position: absolute;
left: var(--h);
transform-origin: left top;
transform: rotate(90deg);
}
}
}
</style>
效果:(现在不需要按住shift,可直接滑动滚轮实现页面横向滑动)
6.v-size-ob是自定义指令:(获取元素的宽高)
新建一个sizeOb.ts文件
const map = new WeakMap();
const ob = new ResizeObserver((entries) => {
for (const entry of entries) {
const handler = map.get(entry.target);
if (handler) {
const box = entry.borderBoxSize[0];
handler({
width: box.inlineSize,
height: box.blockSize,
});
}
}
});
export default {
mounted(el, binding) {
ob.observe(el);
map.set(el, binding.value);
},
unmounted(el) {
ob.unobserve(el);
},
};
在main.ts入口文件中引入
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
import Antd from "ant-design-vue";
import "ant-design-vue/dist/reset.css";
import sizeOb from "./directives/sizeOb";
let app = createApp(App);
app.config.globalProperties.msg = "hello";
//自定义指令
app.directive("size-ob", sizeOb);
app.use(Antd).mount("#app");