mirror of
https://gitee.com/wot-design-uni/wot-design-uni.git
synced 2025-12-07 09:38:44 +08:00
parent
0e3195059e
commit
9d34f2e5d9
@ -11,7 +11,6 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
|
||||||
const value = ref<number>(1)
|
const value = ref<number>(1)
|
||||||
|
|
||||||
function changeValue({ value }) {
|
function changeValue({ value }) {
|
||||||
@ -60,6 +59,14 @@ function changeValue({ value }) {
|
|||||||
<wd-rate v-model="value" size="30px" space="10px"/>
|
<wd-rate v-model="value" size="30px" space="10px"/>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 允许半选
|
||||||
|
|
||||||
|
设置 `allowHalf` 属性。
|
||||||
|
|
||||||
|
```html
|
||||||
|
<wd-rate v-model="value" allow-half />
|
||||||
|
```
|
||||||
|
|
||||||
## Attributes
|
## Attributes
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
|
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
|
||||||
@ -75,6 +82,7 @@ function changeValue({ value }) {
|
|||||||
| active-icon | 选中的图标类名 | string | - | wd-icon-star-on | - |
|
| active-icon | 选中的图标类名 | string | - | wd-icon-star-on | - |
|
||||||
| disabled | 是否禁用 | boolean | - | false | - |
|
| disabled | 是否禁用 | boolean | - | false | - |
|
||||||
| disabled-color | 禁用的图标颜色 | string | - | linear-gradient(315deg, rgba(177,177,177,1) 0%,rgba(199,199,199,1) 100%) | - |
|
| disabled-color | 禁用的图标颜色 | string | - | linear-gradient(315deg, rgba(177,177,177,1) 0%,rgba(199,199,199,1) 100%) | - |
|
||||||
|
| allow-half | 是否允许半选 | boolean | - | false | $LOWEST_VERSION$ |
|
||||||
|
|
||||||
## Events
|
## Events
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
* @Author: weisheng
|
* @Author: weisheng
|
||||||
* @Date: 2023-07-29 17:03:39
|
* @Date: 2023-07-29 17:03:39
|
||||||
* @LastEditTime: 2024-03-17 20:19:52
|
* @LastEditTime: 2025-02-13 23:36:41
|
||||||
* @LastEditors: weisheng
|
* @LastEditors: weisheng
|
||||||
* @Description:
|
* @Description:
|
||||||
* @FilePath: /wot-design-uni/src/pages/rate/Index.vue
|
* @FilePath: /wot-design-uni/src/pages/rate/Index.vue
|
||||||
@ -41,6 +41,10 @@
|
|||||||
<demo-block title="修改size、space">
|
<demo-block title="修改size、space">
|
||||||
<wd-rate v-model="value7" space="10px" size="30px" />
|
<wd-rate v-model="value7" space="10px" size="30px" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
|
<demo-block title="允许半选">
|
||||||
|
<wd-rate v-model="value8" allow-half />
|
||||||
|
</demo-block>
|
||||||
</page-wraper>
|
</page-wraper>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -53,6 +57,7 @@ const value4 = ref<number>(3)
|
|||||||
const value5 = ref<number>(4)
|
const value5 = ref<number>(4)
|
||||||
const value6 = ref<number>(3)
|
const value6 = ref<number>(3)
|
||||||
const value7 = ref<number>(5)
|
const value7 = ref<number>(5)
|
||||||
|
const value8 = ref<number>(2.5)
|
||||||
|
|
||||||
function changeValue1({ value }: any) {
|
function changeValue1({ value }: any) {
|
||||||
console.log(value)
|
console.log(value)
|
||||||
|
|||||||
@ -9,16 +9,17 @@
|
|||||||
@include e(item) {
|
@include e(item) {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
touch-action: none; // 禁用默认触摸行为
|
||||||
}
|
}
|
||||||
@include e(item-star) {
|
@include edeep(item-star) {
|
||||||
display: inline-block;
|
-webkit-background-clip: text !important;
|
||||||
vertical-align: top;
|
color: transparent;
|
||||||
|
}
|
||||||
@include m(active) {
|
@include e(item-half) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
width: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,5 +85,12 @@ export const rateProps = {
|
|||||||
* 类型: string
|
* 类型: string
|
||||||
* 默认值: 'linear-gradient(315deg, rgba(177,177,177,1) 0%,rgba(199,199,199,1) 100%)'
|
* 默认值: 'linear-gradient(315deg, rgba(177,177,177,1) 0%,rgba(199,199,199,1) 100%)'
|
||||||
*/
|
*/
|
||||||
disabledColor: makeStringProp('linear-gradient(315deg, rgba(177,177,177,1) 0%,rgba(199,199,199,1) 100%)')
|
disabledColor: makeStringProp('linear-gradient(315deg, rgba(177,177,177,1) 0%,rgba(199,199,199,1) 100%)'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否允许半选
|
||||||
|
* 类型: boolean
|
||||||
|
* 默认值: false
|
||||||
|
*/
|
||||||
|
allowHalf: makeBooleanProp(false)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="`wd-rate ${customClass}`" :style="customStyle">
|
<view :class="`wd-rate ${customClass}`" :style="customStyle" @touchmove="onTouchMove">
|
||||||
<view
|
<view
|
||||||
v-for="(rate, index) in rateList"
|
v-for="(rate, index) in rateList"
|
||||||
:key="index"
|
:key="index"
|
||||||
:data-index="index"
|
:data-index="index"
|
||||||
:style="{ 'margin-right': index == rateList.length - 1 ? 0 : space }"
|
:style="{ 'margin-right': index == rateList.length - 1 ? 0 : space }"
|
||||||
class="wd-rate__item"
|
class="wd-rate__item"
|
||||||
@click="changeRate(index)"
|
|
||||||
>
|
>
|
||||||
<view class="wd-rate__item-star" :style="{ width: size, height: size }">
|
<wd-icon
|
||||||
<wd-icon :name="icon" :size="size" :custom-style="iconStyle" />
|
custom-class="wd-rate__item-star"
|
||||||
</view>
|
:name="isActive(rate) ? activeIcon : icon"
|
||||||
<view class="wd-rate__item-star wd-rate__item-star--active" :style="{ width: rate, height: size }">
|
:size="size"
|
||||||
<wd-icon :name="activeIcon" :size="size" :custom-style="iconActiveStyle" />
|
:custom-style="rate === '100%' ? iconActiveStyle : iconStyle"
|
||||||
|
@click="changeRate(index, false)"
|
||||||
|
/>
|
||||||
|
<view v-if="props.allowHalf" class="wd-rate__item-half" @click.stop="changeRate(index, true)">
|
||||||
|
<wd-icon
|
||||||
|
custom-class="wd-rate__item-star"
|
||||||
|
:name="isActive(rate) ? activeIcon : icon"
|
||||||
|
:size="size"
|
||||||
|
:custom-style="rate !== '0' ? iconActiveStyle : iconStyle"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -30,8 +38,10 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import wdIcon from '../wd-icon/wd-icon.vue'
|
import wdIcon from '../wd-icon/wd-icon.vue'
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, getCurrentInstance, ref, watch } from 'vue'
|
||||||
import { rateProps } from './types'
|
import { rateProps } from './types'
|
||||||
|
import { getRect } from '../common/util'
|
||||||
|
const { proxy } = getCurrentInstance() as any
|
||||||
|
|
||||||
const props = defineProps(rateProps)
|
const props = defineProps(rateProps)
|
||||||
const emit = defineEmits(['update:modelValue', 'change'])
|
const emit = defineEmits(['update:modelValue', 'change'])
|
||||||
@ -40,11 +50,11 @@ const rateList = ref<Array<string>>([])
|
|||||||
const activeValue = ref<string>('')
|
const activeValue = ref<string>('')
|
||||||
|
|
||||||
const iconStyle = computed(() => {
|
const iconStyle = computed(() => {
|
||||||
return `background:${props.color}; -webkit-background-clip: text; color: transparent`
|
return `background:${props.color};`
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconActiveStyle = computed(() => {
|
const iconActiveStyle = computed(() => {
|
||||||
return `background:${props.disabled ? props.disabledColor : activeValue.value}; -webkit-background-clip: text; color: transparent`
|
return `background:${props.disabled ? props.disabledColor : activeValue.value};`
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -72,11 +82,16 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 当前选项是否为激活状态
|
||||||
|
const isActive = (rate: string) => {
|
||||||
|
return rate !== '0'
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 计算当前应当展示的rate数量
|
* @description 计算当前应当展示的rate数量
|
||||||
*/
|
*/
|
||||||
function computeRateList() {
|
function computeRateList() {
|
||||||
const { modelValue, num } = props
|
const { modelValue, num, allowHalf } = props
|
||||||
// value和num都准备好才能计算
|
// value和num都准备好才能计算
|
||||||
if (modelValue === null || !num) return
|
if (modelValue === null || !num) return
|
||||||
if (typeof modelValue !== 'number') {
|
if (typeof modelValue !== 'number') {
|
||||||
@ -84,13 +99,12 @@ function computeRateList() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const tempRateList: string[] = []
|
const tempRateList: string[] = []
|
||||||
const fullLength = Math.ceil(modelValue) - 1
|
const fullLength = Math.floor(modelValue)
|
||||||
for (let i = 0; i < num; i++) {
|
for (let i = 0; i < num; i++) {
|
||||||
if (i < fullLength) {
|
if (i < fullLength) {
|
||||||
tempRateList.push('100%')
|
tempRateList.push('100%')
|
||||||
} else if (i === fullLength) {
|
} else if (i === fullLength && allowHalf && modelValue % 1 !== 0) {
|
||||||
const rate = modelValue - fullLength > 0.5 ? 1 : 0.5
|
tempRateList.push('50%')
|
||||||
tempRateList.push(rate * 100 + '%')
|
|
||||||
} else {
|
} else {
|
||||||
tempRateList.push('0')
|
tempRateList.push('0')
|
||||||
}
|
}
|
||||||
@ -113,15 +127,32 @@ function computeActiveValue() {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @description 点击icon触发组件的change事件
|
* @description 点击icon触发组件的change事件
|
||||||
* @param Event
|
|
||||||
*/
|
*/
|
||||||
function changeRate(index: number) {
|
function changeRate(index: number, isHalf: boolean) {
|
||||||
if (props.readonly || props.disabled) return
|
if (props.readonly || props.disabled) return
|
||||||
emit('update:modelValue', index + 1)
|
const value = isHalf ? index + 0.5 : index + 1
|
||||||
|
emit('update:modelValue', value)
|
||||||
emit('change', {
|
emit('change', {
|
||||||
value: index + 1
|
value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onTouchMove(event: TouchEvent) {
|
||||||
|
const { clientX } = event.touches[0]
|
||||||
|
const rateItems = await getRect('.wd-rate__item', true, proxy)
|
||||||
|
const targetIndex = Array.from(rateItems).findIndex((rect) => {
|
||||||
|
return clientX >= rect.left! && clientX <= rect.right!
|
||||||
|
})
|
||||||
|
if (targetIndex !== -1) {
|
||||||
|
const target = rateItems[targetIndex]
|
||||||
|
const itemWidth = target.width!
|
||||||
|
const isHalf = props.allowHalf && clientX - target.left! < itemWidth / 2
|
||||||
|
const value = isHalf ? targetIndex + 0.5 : targetIndex + 1
|
||||||
|
if (value >= 0.5) {
|
||||||
|
changeRate(targetIndex, isHalf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import './index.scss';
|
@import './index.scss';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user