taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
110 lines (109 loc) • 3.05 kB
JavaScript
import {h, defineComponent, computed, mergeProps} from "vue";
import {Text, View} from "@tarojs/components";
import {pxTransform, convertToUnit} from "../utils/common";
import {useModelValue} from "../composables/model";
const AtRate = defineComponent({
name: "AtRate",
props: {
size: {
type: [Number, String],
default: 20,
validator: (prop) => {
return typeof parseInt(`${prop}`) === "number";
}
},
value: {
type: Number,
default: 0
},
max: {
type: [Number, String],
default: 5,
validator: (prop) => {
return typeof parseInt(`${prop}`) === "number";
}
},
margin: {
type: [Number, String],
default: 5,
validator: (prop) => {
return typeof parseInt(`${prop}`) === "number";
}
},
icon: {
type: String,
default: "star"
},
color: String,
onChange: Function
},
setup(props, {attrs, emit}) {
const modelValue = useModelValue(props, emit, "value");
const iconClasses = computed(() => ({
"at-icon": true,
[`at-icon-${props.icon}-2`]: true
}));
const iconMarginStyle = computed(() => ({
marginRight: pxTransform(parseInt(`${props.margin}`))
}));
const iconStyle = computed(() => (cls) => ({
fontSize: props.size ? convertToUnit(props.size) : "",
color: props.color && cls.includes("at-rate__icon--on") ? props.color : ""
}));
const starColorClasses = computed(() => {
const classNameArr = [];
const floorValue = Math.floor(props.value);
const ceilValue = Math.ceil(props.value);
for (let i = 0; i < parseInt(`${props.max}`); i++) {
if (floorValue > i) {
classNameArr.push("at-rate__icon at-rate__icon--on");
} else if (ceilValue - 1 === i) {
classNameArr.push("at-rate__icon at-rate__icon--half");
} else {
classNameArr.push("at-rate__icon at-rate__icon--off");
}
}
return classNameArr;
});
function handleClick(event) {
if (attrs["onUpdate:value"]) {
modelValue.value = event;
} else {
props.onChange && props.onChange(event);
}
}
return () => h(View, mergeProps(attrs, {
class: "at-rate"
}), {
default: () => [
starColorClasses.value.map((cls, i) => h(View, {
key: `at-rate-star-${i}`,
class: cls,
style: iconMarginStyle.value,
onTap: handleClick.bind(this, i + 1)
}, {
default: () => [
h(Text, {
class: iconClasses.value,
style: iconStyle.value(cls)
}),
h(View, {
class: "at-rate__left"
}, {
default: () => [
h(Text, {
class: iconClasses.value,
style: iconStyle.value(cls)
})
]
})
]
}))
]
});
}
});
var rate_default = AtRate;
export {
rate_default as default
};