gui-switch-navigation.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <template>
  2. <scroll-view
  3. :scroll-with-animation="scorllAnimation"
  4. :scroll-x="true"
  5. :show-scrollbar="false"
  6. :class="['gui-scroll-x', isCenter ? 'gui-nav-center' : '']"
  7. :style="{width:width+'rpx'}"
  8. :scroll-into-view="autoLeft"
  9. :scroll-left="scrollLeft">
  10. <view
  11. class="gui-scroll-x-items gui-columns"
  12. :id="'tab-'+index+(random+'')"
  13. :style="{
  14. width:size == 0 ? 'auto' : size+'rpx',
  15. marginRight:margin+'rpx',
  16. paddingLeft:padding,
  17. paddingRight:padding
  18. }"
  19. v-for="(item, index) in itemsIn"
  20. :key="index"
  21. @tap="change"
  22. :data-index="index">
  23. <view class="gui-flex gui-nowrap gui-align-items-start"
  24. :class="[textAlign == 'center' ? 'gui-justify-content-center' : '']">
  25. <text
  26. class="gui-block gui-border-box"
  27. :class="[titleClass, index == currentIndexIn ? titleActiveClass : []]"
  28. :style="{
  29. textAlign : textAlign,
  30. lineHeight:lineHeight,
  31. fontSize:currentIndexIn == index ? activeFontSize : fontSize,
  32. fontWeight:currentIndexIn == index ? activeFontWeight : ''
  33. }">{{item.name}}</text>
  34. <view v-if="item.tips">
  35. <text
  36. v-if="item.tips != 'point'"
  37. class="gui-nav-tips gui-block"
  38. :style="tipsStyle">{{item.tips}}</text>
  39. <text
  40. v-else
  41. class="gui-nav-tips gui-block"
  42. :style="tipsStyle+'; width:12rpx; height:12rpx; over-flow:hidden; padding:0rpx; margin-top:10rpx;'"></text>
  43. </view>
  44. </view>
  45. <view
  46. class="gui-flex gui-rows"
  47. :style="{justifyContent:activeDirection}">
  48. <view
  49. class="nav-active-line"
  50. :class="currentIndexIn == index ? activeLineClass : []"
  51. :style="{
  52. width:activeLineWidth,
  53. height:activeLineHeight,
  54. borderRadius:activeLineRadius
  55. }"
  56. v-if="currentIndexIn == index"></view>
  57. </view>
  58. </view>
  59. </scroll-view>
  60. </template>
  61. <script>
  62. export default {
  63. name : "gui-switch-navigation",
  64. props : {
  65. width : {type : Number, default : 690},
  66. isCenter : {type : Boolean, default : false},
  67. currentIndex : {type : Number, default : 0},
  68. size : {type : Number, default : 120},
  69. fontSize : {type : String, default : '28rpx'},
  70. activeFontSize : {type : String, default : '28rpx'},
  71. items : {type : Array, default : function () {return []}},
  72. activeLineClass : {type : Array, default : function () {
  73. return ['gui-nav-scale','gui-gtbg-blue', 'gui-gtbg-black'];
  74. }},
  75. titleClass : {type : Array, default : function () {
  76. return ['gui-primary-text'];
  77. }},
  78. titleActiveClass : {type : Array, default : function () {
  79. return ['gui-primary-text'];
  80. }},
  81. activeLineHeight : {type : String, default : '5rpx'},
  82. activeLineWidth : {type : String, default : "36rpx"},
  83. activeLineRadius : {type : String, default : "0rpx"},
  84. activeDirection : {type : String, default : ""},
  85. activeFontWeight : {type : Number, default : 700},
  86. margin : {type : Number, default : 0},
  87. textAlign : {type : String, default : ''},
  88. lineHeight : {type : String, default : '50rpx'},
  89. padding : {type : String, default : '0rpx'},
  90. animatie : {type : Boolean, default : true},
  91. scorllAnimation : {type : Boolean, default : true},
  92. // #ifdef APP-NVUE
  93. tipsStyle : {
  94. type : String,
  95. default : 'background-color:#FF0000; padding-left:10rpx; padding-right:10rpx; color:#FFFFFF; font-size:22rpx',
  96. }
  97. // #endif
  98. // #ifndef APP-NVUE
  99. tipsStyle : {
  100. type : String,
  101. default : 'background-color:#FF0000; padding:0 10rpx; color:#FFFFFF; font-size:22rpx'
  102. }
  103. // #endif
  104. },
  105. data(){
  106. return {
  107. currentIndexIn : 0,
  108. itemsIn : [],
  109. random : 1,
  110. scrollLeft : 0,
  111. scrllTimer : null,
  112. autoLeft : ''
  113. }
  114. },
  115. created:function(){
  116. this.currentIndexIn = this.currentIndex;
  117. this.itemsIn = this.items;
  118. this.random = this.randomNum();
  119. },
  120. watch:{
  121. currentIndex : function(value){
  122. this.currentIndexIn = value;
  123. },
  124. currentIndexIn : function(val){
  125. if(this.scrllTimer != null){clearTimeout(this.scrllTimer);}
  126. this.scrllTimer = setTimeout(()=>{this.setLeft();}, 200);
  127. },
  128. items : function(value){ this.itemsIn = value; }
  129. },
  130. methods:{
  131. change : function (e){
  132. this.currentIndexIn = e.currentTarget.dataset.index;
  133. this.$emit('change', Number(e.currentTarget.dataset.index))
  134. },
  135. randomNum : function () {
  136. return parseInt(Math.random() * 1000);
  137. },
  138. setLeft : function () {
  139. if(this.size < 1){
  140. this.autoLeft = 'tab-'+this.currentIndexIn+''+this.random;
  141. return ;
  142. }
  143. var itemWidth = Number(this.margin) + Number(this.size);
  144. var left = (Number(this.currentIndexIn) + 1) * itemWidth - Number(this.width) / 2 - itemWidth / 2;
  145. var maxLeft = Number(this.itemsIn.length) * itemWidth - this.width;
  146. maxLeft = uni.upx2px(maxLeft - 30);
  147. left = uni.upx2px(left);
  148. if(left > maxLeft){left = maxLeft;}
  149. if(left < 0){left = 0;}
  150. this.scrollLeft = left;
  151. }
  152. },
  153. emits : ['change']
  154. }
  155. </script>
  156. <style scoped>
  157. .nav-active-line{margin-top:6rpx;}
  158. .gui-nav-center{justify-content:center; text-align:center;}
  159. /* #ifndef APP-NVUE */
  160. @keyframes gui-nav-scale{0%{transform: scale(0.1);} 100%{transform: scale(1);}}
  161. .gui-nav-scale{animation:gui-nav-scale 350ms forwards;}
  162. /* #endif */
  163. .gui-nav-tips{text-align:center; line-height:30rpx; height:30rpx; border-radius:50rpx; margin-top:5rpx; margin-left:8rpx;}
  164. </style>