tabs.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <template>
  2. <view class="tui-tabs-view" :class="[isFixed?'tui-tabs-fixed':'tui-tabs-relative',unlined?'tui-unlined':'', isBoxShadow? 'tui-tabs-view-shadow': '']" :style="{height:height+'rpx',padding:`0 ${padding}rpx`,background:bgColor,top:isFixed?top+'px':'auto'}">
  3. <div class="item-wrap" :style="{width: isAdd ? `calc(100% - ${addTabWidth + 30}rpx)` : '100%'}">
  4. <view v-for="(item,index) in tabs" :key="index" class="tui-tabs-item" :class="{'border-left': borderLeft}" :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="{fontSize:size+'rpx',lineHeight:size+'rpx',fontWeight:bold && currentTab==index?'bold':'normal'}">
  6. <div class="tabs-title">{{item.name}}</div>
  7. <!-- tab value -->
  8. <div class="tabs-value" v-if="item.value || item.value == 0">{{ item.value }}</div>
  9. </view>
  10. </view>
  11. </div>
  12. <!-- tab add -->
  13. <div class="tabs-add" v-if="isAdd" :style="{width: `${addTabWidth}rpx`}" @click="add">
  14. <i class="iconfont" :class="[addIcon]"></i>
  15. <span>{{ addText }}</span>
  16. </div>
  17. <view class="tui-tabs-slider" :style="{transform:'translateX('+scrollLeft+'px)',width:sliderWidth+'rpx',height:
  18. sliderHeight+'rpx',borderRadius:sliderRadius,bottom:bottom,marginBottom:bottom=='50%'?('-'+sliderHeight/2+'rpx'):0}"></view>
  19. </view>
  20. </template>
  21. <script>
  22. export default {
  23. name: 'tuiTabs',
  24. props: {
  25. // 标签页
  26. tabs: {
  27. type: Array,
  28. default() {
  29. return []
  30. }
  31. },
  32. // rpx
  33. height: {
  34. type: Number,
  35. default: 80
  36. },
  37. // rpx 只对左右padding起作用,上下为0
  38. padding: {
  39. type: Number,
  40. default: 30
  41. },
  42. // 背景色
  43. bgColor: {
  44. type: String,
  45. default: '#FFFFFF'
  46. },
  47. // 是否固定
  48. isFixed: {
  49. type: Boolean,
  50. default: false
  51. },
  52. // px
  53. top: {
  54. type: Number, // #ifndef H5
  55. default: 0, // #endif
  56. // #ifdef H5
  57. default: 0
  58. // #endif
  59. },
  60. // 是否去掉底部线条
  61. unlined: {
  62. type: Boolean,
  63. default: false
  64. },
  65. // 当前选项卡
  66. currentTab: {
  67. type: Number,
  68. default: 0
  69. },
  70. // 滑块宽度
  71. sliderWidth: {
  72. type: Number,
  73. default: 68
  74. },
  75. // 滑块高度
  76. sliderHeight: {
  77. type: Number,
  78. default: 6
  79. },
  80. sliderRadius: {
  81. type: String,
  82. default: '50upx'
  83. },
  84. // 滑块bottom
  85. bottom: {
  86. type: String,
  87. default: '0'
  88. },
  89. // 标签页宽度
  90. itemWidth: {
  91. type: String,
  92. default: '25%'
  93. },
  94. // 字体颜色
  95. color: {
  96. type: String,
  97. default: '#999'
  98. },
  99. // 字体大小
  100. size: {
  101. type: Number,
  102. default: 28
  103. },
  104. // 选中后 是否加粗 ,未选中则无效
  105. bold: {
  106. type: Boolean,
  107. default: false
  108. },
  109. // 是否显示borer-right
  110. borderLeft: {
  111. type: Boolean,
  112. default: false
  113. },
  114. // 是否有新增按钮
  115. isAdd: {
  116. type: Boolean,
  117. default: false
  118. },
  119. // 新增按钮的icon
  120. addIcon: {
  121. type: String,
  122. default: 'icontianjiakehu'
  123. },
  124. addText: {
  125. type: String,
  126. default: '添加'
  127. },
  128. // 是否显示box-shadow
  129. isBoxShadow: {
  130. type: Boolean,
  131. default: true
  132. }
  133. },
  134. watch: {
  135. currentTab() {
  136. this.checkCor()
  137. }
  138. },
  139. created() {
  140. setTimeout(() => {
  141. // 高度自适应
  142. uni.getSystemInfo({
  143. success: res => {
  144. this.winWidth = res.windowWidth
  145. this.checkCor()
  146. }
  147. })
  148. }, 50)
  149. },
  150. data() {
  151. return {
  152. winWidth: 0,
  153. scrollLeft: 0,
  154. addTabWidth: 130
  155. }
  156. },
  157. computed: {
  158. // addTabWidth() {
  159. // return uni.upx2px(130)
  160. // }
  161. },
  162. methods: {
  163. checkCor: function() {
  164. let addTabWidth = this.isAdd ? uni.upx2px(this.addTabWidth + 30) : 0
  165. let tabsNum = this.tabs.length
  166. let padding = (this.winWidth / 750) * this.padding
  167. let width = this.winWidth - padding * 2 - addTabWidth
  168. let left = (width / tabsNum - (this.winWidth / 750) * this.sliderWidth) / 2 + padding
  169. let scrollLeft = left
  170. if (this.currentTab > 0) {
  171. scrollLeft = scrollLeft + (width / tabsNum) * this.currentTab
  172. }
  173. this.scrollLeft = scrollLeft
  174. },
  175. // 点击标题切换当前页时改变样式
  176. swichTabs: function(index) {
  177. let item = this.tabs[index]
  178. if (item && item.disabled) return
  179. if (this.currentTab == index) {
  180. return false
  181. } else {
  182. this.$emit('change', {
  183. index: Number(index)
  184. })
  185. }
  186. },
  187. // 新增
  188. add() {
  189. console.log('dfa')
  190. this.$emit('add')
  191. }
  192. }
  193. }
  194. </script>
  195. <style lang="scss" scoped>
  196. .tabs-add {
  197. @include disFlex(center, center);
  198. height: 60upx;
  199. border-left: 1upx solid $borderColor;
  200. padding-left: 30upx;
  201. color: $fontColor3;
  202. .iconfont {
  203. margin-right: 10upx;
  204. }
  205. }
  206. .tui-tabs-view {
  207. width: 100%;
  208. box-sizing: border-box;
  209. display: flex;
  210. align-items: center;
  211. justify-content: space-between;
  212. z-index: 99;
  213. .tui-tabs-item {
  214. &.border-left {
  215. border-left: 2upx solid #ddd;
  216. }
  217. }
  218. .tui-tabs-item:first-child {
  219. &.border-left {
  220. border-left: none;
  221. }
  222. }
  223. }
  224. .tui-tabs-view-shadow {
  225. box-shadow: 4upx 4upx 10upx #eee;
  226. }
  227. .tui-tabs-relative {
  228. position: relative;
  229. }
  230. .tui-tabs-fixed {
  231. position: fixed;
  232. left: 0;
  233. }
  234. .tui-tabs-fixed::before,
  235. .tui-tabs-relative::before {
  236. content: '';
  237. position: absolute;
  238. border-bottom: 1upx solid #eaeef1;
  239. -webkit-transform: scaleY(0.5);
  240. transform: scaleY(0.5);
  241. bottom: 0;
  242. right: 0;
  243. left: 0;
  244. }
  245. .tui-unlined::before {
  246. border-bottom: 0 !important;
  247. }
  248. .item-wrap {
  249. width: 100%;
  250. display: flex;
  251. align-items: center;
  252. justify-content: center;
  253. color: $fontColor3;
  254. }
  255. .tui-tabs-item {
  256. display: flex;
  257. align-items: center;
  258. justify-content: center;
  259. }
  260. .tui-tabs-disabled {
  261. opacity: 0.6;
  262. }
  263. .tui-tabs-title {
  264. // display: flex;
  265. // align-items: center;
  266. // justify-content: center;
  267. position: relative;
  268. z-index: 2;
  269. width: 100%;
  270. }
  271. .tabs-title {
  272. text-align: center;
  273. }
  274. .tabs-value {
  275. // @include disFlex(center, center);
  276. font-size: 24upx;
  277. text-align: center;
  278. margin-top: 6upx;
  279. }
  280. .tui-tabs-active {
  281. transition: all 0.15s ease-in-out;
  282. color: $mainColor;
  283. }
  284. .tui-tabs-slider {
  285. position: absolute;
  286. left: 0;
  287. transition: all 0.15s ease-in-out;
  288. z-index: 0;
  289. transform: translateZ(0);
  290. background: $mainColor;
  291. }
  292. </style>