common.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { computed, Ref, ref } from 'vue';
  2. import { createComponent } from '@/packages/utils/create';
  3. import { pxCheck } from '@/packages/utils/pxCheck';
  4. import { useTouch } from '@/packages/utils/useTouch';
  5. const { componentName } = createComponent('rate');
  6. const useComponent = (touchable: Boolean = true) => {
  7. return {
  8. props: {
  9. count: {
  10. type: [String, Number],
  11. default: 5
  12. },
  13. modelValue: {
  14. type: [String, Number],
  15. default: 0
  16. },
  17. iconSize: {
  18. type: [String, Number],
  19. default: 18
  20. },
  21. activeColor: {
  22. type: String,
  23. default: ''
  24. },
  25. voidColor: {
  26. type: String,
  27. default: ''
  28. },
  29. uncheckedIcon: {
  30. type: String,
  31. default: 'star-n'
  32. },
  33. checkedIcon: {
  34. type: String,
  35. default: 'star-fill-n'
  36. },
  37. readonly: {
  38. type: Boolean,
  39. default: false
  40. },
  41. disabled: {
  42. type: Boolean,
  43. default: false
  44. },
  45. allowHalf: {
  46. type: Boolean,
  47. default: false
  48. },
  49. touchable: {
  50. type: Boolean,
  51. default: true
  52. },
  53. spacing: {
  54. type: [String, Number],
  55. default: 14
  56. },
  57. classPrefix: {
  58. type: String,
  59. default: 'nut-icon'
  60. },
  61. fontClassName: {
  62. type: String,
  63. default: 'nutui-iconfont'
  64. }
  65. },
  66. emits: ['update:modelValue', 'change'],
  67. setup(props: any, { emit }: any) {
  68. const rateRefs = ref<HTMLElement[]>([]);
  69. const classes = computed(() => {
  70. const prefixCls = componentName;
  71. return {
  72. [prefixCls]: true
  73. };
  74. });
  75. const updateVal = (value: number) => {
  76. emit('update:modelValue', value);
  77. emit('change', value);
  78. };
  79. const onClick = (e: number, index: number) => {
  80. if (props.disabled || props.readonly) return;
  81. let value = 0;
  82. if (index === 1 && props.modelValue === index) {
  83. } else {
  84. value = index;
  85. if (props.allowHalf && e == 2) {
  86. value -= 0.5;
  87. }
  88. }
  89. updateVal(value);
  90. };
  91. const getScoreByPosition = (x: number, rateRefs: Ref<HTMLElement[]>, allowHalf: boolean) => {
  92. let v = 0;
  93. for (let index = rateRefs.value.length - 1; index >= 0; index--) {
  94. const item = rateRefs.value[index];
  95. if (x > item.offsetLeft) {
  96. if (allowHalf) {
  97. v = index + (x > item.offsetLeft + item.clientWidth / 2 ? 1 : 0.5);
  98. } else {
  99. v = index + 1;
  100. }
  101. break;
  102. }
  103. }
  104. return v;
  105. };
  106. const touch = useTouch();
  107. const touchMethods = {
  108. onTouchStart(event: Event) {
  109. if (!props.touchable || props.readonly) return;
  110. touch.start(event);
  111. },
  112. onTouchMove(event: Event) {
  113. if (!props.touchable || !touchable) return;
  114. touch.move(event);
  115. if (touch.isHorizontal()) {
  116. if (rateRefs.value) {
  117. event.preventDefault();
  118. updateVal(getScoreByPosition(touch.moveX.value, rateRefs, props.allowHalf));
  119. }
  120. }
  121. }
  122. };
  123. const refRandomId = Math.random().toString(36).slice(-8);
  124. return {
  125. classes,
  126. ...touchMethods,
  127. onClick,
  128. pxCheck,
  129. rateRefs,
  130. refRandomId
  131. };
  132. }
  133. };
  134. };
  135. // import { useTaroRect } from '@/packages/utils/useTaroRect';
  136. // const getScoreByPositionTaro = async (x: number, rateRefs: Ref<HTMLElement[]>, allowHalf: boolean) => {
  137. // let v = 0;
  138. // for (let index = rateRefs.value.length - 1; index >= 0; index--) {
  139. // const _item = rateRefs.value[index];
  140. // let item = await useTaroRect(_item, Taro);
  141. // if (x > (item.left)) {
  142. // if (allowHalf) {
  143. // v = index + (x > item.left + item.width / 2 ? 1 : 0.5);
  144. // } else {
  145. // v = index + 1;
  146. // }
  147. // break;
  148. // }
  149. // }
  150. // return v;
  151. // };
  152. export const component = useComponent();
  153. export const taroComponent = useComponent(false);