[拓展]评分组件增加可自定义图标

This commit is contained in:
xumi 2021-12-08 21:45:19 +08:00
parent debdc84b25
commit 399c7d7258
2 changed files with 45 additions and 18 deletions

View File

@ -236,6 +236,36 @@ export default {
::: :::
::: title 自定义图标
:::
::: demo
<template>
<lay-rate v-model="icons" :icons="['layui-icon-heart', 'layui-icon-heart-fill']" theme="#FE0000"></lay-rate><br>
<lay-rate v-model="halfIcons" :icons="['layui-icon-circle', 'layui-icon-radio', 'layui-icon-circle-dot']" half text></lay-rate><br>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const icons = ref(4)
const halfIcons = ref(0.5)
return {
icons,
halfIcons
}
}
}
</script>
:::
::: title 评分属性 ::: title 评分属性
::: :::
@ -243,13 +273,14 @@ export default {
| 属性 | 描述 | 类型 | 默认值 | | 属性 | 描述 | 类型 | 默认值 |
| -------- | -------- | ------ | ------ | | -------- | -------- | ------ | ------ |
| v-model | 评分值 | number | 0 | | v-model | 评分值 | `number` | 0 |
| length | 评分长度 | number | 5 | | length | 评分长度 | `number` | 5 |
| readonly | 只读模式 | boolean | false | | readonly | 只读模式 | `boolean` | false |
| theme | 只读模式 | string | #ffb800 | | theme | 主题颜色 | `string` | #ffb800 |
| half | 设定组件是否可以选择半星 |boolean | false | | half | 设定组件是否可以选择半星 | `boolean` | false |
| text | 是否显示评分对应的内容 | boolean | false | | text | 是否显示评分对应的内容 | `boolean` | false |
| is-block | 评分是否显示为快元素 | boolean | false | | is-block | 评分是否显示为快元素 | `boolean` | false |
| icons | 评分使用图标`class``["空心", "实心"]`/`["空心", "半心", "实心"]` | `string[]` | 星型 |
::: :::

View File

@ -6,7 +6,7 @@ export default {
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, ref, withDefaults } from "vue"; import { computed, defineProps, ref, withDefaults } from "vue";
import "./index.less"; import "./index.less";
export interface LayRateProps { export interface LayRateProps {
@ -17,6 +17,7 @@ export interface LayRateProps {
half?: boolean; half?: boolean;
text?: boolean; text?: boolean;
isBlock?: boolean; isBlock?: boolean;
icons?: string[];
} }
const props = withDefaults(defineProps<LayRateProps>(), { const props = withDefaults(defineProps<LayRateProps>(), {
@ -26,6 +27,7 @@ const props = withDefaults(defineProps<LayRateProps>(), {
half: false, half: false,
text: false, text: false,
isBlock: false, isBlock: false,
icons: () => ['layui-icon-rate', 'layui-icon-rate-half', 'layui-icon-rate-solid']
}); });
const emit = defineEmits(["update:modelValue", "select"]); const emit = defineEmits(["update:modelValue", "select"]);
@ -34,17 +36,14 @@ const currentValue = ref<number>(props.modelValue);
// //
const tempValue = ref(currentValue.value); const tempValue = ref(currentValue.value);
// //
const isHalf = ref( const isHalf = computed(()=>props.half && Math.round(currentValue.value) !== currentValue.value);
props.half && Math.round(currentValue.value) >= currentValue.value
);
// //
const getValue = function (index: number, event: any): number { const getValue = function (index: number, event: any): number {
if (!props.half) { if (!props.half) {
return index; return index;
} }
isHalf.value = event.offsetX <= event.target.offsetWidth / 2; return index - (event.offsetX <= event.target.offsetWidth / 2 ? 0.5 : 0);
return index - (isHalf.value ? 0.5 : 0);
}; };
// //
@ -61,7 +60,6 @@ const mouseleave = function (index: number, event: any) {
return false; return false;
} }
currentValue.value = tempValue.value; currentValue.value = tempValue.value;
isHalf.value = props.half && Math.round(currentValue.value) >= currentValue.value;
}; };
// --> // -->
@ -91,14 +89,12 @@ const action = function (index: number, event: any) {
:class="[ :class="[
'layui-icon', 'layui-icon',
`${ `${
half && isHalf && currentValue%1 != 0 && index === Math.ceil(currentValue) icons[icons.length - (isHalf && index === Math.ceil(currentValue) ? 2: 1)]
? 'layui-icon-rate-half'
: 'layui-icon-rate-solid'
}`, }`,
]" ]"
:style="{ color: theme }" :style="{ color: theme }"
/> />
<i v-else class="layui-icon layui-icon-rate" :style="{ color: theme }"/> <i v-else :class="['layui-icon'].concat(icons[0])" :style="{ color: theme }"/>
</li> </li>
</ul> </ul>
<template v-if="text"> <template v-if="text">