From 2902814e629de00acfdb66bbd08b2e4f8ed3ffcf Mon Sep 17 00:00:00 2001 From: ElsaOOo Date: Wed, 4 Aug 2021 17:18:37 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0rate=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/rate/demo/basic/index.tsx | 34 ++++++ devui/rate/demo/customize/index.tsx | 40 +++++++ devui/rate/demo/only-read/index.tsx | 24 ++++ devui/rate/demo/rate-demo.tsx | 48 ++++++-- devui/rate/demo/type/index.tsx | 36 ++++++ devui/rate/doc/api-cn.md | 26 +++-- devui/rate/doc/api-en.md | 24 ++-- devui/rate/rate.scss | 70 ++++++++++++ devui/rate/rate.tsx | 168 ++++++++++++++++++++++++++-- devui/rate/use-rate.ts | 39 +++++++ 10 files changed, 470 insertions(+), 39 deletions(-) create mode 100644 devui/rate/demo/basic/index.tsx create mode 100644 devui/rate/demo/customize/index.tsx create mode 100644 devui/rate/demo/only-read/index.tsx create mode 100644 devui/rate/demo/type/index.tsx create mode 100644 devui/rate/rate.scss create mode 100644 devui/rate/use-rate.ts diff --git a/devui/rate/demo/basic/index.tsx b/devui/rate/demo/basic/index.tsx new file mode 100644 index 00000000..2a0afb0a --- /dev/null +++ b/devui/rate/demo/basic/index.tsx @@ -0,0 +1,34 @@ +import { defineComponent, ref } from 'vue'; +import DRate from '../../rate'; + +export default defineComponent({ + name: 'BasicRate', + components: { + DRate, + }, + props: {}, + setup() { + const value = ref(2); + const onUpdateValue = (newVal: number) => { + value.value = newVal; + }; + return { + value, + onUpdateValue, + }; + }, + render() { + const { value, onUpdateValue } = this; + const doNew = { + 'onUpdate:value': onUpdateValue, + }; + return ( + <> +
+ +
+
{value} star
+ + ); + }, +}); diff --git a/devui/rate/demo/customize/index.tsx b/devui/rate/demo/customize/index.tsx new file mode 100644 index 00000000..2e44d316 --- /dev/null +++ b/devui/rate/demo/customize/index.tsx @@ -0,0 +1,40 @@ +import { defineComponent, ref } from 'vue'; +import DRate from '../../rate'; + +export default defineComponent({ + name: 'BasicRate', + components: { + DRate, + }, + props: {}, + setup() { + const value = ref(3); + const onUpdateValue = (newVal: number) => { + value.value = newVal; + }; + return { + value, + onUpdateValue, + }; + }, + render() { + const { value, onUpdateValue } = this; + const doNew = { + 'onUpdate:value': onUpdateValue, + }; + return ( + <> +
+ +
+
{value} A
+ + ); + }, +}); diff --git a/devui/rate/demo/only-read/index.tsx b/devui/rate/demo/only-read/index.tsx new file mode 100644 index 00000000..354704ff --- /dev/null +++ b/devui/rate/demo/only-read/index.tsx @@ -0,0 +1,24 @@ +import { defineComponent, ref } from 'vue'; +import DRate from '../../rate'; + +export default defineComponent({ + name: 'OnlyRead', + components: { + DRate, + }, + props: {}, + setup() { + const value = ref(3.5); + return { + value, + }; + }, + render() { + const { value } = this; + return ( +
+ +
+ ); + }, +}); diff --git a/devui/rate/demo/rate-demo.tsx b/devui/rate/demo/rate-demo.tsx index a735c81a..6461b839 100644 --- a/devui/rate/demo/rate-demo.tsx +++ b/devui/rate/demo/rate-demo.tsx @@ -1,12 +1,42 @@ -import { defineComponent } from 'vue' +import { defineComponent } from 'vue'; +import { useDemo } from 'hooks/use-demo'; +import OnlyRead from './only-read/index'; +import OnlyReadCode from './only-read/index?raw'; +import BasicRate from './basic/index'; +import BasicRateCode from './basic/index?raw'; +import CustomizeRate from './customize/index'; +import CustomizeRateCode from './customize/index?raw'; +import TypeRate from './type/index'; +import TypeRateCode from './type/index?raw'; export default defineComponent({ - name: 'd-rate-demo', - props: { + name: 'DRateDemo', + render() { + return useDemo([ + { + id: 'only-read', + title: '只读模式', + code: OnlyReadCode, + content: , + }, + { + id: 'basic-rate', + title: '动态模式', + code: BasicRateCode, + content: , + }, + { + id: 'customize-rate', + title: '动态模式-自定义', + code: CustomizeRateCode, + content: , + }, + { + id: 'type-rate', + title: '使用type参数', + code: TypeRateCode, + content: , + }, + ]); }, - setup(props, ctx) { - return () => { - return
devui-rate-demo
- } - } -}) \ No newline at end of file +}); diff --git a/devui/rate/demo/type/index.tsx b/devui/rate/demo/type/index.tsx new file mode 100644 index 00000000..e67c1e77 --- /dev/null +++ b/devui/rate/demo/type/index.tsx @@ -0,0 +1,36 @@ +import { defineComponent, ref } from 'vue'; +import DRate from '../../rate'; + +export default defineComponent({ + name: 'BasicRate', + components: { + DRate, + }, + props: {}, + setup() { + const value1 = ref(5); + const value2 = ref(3); + const value3 = ref(2); + return { + value1, + value2, + value3, + }; + }, + render() { + const { value1, value2, value3 } = this; + return ( + <> +
+ +
+
+ +
+
+ +
+ + ); + }, +}); diff --git a/devui/rate/doc/api-cn.md b/devui/rate/doc/api-cn.md index 5a4e9733..cf963821 100644 --- a/devui/rate/doc/api-cn.md +++ b/devui/rate/doc/api-cn.md @@ -1,22 +1,26 @@ # 如何使用 -在module中引入: + +在 module 中引入: + ```ts -import { RateModule } from 'ng-devui/rate'; +import { DRate } from "devui"; ``` 在页面中使用: + ```html - + ``` + # Rate ## d-rate 参数 -| 参数 | 类型 | 默认值 | 描述 | 跳转 Demo | -| :-------: | :-----------------------------: | :---: | :------------------------------------------------------- | ------------------------------------------------------ | -| read | `boolean` | false | 可选,设置是否为只读模式,只读模式无法交互 | [只读模式](demo#read-only-mode) | -| count | `number` | 5 | 可选,设置总等级数 | [只读模式](demo#read-only-mode) | -| type | `'success'\|'warning'\|'error'` | -- | 可选,设置当前评分的类型,不同类型对应不同颜色 | [使用type参数](demo#using-the-type-parameter) | -| color | `string` | -- | 可选,星星颜色 | [动态模式-自定义](demo#dynamic-mode-Custom) | -| icon | `string` | -- | 可选,评分图标的样式,只支持 devUI 图标库中所有图标 | [动态模式](demo#dynamic-mode) | -| character | `string` | -- | 可选,评分图标的样式,icon 与 character 只能设置其中一个 | [动态模式-自定义](demo#dynamic-mode-Custom) | +| 参数 | 类型 | 默认值 | 描述 | 跳转 Demo | +| :-------: | :-----------------------------: | :----: | :------------------------------------------------------- | ----------------------------------------------- | +| read | `boolean` | false | 可选,设置是否为只读模式,只读模式无法交互 | [只读模式](demo#read-only-mode) | +| count | `number` | 5 | 可选,设置总等级数 | [只读模式](demo#read-only-mode) | +| type | `'success'\|'warning'\|'error'` | -- | 可选,设置当前评分的类型,不同类型对应不同颜色 | [使用 type 参数](demo#using-the-type-parameter) | +| color | `string` | -- | 可选,星星颜色 | [动态模式-自定义](demo#dynamic-mode-Custom) | +| icon | `string` | -- | 可选,评分图标的样式,只支持 devUI 图标库中所有图标 | [动态模式](demo#dynamic-mode) | +| character | `string` | -- | 可选,评分图标的样式,icon 与 character 只能设置其中一个 | [动态模式-自定义](demo#dynamic-mode-Custom) | diff --git a/devui/rate/doc/api-en.md b/devui/rate/doc/api-en.md index 75b44514..113fb856 100644 --- a/devui/rate/doc/api-en.md +++ b/devui/rate/doc/api-en.md @@ -1,22 +1,26 @@ # How to use + Import into module: + ```ts -import { RateModule } from 'ng-devui/rate'; +import { DRate } from "devui"; ``` In the page: + ```html - + ``` + # Rate ## d-rate parameter -| Parameter | Type | Default | Description | Jump to Demo | -| :-------: | :-----------------------------: | :---: | :------------------------------------------------------- | ------------------------------------------------------ | -| read | `boolean` | false | Optional. This parameter specifies whether to enable read-only mode. In read-only mode, interaction is not supported. | [Read-only Mode](demo#read-only-mode) | -| count | `number` | 5 | Optional. Sets the total number of levels. | [Read-only Mode](demo#read-only-mode) | -| type | `'success'\|'warning'\|'error'` | -- | Optional. Set the current rating type. Different types correspond to different colors. | [Use the type parameter](demo#using-the-type-parameter) | -| color | `string` | -- | Optional. Star color. | [Dynamic Mode-Custom](demo#dynamic-mode-Custom) | -| icon | `string` | -- | Optional. Style of the rating icon. Only all icons in the DevUI icon library are supported. | [Dynamic Mode](demo#dynamic-mode) | -| character | `string` | -- | Optional. Scoring icon style. Only one of icon and character can be set. | [Dynamic Mode-Custom](demo#dynamic-mode-Custom) | +| Parameter | Type | Default | Description | Jump to Demo | +| :-------: | :-----------------------------: | :-----: | :-------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | +| read | `boolean` | false | Optional. This parameter specifies whether to enable read-only mode. In read-only mode, interaction is not supported. | [Read-only Mode](demo#read-only-mode) | +| count | `number` | 5 | Optional. Sets the total number of levels. | [Read-only Mode](demo#read-only-mode) | +| type | `'success'\|'warning'\|'error'` | -- | Optional. Set the current rating type. Different types correspond to different colors. | [Use the type parameter](demo#using-the-type-parameter) | +| color | `string` | -- | Optional. Star color. | [Dynamic Mode-Custom](demo#dynamic-mode-Custom) | +| icon | `string` | -- | Optional. Style of the rating icon. Only all icons in the DevUI icon library are supported. | [Dynamic Mode](demo#dynamic-mode) | +| character | `string` | -- | Optional. Scoring icon style. Only one of icon and character can be set. | [Dynamic Mode-Custom](demo#dynamic-mode-Custom) | diff --git a/devui/rate/rate.scss b/devui/rate/rate.scss new file mode 100644 index 00000000..2e35ff05 --- /dev/null +++ b/devui/rate/rate.scss @@ -0,0 +1,70 @@ +@import '../style/theme/color'; +@import '../style/core/_font'; + +.devui-star-align { + font-size: $devui-font-size-icon; + margin-right: 5px; + position: relative; + line-height: 1; +} + +.devui-pointer { + cursor: pointer; +} + +.devui-star-container { + display: inline-flex; +} + +.devui-star-color-active { + color: #6a81ed; + line-height: 1.5; + + svg g { + fill: #6a81ed; + } +} + +.devui-star-color-success { + color: #3dcca6; + + svg g { + fill: #3dcca6; + } +} + +.devui-star-color-warning { + color: #fac20a; + + svg g { + fill: #fac20a; + } +} + +.devui-star-color-error { + color: #f66f6a; + + svg g { + fill: #f66f6a; + } +} + +.devui-active-star { + position: absolute; + top: 0; + left: 0; + overflow: hidden; +} + +.devui-star-color { + color: $devui-dividing-line; + line-height: 1.5; + + svg g { + fill: $devui-dividing-line; + } +} + +.devui-only-read { + cursor: not-allowed; +} diff --git a/devui/rate/rate.tsx b/devui/rate/rate.tsx index 33a175e3..bd6e7e83 100644 --- a/devui/rate/rate.tsx +++ b/devui/rate/rate.tsx @@ -1,12 +1,162 @@ -import { defineComponent } from 'vue' +import { defineComponent, onMounted, watch, reactive, ref } from 'vue'; +import { rateProps } from './use-rate'; +import './rate.scss'; export default defineComponent({ - name: 'd-rate', - props: { - }, + name: 'DRate', + props: rateProps, + emits: ['change', 'update:value'], setup(props, ctx) { - return () => { - return
devui-rate
- } - } -}) \ No newline at end of file + const totalLevel_array = reactive[]>([]); + const chooseValue = ref(0); + + // 根据mouseMove,mouseLeave,select等操作,改变颜色与是否选中 + const setChange = (start: number, end: number, width: string) => { + for (let i = start; i < end; i++) { + totalLevel_array[i]['width'] = width; + } + }; + + // 初始化设置 + const initRating = () => { + if (!props.value) { + return; + } + chooseValue.value = props.value - 1; + const half_star = chooseValue.value % 1; + const int_current_level = Math.floor(chooseValue.value); + setChange(0, int_current_level + 1, '100%'); + if (half_star > 0) { + totalLevel_array[int_current_level + 1]['width'] = + half_star * 100 + '%'; + setChange(int_current_level + 2, props.count, '0'); + } else { + setChange(int_current_level + 1, props.count, '0'); + } + }; + + onMounted(() => { + for (let i = 0; i < props.count; i++) { + totalLevel_array.push({ width: '0' }); + } + initRating(); + }); + + const hoverToggle = (_, index: number, reset = false) => { + if (props.read) { + return; + } + if (reset) { + if (chooseValue.value >= 0) { + setChange(0, chooseValue.value + 1, '100%'); + setChange(chooseValue.value + 1, props.count, '0'); + } else { + setChange(0, props.count, '0'); + } + } else { + setChange(0, index + 1, '100%'); + setChange(index + 1, props.count, '0'); + } + }; + + const selectValue = (index: number) => { + if (props.read) { + return; + } + setChange(0, index + 1, '100%'); + setChange(index + 1, props.count, '0'); + chooseValue.value = index; + props.onChange && props.onChange(index + 1); + props.onTouched && props.onTouched(); + ctx.emit('update:value', index + 1); + }; + return { + totalLevel_array, + chooseValue, + hoverToggle, + selectValue, + }; + }, + render() { + const { + totalLevel_array, + chooseValue, + icon, + character, + read, + type, + color, + hoverToggle, + selectValue, + } = this; + return ( +
hoverToggle(e, chooseValue, true)} + > + {totalLevel_array.map((item, index) => ( +
hoverToggle(e, index)} + onClick={() => selectValue(index)} + > + + {character} + {!icon && !character && ( + + + + + + + + )} + + + {character} + {!icon && !character && ( + + + + + + + + )} + +
+ ))} +
+ ); + }, +}); diff --git a/devui/rate/use-rate.ts b/devui/rate/use-rate.ts new file mode 100644 index 00000000..8adf7317 --- /dev/null +++ b/devui/rate/use-rate.ts @@ -0,0 +1,39 @@ +import { PropType } from 'vue'; + +export const rateProps = { + value: { + type: Number, + }, + read: { + type: Boolean, + default: false, + }, + count: { + type: Number, + default: 5, + }, + type: { + type: String as PropType<'success' | 'warning' | 'error'>, + default: '', + }, + color: { + type: String, + default: '', + }, + icon: { + type: String, + default: '', + }, + character: { + type: String, + default: '', + }, + onChange: { + type: Function as PropType<(value: number) => void>, + default: undefined, + }, + onTouched: { + type: Function as PropType<() => void>, + default: undefined, + }, +}; -- Gitee From 5e7fa4abfce9e8b5db23d04d79337e1d101fb8ec Mon Sep 17 00:00:00 2001 From: ElsaOOo Date: Thu, 5 Aug 2021 08:52:14 +0800 Subject: [PATCH 2/2] refactor: fix code review --- devui/rate/doc/api-cn.md | 2 +- devui/rate/doc/api-en.md | 2 +- devui/rate/rate.tsx | 29 ++++++++++++++--------------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/devui/rate/doc/api-cn.md b/devui/rate/doc/api-cn.md index cf963821..b54491e9 100644 --- a/devui/rate/doc/api-cn.md +++ b/devui/rate/doc/api-cn.md @@ -3,7 +3,7 @@ 在 module 中引入: ```ts -import { DRate } from "devui"; +import { DRate } from "vue-devui"; ``` 在页面中使用: diff --git a/devui/rate/doc/api-en.md b/devui/rate/doc/api-en.md index 113fb856..6904c6b3 100644 --- a/devui/rate/doc/api-en.md +++ b/devui/rate/doc/api-en.md @@ -3,7 +3,7 @@ Import into module: ```ts -import { DRate } from "devui"; +import { DRate } from "vue-devui"; ``` In the page: diff --git a/devui/rate/rate.tsx b/devui/rate/rate.tsx index bd6e7e83..85ceaafd 100644 --- a/devui/rate/rate.tsx +++ b/devui/rate/rate.tsx @@ -7,13 +7,13 @@ export default defineComponent({ props: rateProps, emits: ['change', 'update:value'], setup(props, ctx) { - const totalLevel_array = reactive[]>([]); + const totalLevelArray = reactive[]>([]); const chooseValue = ref(0); // 根据mouseMove,mouseLeave,select等操作,改变颜色与是否选中 const setChange = (start: number, end: number, width: string) => { for (let i = start; i < end; i++) { - totalLevel_array[i]['width'] = width; + totalLevelArray[i]['width'] = width; } }; @@ -23,21 +23,20 @@ export default defineComponent({ return; } chooseValue.value = props.value - 1; - const half_star = chooseValue.value % 1; - const int_current_level = Math.floor(chooseValue.value); - setChange(0, int_current_level + 1, '100%'); - if (half_star > 0) { - totalLevel_array[int_current_level + 1]['width'] = - half_star * 100 + '%'; - setChange(int_current_level + 2, props.count, '0'); + const halfStar = chooseValue.value % 1; + const intCurrentLevel = Math.floor(chooseValue.value); + setChange(0, intCurrentLevel + 1, '100%'); + if (halfStar > 0) { + totalLevelArray[intCurrentLevel + 1]['width'] = halfStar * 100 + '%'; + setChange(intCurrentLevel + 2, props.count, '0'); } else { - setChange(int_current_level + 1, props.count, '0'); + setChange(intCurrentLevel + 1, props.count, '0'); } }; onMounted(() => { for (let i = 0; i < props.count; i++) { - totalLevel_array.push({ width: '0' }); + totalLevelArray.push({ width: '0' }); } initRating(); }); @@ -71,7 +70,7 @@ export default defineComponent({ ctx.emit('update:value', index + 1); }; return { - totalLevel_array, + totalLevelArray, chooseValue, hoverToggle, selectValue, @@ -79,7 +78,7 @@ export default defineComponent({ }, render() { const { - totalLevel_array, + totalLevelArray, chooseValue, icon, character, @@ -94,12 +93,12 @@ export default defineComponent({ class="devui-star-container" onMouseleave={(e) => hoverToggle(e, chooseValue, true)} > - {totalLevel_array.map((item, index) => ( + {totalLevelArray.map((item, index) => (
hoverToggle(e, index)} onClick={() => selectValue(index)} > -- Gitee