内容简介:实现一个Slider组件,方便用户通过拖动滑块在一个固定区间内进行选择,增强交互细节。概述: 在用户手动一些限定数字时,如果采用输入框的形式,会需要提示信息和错误信息来引导用户,这就存在一些冗余操作。所以衍生出Slider组件,方便用户拖动来选定一个值。代码
实现一个Slider组件,方便用户通过拖动滑块在一个固定区间内进行选择,增强交互细节。
概述: 在用户手动一些限定数字时,如果采用输入框的形式,会需要提示信息和错误信息来引导用户,这就存在一些冗余操作。所以衍生出Slider组件,方便用户拖动来选定一个值。
- 兼容不同游览器的样式;
- Slider组件的value、min、max之间的关系,以及对样式的影响。
1. 实例
代码
<!-- 基础用法 --> <fat-slider /> <!-- 设置Min、Max以及Step --> <fat-slider :min="20" :max="40" step="5" /> <!-- 绑定v-model --> <fat-slider v-model="initValue" /> <!-- 不现实Tool-Tip --> <fat-slider v-model="value" :show-tooltip="false" /> <!-- disabled 该组件 --> <fat-slider disabled /> 复制代码
实例地址:Slider 实例
代码地址: Github UI-Library
2. 原理
该组件的实现是基于原生的 <input type="range" /> ,再通过改写样式以达到上图效果。
组件的基本结构如下
<template>
<div :class="['slider-wrap', { 'is-disabled': disabled }]">
<input
:class="['slider-inner', { 'is-disabled': disabled }]"
:disabled="disabled"
:min="min"
:max="max"
type="range"
v-on="$listeners"
v-model="rate"
v-bind="$attrs"
>
</div>
</template>
复制代码
- 先将修改组件的thumb以及轨道track的样式:
将其从原生的形式
变成以下的样式
基于 cross-browser-range-input 这篇博文,进行基础样式的修改。
为了兼容不同的游览器,首先利用 @mixin 抽离出thumb公共的样式。
@mixin thumb-common-style() {
position: relative;
z-index: 3;
border: 2px solid #409eff;
background: #fff;
cursor: grab;
transition: all 0.3s;
}
// 后续可以丰富rect-slider-thumb等类型
@mixin circle-slider-thumb() {
width: 18px;
height: 18px;
border-radius: 50%;
&:active {
cursor: grabbing;
}
}
复制代码
然后适配不同的浏览器
&::-webkit-slider-thumb {
// thumb居中
margin-top: -6px;
@include circle-slider-thumb();
@include thumb-common-style();
}
&::-moz-range-thumb {
@include circle-slider-thumb();
@include thumb-common-style();
// z-index无效
transform: translateZ(1px);
}
&::-ms-thumb {
@include circle-slider-thumb();
@include thumb-common-style();
}
复制代码
然后以同样的方法来处理track的样式
@mixin common-track {
width: 100%;
height: 6px;
background: #e4e7ed;
border-radius: 3px;
cursor: pointer;
}
复制代码
适配不同浏览器
&::-webkit-slider-runnable-track {
@include common-track();
}
&::-moz-range-track {
@include common-track();
}
/* 只有ms支持fill-lower、fill-upper */
&::-ms-track {
width: 100%;
height: 6px;
cursor: pointer;
background: transparent;
border-color: transparent;
border-width: 16px 0;
color: transparent;
}
&::-ms-fill-lower {
background: #409eff;
border-radius: 3px;
}
&::-ms-fill-upper {
background: #c4c4c4;
border-radius: 3px;
}
复制代码
此时Slider组件在不同浏览器下的显示,如下图
-
Chrome
-
Firefox
-
Ie11
此时的Ie11优秀的不得了,不仅提供了 fill-upper 、 fill-lower 还自带tool-tip提示功能。为了让其他浏览器向他靠齐,就需要实现上述两个功能。丰富组件的结构为
<div :class="['slider-wrapper', { 'is-disabled': disabled }]">
<div v-if="!isIE" class="progress" :style="progressStyle"></div>
<input
:class="['slider-inner', { 'is-disabled': disabled }]"
:disabled="disabled"
:min="min"
:max="max"
type="range"
v-on="$listeners"
v-model="rate"
v-bind="$attrs"
>
<span v-if="!isIE && showTooltip" class="tooltip" :style="toolTipPosition">
{{ rate }}</span>
</div>
复制代码
组件中 progress 、 tooltip 的样式需要通过当前的rate值来进行修改,其规则为
computed: {
isIE() {
return (
!!window.ActiveXObject ||
"ActiveXObject" in window ||
navigator.userAgent.indexOf("Edge") > -1
);
},
progressStyle() {
const { rate, max, min } = this;
return {
width: `${((rate - min) * 100) / (max - min)}%`
};
},
toolTipPosition() {
const { rate, max, min } = this;
const xOffset = 9 - 18 * ((rate - min) / (max - min));
return {
left: `${((rate - min) * 100) / (max - min)}%`,
marginLeft: `${xOffset}px`,
transform: `translateX(-50%)`
};
}
}
复制代码
其中 progressStyle 比较好理解,就是当前rate的值占整体的百分比,而 toolTipPosition 则是利用
position: absolute; /* <percentage>s of the width of the containing block */ left: 10%; /* <percentage>s of the width of the element */ tansform: translateX(-50%); 复制代码
3. 使用
进一步将其封装成Vue的组件,配置其 props 、 data
export default {
props: {
showTooltip: { type: Boolean, default: true },
disabled: { type: Boolean, default: false },
min: { type: Number, default: 0 },
max: { type: Number, default: 100 },
value: { type: [Number, String] }
},
// 处理v-model
model: {
prop: "value",
event: "sliding"
},
watch: {
// 动态修改
rate(value) {
this.$emit("sliding", Number(value));
},
// 如果不存在初始值的话,以最小值为初始值
value: {
handler(value) {
this.rate = this.value || this.min;
},
immediate: true
}
}
}
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Vue自定义组件(简单实现一个自定义组件)
- 实现一个沙漏⏳组件
- angular 实现下拉列表组件
- 从零实现Vue的组件库(五)- Breadcrumb 实现
- 从零实现Vue的组件库(十)- Select 实现
- 从零实现Vue的组件库(十二)- Table 实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Programming in Haskell
Graham Hutton / Cambridge University Press / 2007-1-18 / GBP 34.99
Haskell is one of the leading languages for teaching functional programming, enabling students to write simpler and cleaner code, and to learn how to structure and reason about programs. This introduc......一起来看看 《Programming in Haskell》 这本书的介绍吧!