detail-page-header.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <template>
  2. <view
  3. class="ylx-page-header row"
  4. :style="{
  5. height: navigationBarHeight+statusBarHeight+'px',
  6. paddingTop: statusBarHeight+'px',
  7. backgroundColor: 'rgba(255,255,255, '+headerOpacity+')'
  8. }"
  9. >
  10. <view class="btn center" @click="navBack">
  11. <text class="yticon icon-xiangzuo" :class="{dark: headerOpacity < 0.5}"></text>
  12. </view>
  13. <view class="cen center">
  14. <view
  15. class="cen-item"
  16. :class="{active: index === currentAnchor}"
  17. :style="{opacity: headerOpacity}"
  18. v-for="(item, index) in anchorList"
  19. :key="index"
  20. @click="navToAnchor(index)"
  21. >
  22. <text>{{ item.name }}</text>
  23. </view>
  24. </view>
  25. <view class="btn"></view>
  26. </view>
  27. </template>
  28. <script>
  29. let _disableScroll = false;
  30. export default {
  31. name: 'ProductPageHeader',
  32. data() {
  33. return {
  34. headerOpacity: 0,
  35. currentAnchor: 0,
  36. anchorList: [
  37. {id: 1, name: '视频讲解', top: 0},
  38. {id: 2, name: '解析文档', top: 0},
  39. {id: 3, name: '文档下载', top: 0},
  40. ]
  41. };
  42. },
  43. props: {
  44. },
  45. computed: {
  46. statusBarHeight(){
  47. return this.systemInfo.statusBarHeight;
  48. },
  49. navigationBarHeight(){
  50. return this.systemInfo.navigationBarHeight;
  51. }
  52. },
  53. methods: {
  54. //转到锚点
  55. navToAnchor(index){
  56. const {headerOpacity, anchorList, statusBarHeight, navigationBarHeight} = this;
  57. if(this.headerOpacity == 0){
  58. return;
  59. }
  60. _disableScroll = true;
  61. uni.pageScrollTo({
  62. scrollTop: anchorList[index].top - 1,
  63. duration: 200
  64. })
  65. this.currentAnchor = index;
  66. setTimeout(()=>{
  67. _disableScroll = false;
  68. }, 400)
  69. },
  70. pageScroll(e){
  71. //头部渐变
  72. this.headerOpacity = e.scrollTop/150;
  73. //锚点切换
  74. if(_disableScroll){
  75. return;
  76. }
  77. const {currentAnchor, anchorList} = this;
  78. const cur = e.scrollTop >= anchorList[2].top ? 2 : e.scrollTop >= anchorList[1].top ? 1:0;
  79. if(cur !== currentAnchor){
  80. this.currentAnchor = cur;
  81. }
  82. },
  83. navBack(){
  84. uni.navigateBack();
  85. }
  86. }
  87. }
  88. </script>
  89. <style scoped lang="scss">
  90. .ylx-page-header{
  91. position: fixed;
  92. left: 0;
  93. top: 100rpx;
  94. z-index: 90;
  95. justify-content: space-between;
  96. width: 100%;
  97. }
  98. .btn{
  99. width: 80rpx;
  100. }
  101. .icon-xiangzuo{
  102. width: 52rpx;
  103. height: 52rpx;
  104. border-radius: 100rpx;
  105. font-size: 36rpx;
  106. color: #333;
  107. text-align: center;
  108. line-height: 52rpx;
  109. &.dark{
  110. background-color: rgba(0,0,0,.5);
  111. color: #fff;
  112. }
  113. }
  114. .cen{
  115. flex: 1;
  116. height: 100%;
  117. position: relative;
  118. .cen-item{
  119. width: 50px;
  120. height: 36px;
  121. font-size: 15px;
  122. color: #333;
  123. text-align: center;
  124. line-height: 36px;
  125. position: relative;
  126. }
  127. .active{
  128. font-size: 17px;
  129. font-weight: 700;
  130. &:after{
  131. position: absolute;
  132. left: 50%;
  133. bottom: 0;
  134. transform: translateX(-50%);
  135. content: '';
  136. width: 30px;
  137. height: 2px;
  138. background-color: $base-color;
  139. border-radius: 10rpx;
  140. }
  141. }
  142. }
  143. </style>