tui-tabs.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <template>
  2. <view class="tui-tabs-view" :class="[isFixed?'tui-tabs-fixed':'tui-tabs-relative',unlined?'tui-unlined':'']" :style="{height:height+'rpx',padding:`0 ${padding}rpx`,background:bgColor,top:isFixed?top+'px':'auto'}">
  3. <view v-for="(item,index) in tabs" :key="index" class="tui-tabs-item" :style="{width:itemWidth}" @tap.stop="swichTabs(index)">
  4. <view class="tui-tabs-title" :class="{'tui-tabs-active':currentTab==index,'tui-tabs-disabled':item.disabled}" :style="{color:currentTab==index?selectedColor:color,fontSize:size+'rpx',lineHeight:size+'rpx',fontWeight:bold && currentTab==index?'bold':'normal'}">{{item.name}}</view>
  5. </view>
  6. </view>
  7. </template>
  8. <script>
  9. export default {
  10. name: "tuiTabs",
  11. props: {
  12. //标签页
  13. tabs: {
  14. type: Array,
  15. default () {
  16. return []
  17. }
  18. },
  19. //rpx
  20. height: {
  21. type: Number,
  22. default: 80
  23. },
  24. //rpx 只对左右padding起作用,上下为0
  25. padding: {
  26. type: Number,
  27. default: 30
  28. },
  29. //背景色
  30. bgColor: {
  31. type: String,
  32. default: "#FFFFFF"
  33. },
  34. //是否固定
  35. isFixed: {
  36. type: Boolean,
  37. default: false
  38. },
  39. //px
  40. top: {
  41. type: Number
  42. // #ifndef H5
  43. ,
  44. default: 0
  45. // #endif
  46. // #ifdef H5
  47. ,
  48. default: 44
  49. // #endif
  50. },
  51. //是否去掉底部线条
  52. unlined: {
  53. type: Boolean,
  54. default: false
  55. },
  56. //当前选项卡
  57. currentTab: {
  58. type: Number,
  59. default: 0
  60. },
  61. //滑块宽度
  62. sliderWidth: {
  63. type: Number,
  64. default: 68
  65. },
  66. //滑块高度
  67. sliderHeight: {
  68. type: Number,
  69. default: 6
  70. },
  71. //滑块背景颜色
  72. sliderBgColor: {
  73. type: String,
  74. default: "#C74547"
  75. },
  76. sliderRadius:{
  77. type: String,
  78. default: "50rpx"
  79. },
  80. //滑块bottom
  81. bottom: {
  82. type: String,
  83. default: "0"
  84. },
  85. //标签页宽度
  86. itemWidth: {
  87. type: String,
  88. default: "25%"
  89. },
  90. //字体颜色
  91. color: {
  92. type: String,
  93. default: "#666"
  94. },
  95. //选中后字体颜色
  96. selectedColor: {
  97. type: String,
  98. default: "#C74547"
  99. },
  100. //字体大小
  101. size: {
  102. type: Number,
  103. default: 28
  104. },
  105. //选中后 是否加粗 ,未选中则无效
  106. bold: {
  107. type: Boolean,
  108. default: false
  109. }
  110. },
  111. watch: {
  112. currentTab() {
  113. this.checkCor();
  114. }
  115. },
  116. created() {
  117. setTimeout(() => {
  118. // 高度自适应
  119. uni.getSystemInfo({
  120. success: (res) => {
  121. this.winWidth = res.windowWidth;
  122. this.checkCor()
  123. }
  124. });
  125. }, 50);
  126. },
  127. data() {
  128. return {
  129. winWidth: 0,
  130. scrollLeft: 0
  131. };
  132. },
  133. methods: {
  134. checkCor: function() {
  135. let tabsNum = this.tabs.length
  136. let padding = this.winWidth / 750 * this.padding
  137. let width = this.winWidth - padding * 2
  138. let left = (width / tabsNum - (this.winWidth / 750 * this.sliderWidth)) / 2 + padding
  139. let scrollLeft = left
  140. if (this.currentTab > 0) {
  141. scrollLeft = scrollLeft + (width / tabsNum) * this.currentTab
  142. }
  143. this.scrollLeft = scrollLeft
  144. },
  145. // 点击标题切换当前页时改变样式
  146. swichTabs: function(index) {
  147. let item = this.tabs[index]
  148. if (item && item.disabled) return;
  149. if (this.currentTab == index) {
  150. return false;
  151. } else {
  152. this.$emit("change", {
  153. index: Number(index)
  154. })
  155. }
  156. }
  157. }
  158. }
  159. </script>
  160. <style>
  161. .tui-tabs-view {
  162. width: 100%;
  163. box-sizing: border-box;
  164. display: flex;
  165. align-items: center;
  166. justify-content: space-between;
  167. z-index: 1;
  168. }
  169. .tui-tabs-relative {
  170. position: relative;
  171. }
  172. .tui-tabs-fixed {
  173. left: 0;
  174. }
  175. .tui-tabs-fixed::before,
  176. .tui-tabs-relative::before {
  177. content: '';
  178. position: absolute;
  179. border-bottom: 1upx solid #eaeef1;
  180. -webkit-transform: scaleY(0.5);
  181. transform: scaleY(0.5);
  182. bottom: 0;
  183. right: 0;
  184. left: 0;
  185. }
  186. .tui-unlined::before {
  187. border-bottom: 0 !important
  188. }
  189. .tui-tabs-item {
  190. display: flex;
  191. align-items: center;
  192. justify-content: center;
  193. margin: auto;
  194. }
  195. .tui-tabs-disabled {
  196. opacity: .6;
  197. }
  198. .tui-tabs-title {
  199. display: flex;
  200. align-items: center;
  201. justify-content: center;
  202. position: relative;
  203. z-index: 2;
  204. }
  205. .tui-tabs-active {
  206. transition: all 0.15s ease-in-out;
  207. }
  208. </style>