tui-steps.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <template>
  2. <view class="tui-steps-box" :class="{ 'tui-steps-column': direction === 'column' }">
  3. <view class="tui-step-item" :style="{ width: direction === 'column' ? '100%' : spacing }"
  4. :class="[direction === 'row' ? 'tui-step-horizontal' : 'tui-step-vertical']" v-for="(item, index) in items"
  5. :key="index" @tap.stop="handleClick(index)">
  6. <view class="tui-step-item-ico" :class="[direction === 'column' ? 'tui-step-column_ico' : 'tui-step-row_ico']" :style="{ width: direction === 'column' ? '36rpx' : '100%' }">
  7. <view v-if="!item.name && !item.icon" class="tui-step-ico"
  8. :style="{
  9. width: type == 2 || activeSteps === index ? '36rpx' : '16rpx',
  10. height: type == 2 || activeSteps === index ? '36rpx' : '16rpx',
  11. backgroundColor: index <= activeSteps ? activeColor : type == 2 ? '#fff' : deactiveColor,
  12. borderColor: index <= activeSteps ? activeColor : deactiveColor
  13. }">
  14. <text v-if="activeSteps !== index"
  15. :style="{ color: index <= activeSteps ? '#fff' : '' }">{{ type == 1 ? '' : index + 1 }}</text>
  16. <tui-icon name="check" :size="16" color="#fff" v-if="activeSteps === index"></tui-icon>
  17. </view>
  18. <view class="tui-step-custom" :style="{ backgroundColor: backgroundColor }"
  19. v-if="item.name || item.icon">
  20. <tui-icon :name="item.name" :size="item.size || 20" :color="index <= activeSteps ? activeColor : deactiveColor"
  21. v-if="item.name"></tui-icon>
  22. <image :src="index <= activeSteps ? item.activeIcon : item.icon" class="tui-step-img"
  23. mode="widthFix" v-if="!item.name"></image>
  24. </view>
  25. <view class="tui-step-line"
  26. :class="['tui-step-' + direction + '_line', direction == 'column' && (item.name || item.icon) ? 'tui-custom-left' : '']"
  27. :style="{
  28. borderColor: index <= activeSteps - 1 ? activeColor : deactiveColor,
  29. borderRightStyle: direction == 'column' ? lineStyle : '',
  30. borderTopStyle: direction == 'column' ? '' : lineStyle
  31. }" v-if="index != items.length - 1"></view>
  32. </view>
  33. <view class="tui-step-item-main" :class="['tui-step-' + direction + '_item_main']">
  34. <view class="tui-step-item-title" :style="{
  35. color: index <= activeSteps ? activeColor : deactiveColor,
  36. fontSize: titleSize + 'rpx',
  37. lineHeight: titleSize + 'rpx',
  38. fontWeight: bold ? 'bold' : 'normal'
  39. }">
  40. {{ item.title }}
  41. </view>
  42. <view class="tui-step-item-content"
  43. :style="{ color: index <= activeSteps ? activeColor : deactiveColor, fontSize: descSize + 'rpx' }">
  44. {{ item.desc }}</view>
  45. </view>
  46. </view>
  47. </view>
  48. </template>
  49. <script>
  50. //如果自定义传入图标内容,则需要拆分组件
  51. export default {
  52. name: 'tuiSteps',
  53. emits: ['click'],
  54. props: {
  55. // 1-默认步骤 2-数字步骤
  56. type: {
  57. type: Number,
  58. default: 1
  59. },
  60. spacing: {
  61. type: String,
  62. default: '160rpx'
  63. },
  64. // 方向 row column
  65. direction: {
  66. type: String,
  67. default: 'row'
  68. },
  69. // 激活状态成功颜色
  70. activeColor: {
  71. type: String,
  72. default: '#5677fc'
  73. },
  74. // 未激活状态颜色
  75. deactiveColor: {
  76. type: String,
  77. default: '#999999'
  78. },
  79. //title字体大小
  80. titleSize: {
  81. type: Number,
  82. default: 28
  83. },
  84. //title是否粗体
  85. bold: {
  86. type: Boolean,
  87. default: false
  88. },
  89. //desc字体大小
  90. descSize: {
  91. type: Number,
  92. default: 24
  93. },
  94. // 当前步骤
  95. activeSteps: {
  96. type: Number,
  97. default: -1
  98. },
  99. //线条样式 同border线条样式
  100. lineStyle: {
  101. type: String,
  102. default: 'solid'
  103. },
  104. /**
  105. * [{
  106. title: "标题",
  107. desc: "描述",
  108. name:"字体图标 thorui icon内",
  109. size:字体图标大小,单位px
  110. icon:"图片图标",
  111. activeIcon:"已完成步骤显示图片图标"
  112. }]
  113. * */
  114. items: {
  115. type: Array,
  116. default () {
  117. return [];
  118. }
  119. },
  120. //自定义item内容时背景色
  121. backgroundColor: {
  122. type: String,
  123. default: '#fff'
  124. }
  125. },
  126. data() {
  127. return {};
  128. },
  129. methods: {
  130. handleClick(index) {
  131. this.$emit('click', {
  132. index: index
  133. });
  134. }
  135. }
  136. };
  137. </script>
  138. <style scoped>
  139. .tui-steps-box {
  140. width: 100%;
  141. display: flex;
  142. justify-content: center;
  143. }
  144. .tui-steps-column {
  145. flex-direction: column;
  146. }
  147. .tui-step-ico {
  148. border-radius: 50%;
  149. position: relative;
  150. z-index: 3;
  151. margin: 0 auto;
  152. border-width: 1rpx;
  153. border-style: solid;
  154. display: inline-flex;
  155. align-items: center;
  156. justify-content: center;
  157. flex-shrink: 0;
  158. }
  159. .tui-step-row_ico {
  160. align-items: center;
  161. }
  162. .tui-step-column_ico {
  163. align-items: flex-start;
  164. }
  165. .tui-step-line {
  166. position: absolute;
  167. left: 50%;
  168. top: 20rpx;
  169. width: 100%;
  170. height: 0rpx;
  171. border-top-width: 1px;
  172. z-index: 2;
  173. transform: translateY(-50%) translateZ(0);
  174. }
  175. .tui-step-row_item_main {
  176. text-align: center;
  177. }
  178. .tui-step-item {
  179. font-size: 24rpx;
  180. position: relative;
  181. box-sizing: border-box;
  182. }
  183. .tui-step-item-ico {
  184. height: 36rpx;
  185. display: flex;
  186. justify-content: center;
  187. }
  188. .tui-step-custom {
  189. display: flex;
  190. align-items: center;
  191. justify-content: center;
  192. width: 48rpx;
  193. height: 40rpx;
  194. position: relative;
  195. z-index: 4;
  196. margin: 0 auto;
  197. }
  198. .tui-step-img {
  199. width: 40rpx;
  200. height: 40rpx;
  201. }
  202. .tui-step-item-main {
  203. margin-top: 16rpx;
  204. clear: both;
  205. }
  206. .tui-step-item-title {
  207. word-break: break-all;
  208. }
  209. .tui-step-item-content {
  210. margin-top: 8rpx;
  211. word-break: break-all;
  212. }
  213. .tui-step-vertical {
  214. width: 100%;
  215. display: flex;
  216. padding-bottom: 60rpx;
  217. }
  218. .tui-step-column_item_main {
  219. margin-top: 0;
  220. padding-left: 20rpx;
  221. max-width: 80%;
  222. }
  223. .tui-step-column_line {
  224. position: absolute;
  225. height: 100%;
  226. top: 0;
  227. left: 18rpx;
  228. margin: 0;
  229. width: 0rpx;
  230. border-right-width: 1px;
  231. transform: none !important;
  232. }
  233. .tui-custom-left {
  234. left: 20rpx !important;
  235. }
  236. </style>