tui-zxtabs.vue 4.9 KB

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