vue实现页面刻度
实现页面刻度的基本思路
在Vue中实现页面刻度通常用于展示进度、时间轴或测量工具。核心是通过动态计算和渲染刻度线,结合CSS样式和Vue的数据绑定能力。
水平刻度线实现
创建水平刻度组件,使用v-for动态生成刻度线,通过计算属性控制间距和样式:
<template>
<div class="scale-container">
<div
v-for="(tick, index) in ticks"
:key="index"
:style="{ left: `${tick.position}px` }"
class="tick"
>
<span v-if="showLabels">{{ tick.label }}</span>
</div>
</div>
</template>
<script>
export default {
props: {
totalLength: { type: Number, default: 1000 },
interval: { type: Number, default: 100 },
showLabels: { type: Boolean, default: true }
},
computed: {
ticks() {
return Array.from(
{ length: Math.floor(this.totalLength / this.interval) + 1 },
(_, i) => ({
position: i * this.interval,
label: i * this.interval
})
)
}
}
}
</script>
<style>
.scale-container {
position: relative;
height: 30px;
border-bottom: 1px solid #000;
}
.tick {
position: absolute;
bottom: 0;
width: 1px;
height: 10px;
background-color: #000;
}
.tick span {
position: absolute;
transform: translateX(-50%);
font-size: 12px;
}
</style>
垂直刻度线实现
调整CSS实现垂直刻度,主要修改定位方式和容器样式:
.vertical-scale {
position: relative;
width: 30px;
border-right: 1px solid #000;
}
.vertical-tick {
position: absolute;
right: 0;
width: 10px;
height: 1px;
background-color: #000;
}
.vertical-tick span {
position: absolute;
white-space: nowrap;
transform: translate(100%, -50%);
}
动态响应式刻度
结合resizeObserver实现响应式刻度,当容器尺寸变化时自动调整刻度密度:
import { onMounted, onUnmounted, ref } from 'vue'
export default {
setup() {
const containerRef = ref(null)
const ticks = ref([])
const interval = 50 // 每50px一个刻度
const updateTicks = () => {
if (!containerRef.value) return
const width = containerRef.value.offsetWidth
ticks.value = Array.from(
{ length: Math.floor(width / interval) + 1 },
(_, i) => ({
position: i * interval,
label: i * interval
})
)
}
let observer
onMounted(() => {
observer = new ResizeObserver(updateTicks)
if (containerRef.value) observer.observe(containerRef.value)
})
onUnmounted(() => {
if (observer) observer.disconnect()
})
return { containerRef, ticks }
}
}
自定义刻度样式
通过插槽允许自定义刻度样式,增强组件灵活性:
<template>
<div ref="containerRef" class="scale-container">
<div
v-for="(tick, index) in ticks"
:key="index"
:style="getTickStyle(tick)"
>
<slot name="tick" :tick="tick">
<div class="default-tick"></div>
<span v-if="showLabels">{{ tick.label }}</span>
</slot>
</div>
</div>
</template>
刻度与数据绑定
将刻度位置与业务数据关联,实现交互功能:

const handleClick = (tick) => {
emit('tick-selected', tick.position)
}
以上方案可根据实际需求组合使用,通过调整间隔、样式和交互逻辑实现各种刻度场景。






