vue3组件篇 Slider
文章目录
- 组件介绍
- 组件安装与使用
- 组件代码
- 参数说明
- 事件
- 关于dxui组件库
组件介绍
slider组件已成为前端开发中广泛使用的UI组件之一。Slider组件可以让用户在一个可选范围内选择一个值,如音量、进度条等。
Slider组件的设计和功能可以有很多种变化,但通常包含一个滑块和一个轨道。用户可以通过拖动滑块来选择一个值,滑块的位置在轨道上表示该值。
在前端开发中,Slider组件可以使用HTML、CSS和JavaScript实现。HTML中可以使用range input元素来创建Slider组件,CSS可以控制Slider组件的样式,而JavaScript可以增加Slider组件的交互功能,例如拖动滑块时更新滑块位置以及相应的值。
<input type="range" id="slider-input" min="0" max="100" />// 修改滑条的轨道样式
input[type='range'] {-webkit-appearance: none;background: linear-gradient(75deg, #fff, #ff2d52);border-radius: 4px;width: 100%;height: 12px;outline: none;// box-shadow: 0 0 6px rgba();
}// 修改滑条的按钮样式
input[type='range']::-webkit-slider-thumb {-webkit-appearance: none;width: 20px;height: 20px;background: #f53b57;border-radius: 50%;transition: 0.3s;cursor: pointer;
}// 修改滑条按钮激活时的样式
input[type='range']:active::-webkit-slider-thumb {background: #f53b57;box-shadow: 0 0 0 6px rgba(155, 73, 146, 0.4);
}
如果想要存手写一个slider组件,我们需要准备些什么
- slider组件需要确立一个数值范围,即最大最小值min或max
- 按钮的拖动时,触发事件监听,和数值变化
- step步长的限制
- 最难处理的是 进度与value与min和max之间及step的关联计算
- 按钮的拖动效果,以及拖动的边界限制
- 点击滑条上某个位置时,按钮和数值的变化
- 滑条的禁用
组件安装与使用
需要先安装vue3-dxui
yarn add vue3-dxui
或者
npm install vue3-dxui
全局main.ts中引入css
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'vue3-dxui/dxui/dxui.css'createApp(App).use(store).use(router).mount('#app')
按需引入
<script>
import { Slider } from 'vue3-dxui'export default {components: {Slider}
}
</script>
组件代码
<template><div class="dx-slider-warpper"><div class="dx-slider-content" :draggable="false"><div class="dx-slider-track" ref="sliderTrack" :draggable="false" @click="handleClickTrack"><div class="dx-slider-fill" :style="{ width: sliderFillPercent + '%' }"></div></div><divclass="dx-slider-thumb":class="sliderThumbStatusClass"ref="sliderThumb":style="{ left: thumbX }"@mousedown="thumbDown":draggable="false"></div></div><div class="dx-slider-other"><div class="dx-slider-min">{{ min }}</div><div class="dx-slider-value">{{ sliderValue }}</div><div class="dx-slider-max">{{ max }}</div></div></div>
</template><script lang="ts">
import { onMounted, ref, watch, SetupContext } from 'vue'
import { Data } from './types/index'
export default {props: {// 滑动条最小值min: {require: false,default: 0,type: Number},// 滑动条最大值max: {require: false,default: 100,type: Number},// 滑动条每一次滑动的最小值1 必须为整数step: {require: false,default: 1,type: Number},value: {require: false,default: 0,type: Number},disabled: {require: false,default: false,type: Boolean}},setup(props: Data, context: SetupContext) {let maxX = 0let thumbWidth = 6const sliderTrack = ref<any>()const sliderThumb = ref<any>()// sliderThumb被激活时的样式名称const sliderThumbStatusClass = ref('')// 当前的值const sliderValue = ref<number>(props.value as number)// 进度条填充百分比const sliderFillPercent = ref<number>(0)// 数值之间的间距const distance = Number(props.max) - Number(props.min)// value的值必须大于等于min,小于等于maxif (sliderValue.value < Number(props.min)) {sliderValue.value = Number(props.min) || 0} else if (sliderValue.value > Number(props.max)) {sliderValue.value = Number(props.max) || 100}const thumbX = ref('0px')const thumbTop = ref('-7px')onMounted(() => {thumbWidth = (sliderThumb.value?.offsetWidth || 0) / 2thumbTop.value = -((sliderThumb.value?.offsetHeight || 0) / 2) + 'px'maxX = (sliderTrack.value?.offsetWidth || 0) - thumbWidth// 初始化,根据sliderValue.value的值,分别计算百分比和thumbXsliderFillPercent.value = ((sliderValue.value - Number(props.min)) / distance) * 100thumbX.value =((sliderValue.value - Number(props.min)) / distance) * (maxX + thumbWidth) -thumbWidth +'px'if (props.disabled) {sliderThumbStatusClass.value = 'dx-slider-thumb-disabled'}})// 点击轨道,thumb跳跃至点击的位置,offsetX是个好东西const handleClickTrack = (e: any) => {const targetX = e?.offsetXif (props.disabled) {return}thumbX.value = targetX - thumbWidth + 'px'}const thumbDown = (e: any) => {if (props.disabled) {return}sliderThumbStatusClass.value = 'dx-slider-thumb-active'const startX = e?.clientXconst initX = parseFloat(thumbX.value)const handler = (event: any) => {const nowX = event.clientXconst disX = nowX - startXthumbX.value = initX + disX + 'px'// 限制可拖拽的范围if (initX + disX <= -thumbWidth) {thumbX.value = `-${thumbWidth}px`}if (initX + disX > maxX) {thumbX.value = `${maxX}px`}}document.addEventListener('mousemove', handler, false)document.addEventListener('mouseup',() => {sliderThumbStatusClass.value = ''document.removeEventListener('mousemove', handler)},false)}watch(thumbX, () => {// 计算百分比,显示fill的进度条sliderFillPercent.value =((parseFloat(thumbX.value) + thumbWidth) / (maxX + thumbWidth)) * 100// 计算对应的value的值const b =((parseFloat(thumbX.value) + thumbWidth) / (maxX + thumbWidth)) * distance +Number(props.min)// 求余并去除余数const a = b % Number(props.step)sliderValue.value = b - acontext.emit('sliderChange', sliderValue.value)})return {thumbDown,thumbX,thumbTop,handleClickTrack,sliderTrack,sliderThumb,sliderFillPercent,sliderThumbStatusClass,sliderValue}}
}
</script><style lang="scss" scoped>
@import '@/scss/layout.scss';.dx-slider-warpper {// .dx-slider-min,// .dx-slider-max {// display: inline-block;// }.dx-slider-other {// overflow: hidden;margin: 6px 0;position: relative;// &::after {// content: '';// clear: both;// display: block;// }.dx-slider-min {position: absolute;transform: translateX(-50%);}.dx-slider-max {position: absolute;right: 0;top: 0;transform: translateX(50%);}}.dx-slider-value {display: inline-block;margin-left: 50%;transform: translateX(-50%);}.dx-slider-content {position: relative;cursor: pointer;-webkit-user-drag: none;user-select: none;width: calc(100%);}.dx-slider-track {width: 100%;height: 6px;border-radius: 3px;background-color: $background-color;overflow: hidden;.dx-slider-fill {background-color: $blue-middle-color;height: 100%;width: 20%;}}.dx-slider-track:hover {background: #e1e1e1;}.dx-slider-thumb {height: 14px;width: 14px;border-radius: 50%;border: 2px solid $blue-color;background: $white-color;cursor: pointer;position: absolute;z-index: 100;top: 50%;transform: translateY(-50%);}.dx-slider-thumb-active {height: 20px;width: 20px;}.dx-slider-thumb-disabled {cursor: not-allowed;border: 2px solid $background-color;background: $white-color;}
}
</style>
参数说明
参数 | 说明 |
---|---|
max | 最大值 number 默认值 0 |
min | 最小值 number 默认值 0 |
step | 步长 number 必须为整数 最小为1 默认值 1 |
value | 滑条当前的值 |
disabled | 是否禁用滑条 |
事件
事件名称 | 说明 |
---|---|
sliderChange | 通过@sliderChange 监听滑条的变化和最新的值 |
关于dxui组件库
dxui组件库是我个人搭建的vue3 前端交互组件库,倾向于pc网站的交互模式。
- 如果你有任何问题,请在博客下方评论留言,我尽可能24小时内回复。
- dxui新上线的官网域名变更 http://dxui.cn
- npm 官方链接 https://www.npmjs.com/package/vue3-dxui
- 如果你想看完整源码 https://github.com/757363985/dxui
vue3组件篇 Slider相关推荐
- vue3 组件篇 Affix
文章目录 组件介绍 组件库安装与使用 组件代码 参数说明 事件 关于dxui组件库 组件介绍 Affix是一种常用于前端界面设计的组件,它可以让网页元素固定在页面中的某个位置,随着用户的滚动而保持不变 ...
- vue3组件篇 Select
文章目录 组件介绍 何时使用 基本功能 组件安装与使用 组件代码 参数说明 事件 关于dxui组件库 组件介绍 何时使用 弹出一个下拉菜单给用户选择操作,用于代替原生的选择器,或者需要一个更优雅的多选 ...
- vue3 组件篇 tag
文章目录 组件介绍 标准用法 自定义背景色和字体颜色 点击和关闭的回调 组件代码 参数说明 关于dxui组件库 组件介绍 tag组件,是前端开发常用组件之一,无论是移动端,还是pc端,我们都能经常看到 ...
- VUE3组件库-input组件
theme: mk-cute 这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战 VUE3组件库-input组件 大家好,今天一起来学习vue3实现input组件,希望对你有帮助 目录预览 基 ...
- 手把手教你写一个Vue3组件库但是乞丐版
好久没写文章了,最近在研究一些组件库的实现方法,分享一下.在这我这篇文章之前其实已经有一篇文章讲了Vue如何打包组件库了(最底部),但是这篇文章一是没有源码二是Vue3和Vue2的组件库写法有点不一样 ...
- 使用 Vite 和 TypeScript 从零打造一个属于自己的 Vue3 组件库
前言 随着前端技术的发展,业界涌现出了许多的UI组件库.例如我们熟知的ElementUI,Vant,AntDesign等等.但是作为一个前端开发者,你知道一个UI组件库是如何被打造出来的吗? 读完这篇 ...
- Xamarin Android组件篇教程RecylerView动画组件RecylerViewAnimators(1)
Xamarin Android组件篇教程RecylerView动画组件RecylerViewAnimators(1) RecyclerView是比ListView和GridView更为强大的布局视图, ...
- 九十一、Python的GUI系列 | QT组件篇
@Author:Runsen @Date:2020/7/13 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏 ...
- VMware View 5.0从菜鸟到高手系列 3 -安装View Composer组件篇
在vCenter Server上安装View Composer组件 View Composer具有非常强大的功能,可以为企业快速部署成千上万的虚拟桌面并为企业节省近70%的存储空间. 1. 安装Vie ...
最新文章
- Windows系统程序设计之结构化异常处理
- 如何设置定时器每天执行一次_游戏活动的自动循环——定时器管理
- 数论只会 for 循环 (数学+分块+记忆化)
- 让猫给人打工,猫咖是一门好生意吗?
- 使用腾讯云函数签到天翼云盘
- 如何更高效、更系统地彻底搞懂3D视觉?
- OPERA重要密码学习一
- 基于VTD自带的场景 进行场景搭建
- 【Eclipse使用教程】Java导包快捷键
- leetcode 1800. Maximum Ascending Subarray Sum(python)
- 【已解决】Mysql 存储 emoji 表情报错 Incorrect string value: ‘\xF0\x9F\x98\x82\xF0\x9F
- QObject::moveToThread:
- 分布式与容器化的介绍
- NoMachine出现 The session negotiation failed的解决方案及踩坑总结
- One hundred years of uncertainty
- 微信小程序 云开发-答题小程序 demo
- 2022-08-15 MySQL数据库
- c语言煎饼问题算法,翻煎饼问题(示例代码)
- 总结:2018年互联网套路简史
- 电脑爱好者2012年全彩高清PDF