index.vue 2.1 KB

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