vue-pure-admin选择器组件:Selector自定义选择器实现
还在为复杂的范围选择需求而烦恼吗?vue-pure-admin的ReSelector组件提供了优雅的解决方案!本文将深入解析这个强大的自定义选择器组件,带你掌握从基础使用到高级定制的完整技能树。
组件概述
ReSelector是一个专门为范围选择场景设计的Vue3组件,具有以下核心特性:
- 🎯 双向范围选择:支持选择起始和结束值
- 📊 数据回显:支持初始化时显示已选范围
- 🚫 禁用状态:灵活控制组件交互状态
- 🎨 视觉反馈:丰富的鼠标交互效果
- 🔧 TypeScript支持:完整的类型定义
核心实现原理
组件架构
关键技术点
1. CSS类名管理
组件使用精心设计的CSS类名系统来实现视觉反馈:
.hs-on { background-color: #409eff; border-radius: 50%; } /* 激活状态 */
.hs-range { background-color: #f2f6fc; } /* 范围背景 */
.both-left-sides { border-radius: 50% 0 0 50%; } /* 左侧圆角 */
.both-right-sides { border-radius: 0 50% 50% 0; } /* 右侧圆角 */
2. 选择算法逻辑
// 鼠标移动时的范围计算
const setCurrentValue = index => {
if (selectedList.length === 1) {
let firstIndex = overList[0].index;
// 向右选择
if (index > firstIndex) {
selectedDirection = "right";
while (index >= firstIndex) {
addClass(document.querySelector(".hs-select__item" + firstIndex), inRange);
firstIndex++;
}
}
// 向左选择
else {
selectedDirection = "left";
while (index <= firstIndex) {
addClass(document.querySelector(".hs-select__item" + firstIndex), inRange);
firstIndex--;
}
}
}
};
基础使用教程
安装与引入
首先确保项目中已安装必要的依赖:
npm install @pureadmin/utils
然后在组件中引入:
import { ReSelector } from "@/components/ReSelector";
基本示例
<template>
<div>
<ReSelector
:HsKey="0"
:max="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]"
@selectedVal="handleSelection"
/>
<p>选中范围:{{ selectedRange }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { ReSelector } from "@/components/ReSelector";
const selectedRange = ref("");
const handleSelection = ({ left, right }) => {
selectedRange.value = `${left}-${right}`;
};
</script>
配置选项详解
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| HsKey | Number | String | 0 | 组件唯一标识符 |
| disabled | Boolean | false | 是否禁用组件 |
| value | Number | 0 | 当前值 |
| max | Array | [1,2,3,4,5,6,7,8,9,10] | 可选值数组 |
| echo | Array | [] | 回显数据数组 |
事件处理
组件发出 selectedVal 事件,返回包含选择信息的对象:
interface SelectionResult {
left: any; // 起始值
right: any; // 结束值
whole: any[]; // 完整选择信息
}
高级功能
数据回显模式
<ReSelector
:HsKey="1"
:echo="[3, 8]"
:disabled="true"
:max="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct']"
/>
自定义数据源
<ReSelector
:HsKey="2"
:max="[
{ id: 1, name: '选项1' },
{ id: 2, name: '选项2' },
{ id: 3, name: '选项3' },
{ id: 4, name: '选项4' }
]"
@selectedVal="handleObjectSelection"
/>
实战案例
案例1:日期范围选择器
<template>
<div class="date-selector">
<ReSelector
:HsKey="'date'"
:max="generateDates()"
@selectedVal="handleDateSelection"
/>
<div v-if="selectedDateRange" class="result">
选择日期范围:{{ selectedDateRange }}
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { ReSelector } from "@/components/ReSelector";
const selectedDateRange = ref("");
const generateDates = () => {
const dates = [];
for (let i = 1; i <= 31; i++) {
dates.push(`${i}日`);
}
return dates;
};
const handleDateSelection = ({ left, right }) => {
selectedDateRange.value = `${left} 至 ${right}`;
};
</script>
案例2:价格区间筛选
<template>
<div class="price-filter">
<h4>价格区间选择</h4>
<ReSelector
:HsKey="'price'"
:max="priceOptions"
@selectedVal="handlePriceSelection"
/>
<el-button
v-if="selectedPriceRange"
type="primary"
@click="applyFilter"
>
应用筛选: {{ selectedPriceRange }}
</el-button>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { ReSelector } from "@/components/ReSelector";
const priceOptions = ['100', '200', '300', '400', '500', '600', '700', '800'];
const selectedPriceRange = ref("");
const handlePriceSelection = ({ left, right }) => {
selectedPriceRange.value = `¥${left}-¥${right}`;
};
const applyFilter = () => {
// 执行筛选逻辑
console.log('应用价格筛选:', selectedPriceRange.value);
};
</script>
性能优化建议
1. 避免不必要的重渲染
// 使用 computed 属性优化
const optimizedMax = computed(() => {
return props.max.map(item => ({
...item,
// 添加缓存标识
_cache: Date.now()
}));
});
2. 事件防抖处理
import { debounce } from 'lodash-es';
const handleSelection = debounce(({ left, right }) => {
selectedRange.value = `${left}-${right}`;
}, 300);
3. 虚拟滚动支持(大数据量)
对于大量数据的场景,可以考虑实现虚拟滚动版本:
// 虚拟滚动实现思路
const visibleItems = computed(() => {
const start = Math.max(0, scrollIndex.value - 5);
const end = Math.min(props.max.length, scrollIndex.value + 10);
return props.max.slice(start, end);
});
常见问题解答
Q1: 如何自定义样式?
A: 通过覆盖CSS变量或使用深度选择器:
/* 自定义主题色 */
:deep(.hs-on) {
background-color: your-custom-color;
}
/* 修改尺寸 */
:deep(.hs-item) {
width: 40px;
height: 40px;
line-height: 40px;
}
Q2: 支持动态更新数据吗?
A: 是的,组件会响应props的变化:
<ReSelector
:HsKey="dynamicKey"
:max="dynamicData"
:echo="dynamicEcho"
/>
Q3: 如何处理移动端适配?
A: 组件本身支持响应式,可通过CSS媒体查询进一步优化:
@media (max-width: 768px) {
:deep(.hs-item) {
width: 25px;
height: 25px;
line-height: 25px;
font-size: 12px;
}
}
总结
vue-pure-admin的ReSelector组件为范围选择场景提供了强大而灵活的解决方案。通过本文的详细解析,你应该已经掌握了:
- ✅ 组件的基本使用方法
- ✅ 高级配置和自定义选项
- ✅ 实战案例和应用场景
- ✅ 性能优化技巧
- ✅ 常见问题解决方法
无论你是需要简单的数值范围选择,还是复杂的自定义数据筛选,ReSelector都能满足你的需求。其优雅的API设计和丰富的功能特性,使其成为vue-pure-admin生态中不可或缺的重要组件。
现在就开始在你的项目中尝试使用ReSelector,体验它带来的开发便利和用户体验提升吧!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



