feat(lenticular): 新增 ManualTiltSlider 独立组件
- uniapp <slider> 包装,0..1 双向绑定 - 内置 ↺ 复位按钮 - value validator 拦截 0..1 范围外输入 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
c6cb55dfc0
commit
86a5fdfbb5
85
frontend/components/lenticular/ManualTiltSlider.vue
Normal file
85
frontend/components/lenticular/ManualTiltSlider.vue
Normal file
@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<view v-if="showReset || label" class="tilt-slider-row">
|
||||
<view v-if="showReset" class="tilt-slider-reset" @tap="handleReset">
|
||||
<text class="tilt-slider-reset-icon">↺</text>
|
||||
</view>
|
||||
<text v-if="label" class="tilt-slider-label">{{ label }}</text>
|
||||
<slider
|
||||
class="tilt-slider"
|
||||
:min="min"
|
||||
:max="max"
|
||||
:step="step"
|
||||
:value="value"
|
||||
:disabled="disabled"
|
||||
:activeColor="activeColor"
|
||||
:backgroundColor="backgroundColor"
|
||||
:show-value="false"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
value: { type: Number, default: 0.5, validator: v => v >= 0 && v <= 1 },
|
||||
disabled: { type: Boolean, default: false },
|
||||
label: { type: String, default: '手动调节倾斜' },
|
||||
showReset: { type: Boolean, default: true },
|
||||
min: { type: Number, default: 0 },
|
||||
max: { type: Number, default: 1 },
|
||||
step: { type: Number, default: 0.01 },
|
||||
activeColor: { type: String, default: '#6E7AFF' },
|
||||
backgroundColor: { type: String, default: '#E5E7EB' },
|
||||
})
|
||||
|
||||
const emit = defineEmits(['change', 'reset'])
|
||||
|
||||
function handleChange(e) {
|
||||
const v = Number(e.detail.value)
|
||||
if (!Number.isFinite(v)) {
|
||||
console.warn('[ManualTiltSlider] non-finite value', e.detail.value)
|
||||
return
|
||||
}
|
||||
if (v < 0 || v > 1) {
|
||||
console.warn('[ManualTiltSlider] value out of [0,1]', v)
|
||||
return
|
||||
}
|
||||
emit('change', v)
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
emit('reset')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tilt-slider-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
padding: 8rpx 16rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
.tilt-slider-reset {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.tilt-slider-reset-icon {
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
.tilt-slider-label {
|
||||
font-size: 12px;
|
||||
color: #6B7280;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.tilt-slider {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user