Skip to content

Commit

Permalink
feat(slider): 添加悬浮显示的功能
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoboRao committed Oct 22, 2021
1 parent ab3df9f commit a49bd72
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 55 deletions.
2 changes: 1 addition & 1 deletion devui/slider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export { Slider }
export default {
title: 'Slider 滑块',
category: '数据录入',
status: '已完成',
status: '80%',
install(app: App): void {
app.use(Slider as any)
}
Expand Down
4 changes: 4 additions & 0 deletions devui/slider/src/slider-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,9 @@ export const sliderProps = {
type: Number,
default: 1,
},
tipsRenderer:{
type: String,
default: '',
}
} as const;
export type SliderProps = ExtractPropTypes<typeof sliderProps>;
29 changes: 29 additions & 0 deletions devui/slider/src/slider.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,35 @@
transform: none;
}
}

.devui-slider_popover {
position: relative;
bottom: 26px;
transform: translate(-50%);
border-radius: $devui-border-radius-feedback;
font-size: $devui-font-size-sm;
color: $devui-feedback-overlay-text;

.devui-slider_popover-arrow {
position: absolute;
left: 50%;
margin-left: -4px;
bottom: -4px;
width: 8px;
height: 8px;
transform: rotate(45deg);
display: block;
z-index: -1;
background-color: $devui-feedback-overlay-bg;
}

.devui-slider_popover-content {
padding: 5px 14px;
text-align: center;
border-radius: $devui-border-radius-feedback;
background-color: $devui-feedback-overlay-bg;
}
}
}

.devui-min_count {
Expand Down
26 changes: 15 additions & 11 deletions devui/slider/src/slider.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { defineComponent, ref, computed, onMounted } from 'vue';
import { sliderProps } from './slider-types';
import { Input } from '../../input';
import './slider.scss';

export default defineComponent({
name: 'DSlider',
components: {
Input,
},
props: sliderProps,
emits: ['update:modelValue'],
setup(props, ctx) {
let isClick = true;
let startPosition = 0;
let startX = 0;

const popoverShow = ref(false);
const sliderRunway = ref<HTMLDivElement>(null);
const inputValue = ref<number>(props.modelValue);
const currentPosition = ref<number>(0);
Expand All @@ -30,7 +27,6 @@ export default defineComponent({
''
);
};

//当传入modelValue时用以定位button的位置
if (props.modelValue > props.max) {
percentDispaly.value = '100%';
Expand All @@ -39,14 +35,13 @@ export default defineComponent({
} else {
percentDispaly.value = ((props.modelValue - props.min) * 100) / (props.max - props.min) + '%';
}

//一挂载就进行当前位置的计算,以后的移动基于当前的位置移动
onMounted(() => {
const sliderWidth = sliderRunway.value.clientWidth;
currentPosition.value = (sliderWidth * (inputValue.value - props.min)) / (props.max - props.min);
});

function handleonMousedown(event: MouseEvent) {
popoverShow.value = true;
//props.disabled状态是不能点击拖拽的
if (props.disabled || props.disabled) return;
//阻止默认事件
Expand All @@ -63,7 +58,6 @@ export default defineComponent({
//获取当前的x坐标值
startX = event.clientX;
//把当前值给startPosition,以便后面再重新拖拽时,会以当前的位置计算偏移

startPosition = currentPosition.value;
newPostion.value = startPosition;
}
Expand All @@ -75,14 +69,15 @@ export default defineComponent({
*
*/
function onDragging(event: MouseEvent) {
popoverShow.value = true;
const currentX = event.clientX;
const pxOffset = currentX - startX;
//移动的x方向上的偏移+初始位置等于新位置
newPostion.value = startPosition + pxOffset;

setPostion(newPostion.value);
}
function onDragEnd() {
popoverShow.value = false;
//防止mouseup后立即执行click事件,mouseup后
//会立即执行click,但是isClick=true 是100ms才出发,因此不会执行click事件,就跳出来了
setTimeout(() => {
Expand Down Expand Up @@ -112,7 +107,6 @@ export default defineComponent({
ctx.emit('update:modelValue', props.max);
return;
}

//向左偏移百分比的值
percentDispaly.value = Math.round((value * 100) / sliderWidth) + '%';
//更新输入框的值
Expand All @@ -121,7 +115,6 @@ export default defineComponent({
currentPosition.value = newPosition;
ctx.emit('update:modelValue', inputValue.value);
}

//当点击滑动条时,
function handleClick(event) {
if (!props.disabled && isClick) {
Expand Down Expand Up @@ -156,6 +149,14 @@ export default defineComponent({
const disableClass = computed(() => {
return props.disabled ? ' disabled' : '';
});
const popover = () => {
return (
<div class='devui-slider_popover' style={{ left: percentDispaly.value, opacity: popoverShow.value ? 1 : 0 }}>
<div class='devui-slider_popover-arrow'></div>
<div class='devui-slider_popover-content'>{inputValue.value + ' ' + props.tipsRenderer}</div>
</div>
);
};
return () => (
<div class='devui-slider'>
{/* 整个的长度 */}
Expand All @@ -166,7 +167,10 @@ export default defineComponent({
class={'devui-slider__button' + disableClass.value}
style={{ left: percentDispaly.value }}
onMousedown={handleonMousedown}
onMouseenter={() => (popoverShow.value = true)}
onMouseout={() => (popoverShow.value = false)}
></div>
{props.tipsRenderer === 'null' ? '' : popover()}
</div>
<span class='devui-min_count'>{props.min}</span>
<span class='devui-max_count'>{props.max}</span>
Expand Down
66 changes: 23 additions & 43 deletions docs/components/slider/index.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
# Slider 滑动输入条

滑动输入条。

### 何时使用

当用户需要在数值区间内进行选择时使用。

### 基本用法

:::demo
<d-slider :min="minValue" :max="maxValue" v-model='inputValue'></d-slider>

:::demo
```vue
<d-slider :min="minValue" :max="maxValue" v-model='inputValue'></d-slider>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup() {
const inputValue = ref(0);
const minValue = ref(0);
const maxValue = ref(100);
return {
inputValue,
maxValue,
Expand All @@ -30,44 +26,26 @@
});
</script>
```

:::
### 可设置 Step 的滑动组件

<br />
<d-slider :min="minValue" :max="maxValue" v-model='inputValue3' :step="step"></d-slider>

### 带有输入框的滑动组件

:::demo

```vue
<d-slider :min="minValue" :max="maxValue" v-model='inputValue' showInput></d-slider>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup() {
const inputValue = ref(0);
const minValue = ref(0);
const maxValue = ref(100);
return {
inputValue,
maxValue,
minValue
};
},
});
</script>
```
<template>
<d-slider :min="minValue" :max="maxValue" v-model="inputValue"></d-slider>
:::

### 可设置 Step 的滑动组件
:::demo

```vue
<d-slider :min="minValue" :max="maxValue" v-model="inputValue" showInput :step="step"></d-slider>
<script>
import { defineComponent, ref } from 'vue'
<d-slider :min="minValue" :max="maxValue" v-model="inputValue2" showInput></d-slider>
<d-slider :min="minValue" :max="maxValue" v-model="inputValue3" :step="step"></d-slider>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
setup() {
const inputValue = ref(0);
Expand Down Expand Up @@ -101,7 +79,7 @@
const disabledValue = ref(5);
const maxValue = ref(50);
const minValue = ref(2);
return {
disabledValue,
maxValue,
Expand All @@ -110,17 +88,19 @@
},
});
</script>
```
:::

### API

d-slider 参数

| 参数 | 类型 | 默认 | 说明 | 跳转 |
| --------- | ------- | ----- | ------------------------------------------------------------------- | ---- |
| max | number | 100 | 可选,滑动输入条的最大值 |[基本用法](#基本用法) |
| min | number | 0 | 可选,滑动输入条的最小值 |[基本用法](#基本用法) |
| showInput | boolean | false | 可选,值为 true 显示输入框 |[带有输入框的滑动组件](#带有输入框的滑动组件) |
| step | number | 1 | 可选,滑动输入条的步长,取值必须大于等于1,且必须可被(max-min)整除 |[可设置 Step 的滑动组件](#可设置Step的滑动组件) |
| disabled | boolean | false | 可选,值为 true 时禁止用户输入 |[禁止输入态](#禁止输入态) |
| 参数 | 类型 | 默认 | 说明 | 跳转 |
| ------------ | ------- | ----- | ------------------------------------------------------------------- | ------------------------------------ |
| max | number | 100 | 可选,滑动输入条的最大值 | [基本用法](#基本用法) |
| min | number | 0 | 可选,滑动输入条的最小值 | [基本用法](#基本用法) |
| step | number | 1 | 可选,滑动输入条的步长,取值必须大于等于 1,且必须可被(max-min)整除 | [基本用法](#可设置Step的滑动组件) |
| disabled | boolean | false | 可选,值为 true 时禁止用户输入 | [基本用法](#禁止输入态) |
| showInput | boolean | false | 可选,值为 true 显示输入框 | [基本用法](#带有输入框的滑动组件) |
| tipsRenderer | string | | 可选,渲染 Popover 内容的函数,传入 null 时不显示 Popover | [基本用法](#异定制popover的显示内容) |

0 comments on commit a49bd72

Please sign in to comment.