| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- <template>
- <view class="start-bar" :style="`--rate-size: ${size}rpx`">
- <block v-for="(item, index) in starts" :key="index">
- <view
- class="start"
- :class="item.active ? 'active' : ''"
- :data-score="item.score"
- @click="select"
- >
- </view>
- </block>
- </view>
- </template>
- <script lang="ts" setup>
- import { ref, watch } from 'vue';
- const props = defineProps({
- // 最大分值
- max: {
- type: Number,
- default: 5,
- },
- // 分数值
- score: {
- type: Number,
- default: 0,
- },
- // 是否只读
- disabled: {
- type: Boolean,
- default: false,
- },
- // 是否显示分数
- showScore: {
- type: Boolean,
- default: false,
- },
- size: {
- type: Number,
- default: 30,
- },
- });
- const starts = ref([]);
- const emits = defineEmits(['update:score', 'change']);
- const select = ({ target: { dataset } }) => {
- if (props.disabled) return;
- // 这里暂时不支持分数清零
- starts.value = starts.value.map((item) => {
- item.active = item.score <= dataset.score;
- return item;
- });
- emits('update:score', dataset.score);
- emits('change', dataset.score);
- };
- watch(
- () => [props.max, props.score],
- ([max, score]) => {
- starts.value = [];
- for (let i = 1; i <= max; i++) {
- starts.value.push({
- score: i,
- active: i <= score,
- });
- }
- },
- {
- immediate: true,
- }
- );
- </script>
- <style lang="scss" scoped>
- .start-bar {
- display: flex;
- justify-content: space-around;
- --rate-fill-color: #bebebe;
- --rate-size: 30rpx;
- }
- .start.active {
- --rate-fill-color: #f7ba2a;
- }
- .start,
- .start::before,
- .start::after {
- width: 0;
- height: 0;
- border-top: calc(var(--rate-size) / 1.2) solid var(--rate-fill-color);
- border-right: var(--rate-size) solid transparent;
- border-left: var(--rate-size) solid transparent;
- overflow: visible;
- }
- .start {
- margin: calc(var(--rate-size) / 2);
- position: relative;
- display: block;
- color: var(--rate-fill-color);
- }
- .start::before,
- .start::after {
- content: '';
- display: block;
- position: absolute;
- left: calc(var(--rate-size) * -1);
- top: calc(var(--rate-size) / -1.3);
- }
- .start::before {
- transform: rotate(68deg);
- }
- .start::after {
- transform: rotate(-68deg);
- }
- </style>
|