gui-switch-navigation.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <scroll-view :scroll-with-animation="scorllAnimation"
  3. :scroll-x="true" :show-scrollbar="false"
  4. :class="['gui-scroll-x', isCenter ? 'gui-nav-center' : '']"
  5. :style="{width:width+'rpx'}"
  6. :scroll-left="scrollLeft">
  7. <view class="gui-scroll-x-items gui-columns"
  8. :id="'tab-'+index+(random+'')"
  9. :style="{
  10. width:size == 0 ? 'auto' : size+'rpx',
  11. marginRight:margin+'rpx', paddingLeft:padding, paddingRight:padding
  12. }"
  13. v-for="(item, index) in itemsIn" :key="index" @tap="change" :data-index="index">
  14. <text :class="['gui-block-text', 'gui-border-box', currentIndexIn == index ? 'nav-active' : '']"
  15. :style="{
  16. color:currentIndexIn == index ? activeColor : color,
  17. textAlign : textAlign, lineHeight:lineHeight,
  18. fontSize:currentIndexIn == index ? activeFontSize : fontSize,
  19. fontWeight:currentIndexIn == index ? activeFontWeight : ''}">{{item.name}}</text>
  20. <view class="gui-flex gui-rows" :style="{justifyContent:activeDirection}">
  21. <view class="nav-active-line"
  22. :class="[currentIndexIn == index && animatie ?'gui-nav-scale':'']"
  23. :style="{
  24. backgroundImage:activeLineBg, width:activeLineWidth,
  25. height:activeLineHeight, borderRadius:activeLineRadius
  26. }"
  27. v-if="currentIndexIn == index"></view>
  28. </view>
  29. </view>
  30. </scroll-view>
  31. </template>
  32. <script>
  33. export default {
  34. name : "gui-switch-navigation",
  35. props : {
  36. width : {type : Number, default : 690},
  37. isCenter : {type : Boolean, default : false},
  38. currentIndex : {type : Number, default : 0},
  39. size : {type : Number, default : 120},
  40. fontSize : {type : String, default : '28rpx'},
  41. activeFontSize : {type : String, default : '28rpx'},
  42. items : {type : Array, default : function () {return []}},
  43. activeLineBg : {type : String, default : "linear-gradient(to right, #66BFFF,#3388FF)"},
  44. color : {type : String, default : "#333333"},
  45. activeColor : {type : String, default : "#333333"},
  46. activeLineHeight : {type : String, default : '6rpx'},
  47. activeLineWidth : {type : String, default : "36rpx"},
  48. activeLineRadius : {type : String, default : "0rpx"},
  49. activeDirection : {type : String, default : ""},
  50. activeFontWeight : {type : Number, default : 700},
  51. margin : {type : Number, default : 0},
  52. textAlign : {type : String, default : ''},
  53. lineHeight : {type : String, default : '50rpx'},
  54. padding : {type : String, default : '0rpx'},
  55. animatie : {type : Boolean, default : true},
  56. autoLeft : {type : String, default : ''},
  57. scorllAnimation : {type : Boolean, default : true}
  58. },
  59. data(){
  60. return {
  61. currentIndexIn : 0,
  62. itemsIn : [],
  63. random : 1,
  64. scrollLeft : 0,
  65. scrllTimer : null
  66. }
  67. },
  68. created:function(){
  69. this.currentIndexIn = this.currentIndex;
  70. this.itemsIn = this.items;
  71. this.random = this.randomNum();
  72. },
  73. watch:{
  74. currentIndex : function(value){
  75. this.currentIndexIn = value;
  76. },
  77. currentIndexIn : function(val){
  78. if(this.isCenter){return ;}
  79. if(this.scrllTimer != null){clearTimeout(this.scrllTimer);}
  80. this.scrllTimer = setTimeout(()=>{this.setLeft();}, 200);
  81. },
  82. items : function(value){ this.itemsIn = value; }
  83. },
  84. methods:{
  85. change : function (e){
  86. this.currentIndexIn = e.currentTarget.dataset.index;
  87. this.$emit('change', Number(e.currentTarget.dataset.index))
  88. },
  89. randomNum : function () {
  90. return parseInt(Math.random() * 1000);
  91. },
  92. setLeft : function () {
  93. if(this.isCenter){return ;}
  94. var itemWidth = Number(this.margin) + Number(this.size);
  95. var left = (Number(this.currentIndexIn) + 1) * itemWidth - Number(this.width) / 2 - itemWidth / 2;
  96. var maxLeft = Number(this.itemsIn.length) * itemWidth - this.width;
  97. maxLeft = uni.upx2px(maxLeft - 30);
  98. left = uni.upx2px(left);
  99. if(left > maxLeft){left = maxLeft;}
  100. if(left < 0){left = 0;}
  101. this.scrollLeft = left;
  102. }
  103. }
  104. }
  105. </script>
  106. <style scoped>
  107. .nav-active-line{margin-top:6rpx;}
  108. .gui-nav-center{justify-content:center; text-align:center;}
  109. /* #ifndef APP-NVUE */
  110. @keyframes gui-nav-scale{0%{transform: scale(0.1);} 100%{transform: scale(1);}}
  111. .gui-nav-scale{animation:gui-nav-scale 350ms forwards;}
  112. /* #endif */
  113. </style>