index.vue 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <template>
  2. <div :style="{height:height+'px',zIndex:zIndex}">
  3. <div
  4. :class="className"
  5. :style="{top:(isSticky ? stickyTop +'px' : ''),zIndex:zIndex,position:position,width:width,height:height+'px'}"
  6. >
  7. <slot>
  8. <div>sticky</div>
  9. </slot>
  10. </div>
  11. </div>
  12. </template>
  13. <script>
  14. export default {
  15. name: 'Sticky',
  16. props: {
  17. stickyTop: {
  18. type: Number,
  19. default: 0
  20. },
  21. zIndex: {
  22. type: Number,
  23. default: 1
  24. },
  25. className: {
  26. type: String,
  27. default: ''
  28. }
  29. },
  30. data() {
  31. return {
  32. active: false,
  33. position: '',
  34. width: undefined,
  35. height: undefined,
  36. isSticky: false
  37. }
  38. },
  39. mounted() {
  40. this.height = this.$el.getBoundingClientRect().height
  41. window.addEventListener('scroll', this.handleScroll)
  42. window.addEventListener('resize', this.handleResize)
  43. },
  44. activated() {
  45. this.handleScroll()
  46. },
  47. destroyed() {
  48. window.removeEventListener('scroll', this.handleScroll)
  49. window.removeEventListener('resize', this.handleResize)
  50. },
  51. methods: {
  52. sticky() {
  53. if (this.active) {
  54. return
  55. }
  56. this.position = 'fixed'
  57. this.active = true
  58. this.width = this.width + 'px'
  59. this.isSticky = true
  60. },
  61. handleReset() {
  62. if (!this.active) {
  63. return
  64. }
  65. this.reset()
  66. },
  67. reset() {
  68. this.position = ''
  69. this.width = 'auto'
  70. this.active = false
  71. this.isSticky = false
  72. },
  73. handleScroll() {
  74. const width = this.$el.getBoundingClientRect().width
  75. this.width = width || 'auto'
  76. const offsetTop = this.$el.getBoundingClientRect().top
  77. if (offsetTop < this.stickyTop) {
  78. this.sticky()
  79. return
  80. }
  81. this.handleReset()
  82. },
  83. handleResize() {
  84. if (this.isSticky) {
  85. this.width = this.$el.getBoundingClientRect().width + 'px'
  86. }
  87. }
  88. }
  89. }
  90. </script>