layui/src/module/rate/index.vue

109 lines
2.7 KiB
Vue
Raw Normal View History

2021-11-17 16:45:22 +00:00
<script lang="ts">
export default {
name: "LayRate",
};
</script>
<script setup lang="ts">
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;
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,
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);
// 是否存在半颗星
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;
}
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',
`${
icons[icons.length - (isHalf && index === Math.ceil(currentValue) ? 2: 1)]
2021-12-07 16:16:59 +00:00
}`,
]"
:style="{ color: theme }"
/>
<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>