choo-taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
142 lines (134 loc) • 4.41 kB
JavaScript
import { defineComponent, reactive, computed, watch, toRefs, toRef, resolveComponent, createVNode, withCtx, toDisplayString, createTextVNode, openBlock, createBlock, createCommentVNode, mergeProps } from 'vue';
const AtSlider = defineComponent({
name: "AtSlider",
emits: ["change", "changing"],
props: {
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
},
step: {
type: Number,
default: 1
},
value: {
type: Number,
default: 0
},
disabled: Boolean,
showValue: Boolean,
activeColor: {
type: String,
default: "#6190e8"
},
blockSize: {
type: Number,
default: 28,
validator: (val) => val >= 12 && val <= 28
},
blockColor: {
type: String,
default: "#ffffff"
},
backgroundColor: {
type: String,
default: "#e9e9e9"
}
},
setup(props, { emit }) {
const state = reactive({
_value: clampNumber(props.value, props.min, props.max)
});
const precision = computed(() => 10 ** countDecimals(props.step));
const rootClasses = computed(() => ({
"at-slider": true,
"at-slider--disabled": props.disabled
}));
function clampNumber(value, lower, upper) {
return Math.max(lower, Math.min(upper, value));
}
function countDecimals(value) {
if (Math.floor(value) === value)
return 0;
return value.toString().split(".")[1].length || 0;
}
function ensurePrecision(value) {
return Math.round((value + Number.EPSILON) * precision.value) / precision.value;
}
function handleChanging(e) {
const { _value } = state;
let { value } = e.detail;
value = ensurePrecision(value);
if (value !== _value) {
state._value = value;
}
emit("changing", value);
}
function handleChange(e) {
let { value } = e.detail;
value = ensurePrecision(value);
state._value = value;
emit("change", value);
}
watch(() => [
props.value,
props.min,
props.max
], ([value, min, max]) => {
state._value = clampNumber(value, min, max);
});
return {
...toRefs(props),
value_: toRef(state, "_value"),
rootClasses,
handleChange,
handleChanging
};
}
});
// Binding optimization for webpack code-split
const _resolveComponent = resolveComponent, _createVNode = createVNode, _withCtx = withCtx, _toDisplayString = toDisplayString, _createTextVNode = createTextVNode, _openBlock = openBlock, _createBlock = createBlock, _createCommentVNode = createCommentVNode, _mergeProps = mergeProps;
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_taro_slider = process.env.TARO_ENV === "h5" ? _resolveComponent("taro-slider") : "slider";
const _component_taro_view = process.env.TARO_ENV === "h5" ? _resolveComponent("taro-view") : "view";
return (_openBlock(), _createBlock(_component_taro_view, _mergeProps(_ctx.$attrs, { class: _ctx.rootClasses }), {
default: _withCtx(() => [
_createVNode(_component_taro_view, { class: "at-slider__inner" }, {
default: _withCtx(() => [
_createVNode(_component_taro_slider, {
min: _ctx.min,
max: _ctx.max,
step: _ctx.step,
value: _ctx.value_,
disabled: _ctx.disabled,
"block-size": _ctx.blockSize,
"block-color": _ctx.blockColor,
"active-color": _ctx.activeColor,
"background-color": _ctx.backgroundColor,
onChange: _ctx.handleChange,
onChanging: _ctx.handleChanging
}, null, 8 /* PROPS */, ["min", "max", "step", "value", "disabled", "block-size", "block-color", "active-color", "background-color", "onChange", "onChanging"])
]),
_: 1 /* STABLE */
}),
(_ctx.showValue)
? (_openBlock(), _createBlock(_component_taro_view, {
key: 0,
class: "at-slider__text"
}, {
default: _withCtx(() => [
_createTextVNode(_toDisplayString(_ctx.value_), 1 /* TEXT */)
]),
_: 1 /* STABLE */
}))
: _createCommentVNode("v-if", true)
]),
_: 1 /* STABLE */
}, 16 /* FULL_PROPS */, ["class"]))
}
AtSlider.render = _sfc_render;
export default AtSlider;