index.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import { throttle } from 'lodash'
  2. import { mapState } from 'vuex'
  3. import menuMixin from '../mixin/menu'
  4. import { createMenu } from '../libs/util.menu'
  5. export default {
  6. name: 'ibps-layout-header-aside-menu-header',
  7. mixins: [
  8. menuMixin
  9. ],
  10. data () {
  11. return {
  12. active: this.activeHeader,
  13. isScroll: false,
  14. scrollWidth: 0,
  15. contentWidth: 0,
  16. currentTranslateX: 0,
  17. throttledCheckScroll: null
  18. }
  19. },
  20. computed: {
  21. ...mapState('ibps/menu', [
  22. 'activeHeader',
  23. 'header'
  24. ])
  25. },
  26. watch: {
  27. // $route (to, from) {
  28. // if (to.name === 'dashboard') {
  29. // this.active = ''
  30. // } else {
  31. // this.active = this.activeHeader
  32. // }
  33. // }
  34. 'activeHeader': {
  35. handler (val) {
  36. if (this.$route.name !== 'dashboard') {
  37. this.active = this.activeHeader
  38. }
  39. },
  40. immediate: true
  41. }
  42. // '$route.matched': {
  43. // handler(val) {
  44. // this.active = val[val.length - 1].path
  45. // },
  46. // immediate: true
  47. // }
  48. },
  49. mounted () {
  50. // 初始化判断
  51. // 默认判断父元素和子元素的大小,以确定初始情况是否显示滚动
  52. window.addEventListener('load', this.checkScroll)
  53. // 全局窗口变化监听,判断父元素和子元素的大小,从而控制isScroll的开关
  54. this.throttledCheckScroll = throttle(this.checkScroll, 300)
  55. window.addEventListener('resize', this.throttledCheckScroll)
  56. // zxh 初始化延迟以确定初始情况是否显示滚动
  57. setTimeout(() => {
  58. this.checkScroll()
  59. }, 500)
  60. },
  61. beforeDestroy () {
  62. // 取消监听
  63. window.removeEventListener('resize', this.throttledCheckScroll)
  64. window.removeEventListener('load', this.checkScroll)
  65. },
  66. methods: {
  67. scroll (direction) {
  68. if (direction === 'left') {
  69. // 向右滚动
  70. this.currentTranslateX = 0
  71. } else {
  72. // 向左滚动
  73. if (this.contentWidth * 2 - this.currentTranslateX <= this.scrollWidth) {
  74. this.currentTranslateX -= this.contentWidth
  75. } else {
  76. this.currentTranslateX = this.contentWidth - this.scrollWidth
  77. }
  78. }
  79. },
  80. checkScroll () {
  81. let contentWidth = this.$refs.content.clientWidth
  82. let scrollWidth = this.$refs.scroll.clientWidth
  83. if (this.isScroll) {
  84. // 页面依旧允许滚动的情况,需要更新width
  85. if (this.contentWidth - this.scrollWidth === this.currentTranslateX) {
  86. // currentTranslateX 也需要相应变化【在右端到头的情况时】
  87. this.currentTranslateX = contentWidth - scrollWidth
  88. // 快速的滑动依旧存在判断和计算时对应的contentWidth变成正数,所以需要限制一下
  89. if (this.currentTranslateX > 0) {
  90. this.currentTranslateX = 0
  91. }
  92. }
  93. // 更新元素数据
  94. this.contentWidth = contentWidth
  95. this.scrollWidth = scrollWidth
  96. // 判断何时滚动消失: 当scroll > content
  97. if (contentWidth > scrollWidth) {
  98. this.isScroll = false
  99. }
  100. }
  101. // 判断何时滚动出现: 当scroll < content
  102. if (!this.isScroll && contentWidth < scrollWidth) {
  103. this.isScroll = true
  104. // 注意,当isScroll变为true,对应的元素盒子大小会发生变化
  105. this.$nextTick(() => {
  106. contentWidth = this.$refs.content.clientWidth
  107. scrollWidth = this.$refs.scroll.clientWidth
  108. this.contentWidth = contentWidth
  109. this.scrollWidth = scrollWidth
  110. this.currentTranslateX = 0
  111. })
  112. }
  113. }
  114. },
  115. render (h) {
  116. return <div
  117. flex='cross:center'
  118. class={{ 'ibps-theme-header-menu': true, 'is-scrollable': this.isScroll }}
  119. ref='page'>
  120. <div
  121. ref='content'
  122. class='ibps-theme-header-menu__content'
  123. flex-box='1'
  124. flex>
  125. <div
  126. class='ibps-theme-header-menu__scroll'
  127. flex-box='0'
  128. style={{ transform: `translateX(${this.currentTranslateX}px)` }}
  129. ref='scroll'>
  130. <el-menu
  131. mode='horizontal'
  132. defaultActive={this.active}
  133. onSelect={this.handleHeaderMenuSelect}>
  134. {this.header.map(menu => createMenu.call(this, h, menu, 'id'))}
  135. </el-menu>
  136. </div>
  137. </div>
  138. {
  139. this.isScroll
  140. ? [
  141. <div
  142. class='ibps-theme-header-menu__prev'
  143. flex='main:center cross:center'
  144. flex-box='0'
  145. onClick={() => this.scroll('left')}>
  146. <i class='el-icon-arrow-left'></i>
  147. </div>,
  148. <div
  149. class='ibps-theme-header-menu__next'
  150. flex='main:center cross:center'
  151. flex-box='0'
  152. onClick={() => this.scroll('right')}>
  153. <i class='el-icon-arrow-right'></i>
  154. </div>
  155. ]
  156. : []
  157. }
  158. </div>
  159. }
  160. }