!2 完善评分组件

Merge pull request !2 from xumiSky/develop
This commit is contained in:
就眠儀式 2021-12-07 16:40:14 +00:00 committed by Gitee
commit dbe701079c
2 changed files with 214 additions and 37 deletions

View File

@ -24,13 +24,13 @@ export default {
:::
::: title 响应结果
::: title 显示文字
:::
::: demo
<template>
<lay-rate v-model="all"></lay-rate> {{all}}
<lay-rate v-model="all" :text="true"></lay-rate>
</template>
<script>
@ -50,6 +50,78 @@ export default {
:::
::: title 半星效果
:::
::: demo
<template>
<lay-rate v-model="half1" :half="true" :is-block="true"></lay-rate>
<lay-rate v-model="half2" :half="true" :text="true" :is-block="true"></lay-rate>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const half1 = ref(0.5)
const half2 = ref(0)
return {
half1,
half2
}
}
}
</script>
:::
::: title 自定义内容
:::
::: demo
<template>
<lay-rate v-model="val" :text="true" :is-block="true">
<template v-slot:default="{value}">{{customText(value)}}</template>
</lay-rate>
<lay-rate v-model="val2" :text="true" :is-block="true">
<template v-slot:default="{value}">{{value}}</template>
</lay-rate>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const val = ref(1)
const val2 = ref(1)
const arrs = {
'1': '极差',
'2': '差',
'3': '中等',
'4': '好',
'5': '极好'
};
const customText = function(val){
return arrs[val];
}
return {
val,
val2
}
}
}
</script>
:::
::: title 指定长度
:::
@ -78,6 +150,36 @@ export default {
:::
::: title 触发事件
:::
::: demo
<template>
<lay-rate v-model="val" @select="selectRate"></lay-rate>
<div>F12 打开调试工具 -> console 控制面板进行查看</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const val = ref(0);
const selectRate = function(value){
console.log('selectRate - value:', value)
}
return {
val
}
}
}
</script>
:::
::: title 只读模式
:::
@ -139,10 +241,36 @@ export default {
::: table
| 属性 | 描述 | 默认值 |
| -------- | -------- | ------ |
| v-model | 评分值 | -- |
| length | 评分长度 | -- |
| readonly | 只读模式 | -- |
| 属性 | 描述 | 类型 | 默认值 |
| -------- | -------- | ------ | ------ |
| v-model | 评分值 | number | 0 |
| length | 评分长度 | number | 5 |
| readonly | 只读模式 | boolean | false |
| theme | 只读模式 | string | #ffb800 |
| half | 设定组件是否可以选择半星 |boolean | false |
| text | 是否显示评分对应的内容 | boolean | false |
| is-block | 评分是否显示为快元素 | boolean | false |
:::
::: title 插槽
:::
::: table
| 属性 | 描述 | 参数 |
| -------- | -------- | ------ |
| -- | 默认插槽,自定义内容时可以使用为 | { value } |
:::
::: title 事件
:::
::: table
| 属性 | 描述 | 回调参数 |
| -------- | -------- | ------ |
| select | 选中之后触发事件 | (value: number) |
:::

View File

@ -6,7 +6,7 @@ export default {
</script>
<script setup lang="ts">
import { computed, defineProps, withDefaults } from "vue";
import { defineProps, ref, withDefaults } from "vue";
import "./index.less";
export interface LayRateProps {
@ -14,50 +14,99 @@ export interface LayRateProps {
length?: number;
modelValue: number;
readonly?: boolean | string;
half?: boolean;
text?: boolean;
isBlock?: boolean;
}
const props = withDefaults(defineProps<LayRateProps>(), {
length: 5,
modelValue: 0,
readonly: false,
half: false,
text: false,
isBlock: false,
});
const emit = defineEmits(["update:modelValue"]);
const emit = defineEmits(["update:modelValue", "select"]);
const currentValue = computed({
get: function () {
return props.modelValue;
},
set: function (val) {
emit("update:modelValue", val);
},
});
const currentValue = ref<number>(props.modelValue);
//
const tempValue = ref(currentValue.value);
//
const isHalf = ref(
props.half && Math.round(currentValue.value) >= currentValue.value
);
const mouseenter = function (index: number, event: any) {
//
const getValue = function (index: number, event: any): number {
if (!props.half) {
return index;
}
isHalf.value = event.offsetX <= event.target.offsetWidth / 2;
return index - (isHalf.value ? 0.5 : 0);
};
//
const mousemove = function (index: number, event: any) {
if (props.readonly) {
return false;
}
currentValue.value = index;
currentValue.value = getValue(index, event);
};
//
const mouseleave = function (index: number, event: any) {
if (props.readonly) {
return false;
}
currentValue.value = tempValue.value;
isHalf.value = props.half && Math.round(currentValue.value) >= currentValue.value;
};
// -->
const action = function (index: number, event: any) {
if (props.readonly) {
return false;
}
currentValue.value = getValue(index, event);
tempValue.value = currentValue.value;
emit("update:modelValue", currentValue.value);
emit("select", currentValue.value);
};
</script>
<template>
<ul class="layui-rate">
<li
v-for="index of length"
:key="index"
class="layui-inline"
@mouseenter="mouseenter(index, $event)"
>
<i
v-if="index <= currentValue"
class="layui-icon layui-icon-rate-solid"
:style="{ color: theme }"
/>
<i v-else class="layui-icon layui-icon-rate" :style="{ color: theme }" />
</li>
{{
currentValue
}}
</ul>
<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',
`${
half && isHalf && index === Math.ceil(currentValue)
? 'layui-icon-rate-half'
: 'layui-icon-rate-solid'
}`,
]"
:style="{ color: theme }"
/>
<i v-else class="layui-icon layui-icon-rate" :style="{ color: theme }"/>
</li>
</ul>
<template v-if="text">
<span class="layui-inline">
<slot :value="currentValue">
{{ currentValue + '星' }}
</slot>
</span>
</template>
</div>
</template>