index.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <div class="nut-progress">
  3. <div
  4. class="nut-progress-outer"
  5. ref="progressOuter"
  6. :class="[showText && !textInside ? 'nut-progress-outer-part' : '', size ? 'nut-progress-' + size : '']"
  7. :style="{ height: height }"
  8. >
  9. <div :class="['nut-progress-inner', status == 'active' ? 'nut-active' : '']" :style="bgStyle">
  10. <div
  11. class="nut-progress-text nut-progress-insidetext"
  12. :style="{ lineHeight: height, left: left }"
  13. v-if="showText && textInside"
  14. >
  15. <span :style="textStyle">{{ percentage }}%</span>
  16. </div>
  17. </div>
  18. </div>
  19. <div class="nut-progress-text" :style="{ lineHeight: height }" v-if="showText && !textInside">
  20. <template v-if="status == 'active' || status == ''">
  21. <span :style="textStyle">{{ percentage }}%</span>
  22. </template>
  23. <template v-else-if="status == 'icon'">
  24. <nut-icon size="16px" :name="iconName" :color="iconColor"></nut-icon>
  25. </template>
  26. </div>
  27. </div>
  28. </template>
  29. <script lang="ts">
  30. import { computed, onMounted, provide, reactive, nextTick, ref, watch } from 'vue';
  31. import { createComponent } from '../../utils/create';
  32. const { create } = createComponent('progress');
  33. export default create({
  34. props: {
  35. percentage: {
  36. type: [Number, String],
  37. default: 0,
  38. required: true
  39. },
  40. size: {
  41. type: String,
  42. default: 'base'
  43. },
  44. status: {
  45. type: String,
  46. default: ''
  47. },
  48. strokeWidth: {
  49. type: [Number, String],
  50. default: ''
  51. },
  52. textInside: {
  53. type: Boolean,
  54. default: false
  55. },
  56. showText: {
  57. type: Boolean,
  58. default: true
  59. },
  60. strokeColor: {
  61. type: String,
  62. default: ''
  63. },
  64. textColor: {
  65. tyep: String,
  66. default: ''
  67. },
  68. iconName: {
  69. type: String,
  70. default: 'checked'
  71. },
  72. iconColor: {
  73. type: String,
  74. default: '#439422'
  75. }
  76. },
  77. setup(props, { emit }) {
  78. const height = ref(props.strokeWidth + 'px');
  79. const progressOuter = ref();
  80. const left = ref();
  81. const bgStyle = computed(() => {
  82. return {
  83. width: props.percentage + '%',
  84. background: props.strokeColor || ''
  85. };
  86. });
  87. const textStyle = computed(() => {
  88. return {
  89. color: props.textColor || ''
  90. };
  91. });
  92. watch(
  93. () => props.percentage,
  94. (values) => {
  95. // console.log(
  96. // 'progressOuter.value.offsetWidth',
  97. // progressOuter.value.offsetWidth
  98. // );
  99. // console.log('values', values);
  100. left.value = progressOuter.value.offsetWidth * Number(values) * 0.01 - 5 + 'px';
  101. }
  102. );
  103. onMounted(() => {
  104. left.value = progressOuter.value.offsetWidth * Number(props.percentage) * 0.01 - 5 + 'px';
  105. });
  106. return {
  107. height,
  108. bgStyle,
  109. textStyle,
  110. progressOuter,
  111. left
  112. };
  113. }
  114. });
  115. </script>