iphLeftMenu.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <!--
  2. * @Descripttion: 左侧导航菜单
  3. * @version: 1.0.0
  4. * @Author: dream
  5. * @Date: 2021-03-27 14:13:43
  6. * @LastEditors: dream
  7. * @LastEditTime: 2021-03-28 13:42:16
  8. -->
  9. <template>
  10. <scroll-view class="left-menu-main" scroll-y>
  11. <block v-for="(item, index) in list" :key="index">
  12. <view
  13. :class="['menu-item', item.value === current ? 'active' : '']"
  14. :id="`menu-item-${item.value}`"
  15. @click="changeMenu(item.value)"
  16. >{{item.label}}</view>
  17. </block>
  18. <view
  19. class="menu-bar"
  20. :style="{
  21. height: `${bar.height}rpx`,
  22. top: `${bar.top}rpx`
  23. }"
  24. ></view>
  25. <view
  26. class="menu-content-bar"
  27. :style="{
  28. height: `${contentBar.height}rpx`,
  29. top: `${contentBar.top}rpx`
  30. }"
  31. ></view>
  32. </scroll-view>
  33. </template>
  34. <script>
  35. export default {
  36. name: 'iphLeftMenu',
  37. props: {
  38. value: {
  39. type: Number || String,
  40. default: 1
  41. },
  42. list: {
  43. type: Array,
  44. default: () => []
  45. }
  46. },
  47. data () {
  48. return {
  49. bar: {
  50. top: 32,
  51. height: 28
  52. },
  53. contentBar: {
  54. top: 0,
  55. height: 92
  56. }
  57. }
  58. },
  59. mounted () {
  60. this.changeMenu(this.value)
  61. },
  62. methods: {
  63. changeMenu (val) {
  64. this.$emit('input', val)
  65. const warp = uni.createSelectorQuery().in(this).select('.left-menu-main')
  66. const view = uni.createSelectorQuery().in(this).select(`#menu-item-${val}`)
  67. view.boundingClientRect(data => {
  68. warp.fields({
  69. rect: true,
  70. scrollOffset: true
  71. }, res => {
  72. if (data) {
  73. this.bar.top = (data.top - res.top + res.scrollTop + 16) * 2
  74. this.bar.height = (data.height - 32) * 2
  75. this.contentBar.top = (data.top - res.top + res.scrollTop) * 2
  76. this.contentBar.height = data.height * 2
  77. } else {
  78. this.bar.top = 32
  79. this.bar.height = 28
  80. this.contentBar.top = 0
  81. this.contentBar.height = 92
  82. }
  83. }).exec()
  84. }).exec()
  85. }
  86. }
  87. }
  88. </script>
  89. <style lang="scss" scoped>
  90. .left-menu-main {
  91. position: relative;
  92. width: 160px;
  93. height: 100%;
  94. overflow-y: auto;
  95. .menu-item {
  96. padding: 28px;
  97. font-weight: 500;
  98. text-align: center;
  99. color: $iph-tip-text;
  100. }
  101. .active {
  102. color: $u-type-primary;
  103. }
  104. .menu-bar {
  105. z-index: -1;
  106. position: absolute;
  107. left: 0;
  108. width: 6px;
  109. background: $u-type-primary;
  110. border-radius: 4px;
  111. transition: all .3s ease;
  112. }
  113. .menu-content-bar {
  114. z-index: -2;
  115. position: absolute;
  116. left: 0;
  117. width: 100%;
  118. background-color: $iph-standby-bg;
  119. transition: all .3s ease;
  120. }
  121. }
  122. </style>