2021-11-17 16:45:22 +00:00
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
export default {
|
|
|
|
name: "LayRate",
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2021-12-08 13:45:19 +00:00
|
|
|
import { computed, defineProps, ref, withDefaults } from "vue";
|
2021-11-17 16:45:22 +00:00
|
|
|
import "./index.less";
|
|
|
|
|
|
|
|
export interface LayRateProps {
|
|
|
|
theme?: string;
|
|
|
|
length?: number;
|
|
|
|
modelValue: number;
|
|
|
|
readonly?: boolean | string;
|
2021-12-07 16:16:59 +00:00
|
|
|
half?: boolean;
|
|
|
|
text?: boolean;
|
|
|
|
isBlock?: boolean;
|
2021-12-08 13:45:19 +00:00
|
|
|
icons?: string[];
|
2021-11-17 16:45:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const props = withDefaults(defineProps<LayRateProps>(), {
|
|
|
|
length: 5,
|
|
|
|
modelValue: 0,
|
|
|
|
readonly: false,
|
2021-12-07 16:16:59 +00:00
|
|
|
half: false,
|
|
|
|
text: false,
|
|
|
|
isBlock: false,
|
2021-12-08 13:45:19 +00:00
|
|
|
icons: () => ['layui-icon-rate', 'layui-icon-rate-half', 'layui-icon-rate-solid']
|
2021-11-17 16:45:22 +00:00
|
|
|
});
|
|
|
|
|
2021-12-07 16:16:59 +00:00
|
|
|
const emit = defineEmits(["update:modelValue", "select"]);
|
2021-11-17 16:45:22 +00:00
|
|
|
|
2021-12-07 16:16:59 +00:00
|
|
|
const currentValue = ref<number>(props.modelValue);
|
|
|
|
// 临时存储值
|
|
|
|
const tempValue = ref(currentValue.value);
|
|
|
|
// 是否存在半颗星
|
2021-12-08 13:45:19 +00:00
|
|
|
const isHalf = computed(()=>props.half && Math.round(currentValue.value) !== currentValue.value);
|
2021-12-07 16:16:59 +00:00
|
|
|
|
|
|
|
// 计算评分星值
|
|
|
|
const getValue = function (index: number, event: any): number {
|
|
|
|
if (!props.half) {
|
|
|
|
return index;
|
|
|
|
}
|
2021-12-08 13:45:19 +00:00
|
|
|
return index - (event.offsetX <= event.target.offsetWidth / 2 ? 0.5 : 0);
|
2021-12-07 16:16:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// 在评分星移动事件
|
|
|
|
const mousemove = function (index: number, event: any) {
|
|
|
|
if (props.readonly) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
currentValue.value = getValue(index, event);
|
|
|
|
};
|
|
|
|
|
|
|
|
// 离开评分星事件
|
|
|
|
const mouseleave = function (index: number, event: any) {
|
|
|
|
if (props.readonly) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
currentValue.value = tempValue.value;
|
|
|
|
};
|
2021-11-17 16:45:22 +00:00
|
|
|
|
2021-12-07 16:16:59 +00:00
|
|
|
// 选择评分星 --> 单击事件
|
|
|
|
const action = function (index: number, event: any) {
|
2021-11-17 16:45:22 +00:00
|
|
|
if (props.readonly) {
|
|
|
|
return false;
|
|
|
|
}
|
2021-12-07 16:16:59 +00:00
|
|
|
currentValue.value = getValue(index, event);
|
|
|
|
tempValue.value = currentValue.value;
|
|
|
|
emit("update:modelValue", currentValue.value);
|
|
|
|
emit("select", currentValue.value);
|
2021-11-17 16:45:22 +00:00
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
2021-10-04 00:06:19 +00:00
|
|
|
<template>
|
2021-12-07 16:16:59 +00:00
|
|
|
<div :class="isBlock ? 'layui-block' : 'layui-inline'">
|
|
|
|
<ul class="layui-rate" @mouseleave="mouseleave">
|
|
|
|
<li
|
|
|
|
v-for="index of length"
|
|
|
|
:key="index"
|
|
|
|
class="layui-inline"
|
|
|
|
@mousemove="mousemove(index, $event)"
|
|
|
|
@click="action(index, $event)"
|
|
|
|
>
|
|
|
|
<i
|
|
|
|
v-if="index <= Math.ceil(currentValue)"
|
|
|
|
:class="[
|
|
|
|
'layui-icon',
|
|
|
|
`${
|
2021-12-08 13:45:19 +00:00
|
|
|
icons[icons.length - (isHalf && index === Math.ceil(currentValue) ? 2: 1)]
|
2021-12-07 16:16:59 +00:00
|
|
|
}`,
|
|
|
|
]"
|
|
|
|
:style="{ color: theme }"
|
|
|
|
/>
|
2021-12-08 13:45:19 +00:00
|
|
|
<i v-else :class="['layui-icon'].concat(icons[0])" :style="{ color: theme }"/>
|
2021-12-07 16:16:59 +00:00
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<template v-if="text">
|
|
|
|
<span class="layui-inline">
|
|
|
|
<slot :value="currentValue">
|
|
|
|
{{ currentValue + '星' }}
|
|
|
|
</slot>
|
|
|
|
</span>
|
|
|
|
</template>
|
|
|
|
</div>
|
2021-10-04 00:06:19 +00:00
|
|
|
</template>
|