<template>
<div>
<div class="box">
<div v-for="item in list" :key="item.id" ref="innerBox" class="inner_box" @mouseenter="mouseenter">
<div class="content">{{ item.id }}</div>
</div>
<div v-show="showPointer" ref="pointer" class="pointer"></div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }, { id: 7 }, { id: 8 }, { id: 9 }, { id: 10 }, { id: 11 }],
showPointer: false,
};
},
mounted() {
this.calcPointerPosition(this.$refs.innerBox[0]);
this.showPointer = true;
},
methods: {
mouseenter(e) {
const target = e.target;
this.calcPointerPosition(target);
},
calcPointerPosition(dom) {
this.$refs.pointer.style.setProperty("--s", dom.offsetWidth + "px");
this.$refs.pointer.style.setProperty("--x", dom.offsetLeft + "px");
this.$refs.pointer.style.setProperty("--y", dom.offsetTop + "px");
},
},
};
</script>
<style lang="scss" scoped>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.box {
position: relative;
background-color: black;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
padding: 20px;
gap: 20px;
.inner_box {
// 保持宽高比
position: relative;
width: 100%;
padding-top: 100%;
.content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: aqua;
}
}
.pointer {
--g: 15px;
--s: 240px;
--x: 0px;
--y: 0px;
width: calc(var(--s) + var(--g) * 2);
height: calc(var(--s) + var(--g) * 2);
position: absolute;
left: calc(var(--x) - var(--g));
top: calc(var(--y) - var(--g));
border: 3px solid white;
transition: 0.3s;
}
}
</style>