useScroll.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. const useScroll = {
  2. data() {
  3. return {
  4. scrollableValue: 20,
  5. scrollableElement: null,
  6. scrollTop: void 0,
  7. __activated__: false,
  8. };
  9. },
  10. activated() {
  11. if (!this.__activated__) this.onActivated();
  12. this.scroll(this.scrollTop, 'instant');
  13. },
  14. deactivated() { this.onDeactivated(); },
  15. beforeRouteLeave(to, from, next) {
  16. this.scrollableElement = this.findScrollableElement();
  17. this.scrollTop = this.scrollableElement ? this.scrollableElement.scrollTop : void 0;
  18. next();
  19. },
  20. methods: {
  21. /* activated 生命周期调用 */
  22. onActivated() { this.__activated__ = true; },
  23. /* deactivated 生命周期调用 */
  24. onDeactivated() { this.__activated__ = false; },
  25. findScrollableElement(el) {
  26. if (this.$refs.scrollableElement) return this.unrefElement();
  27. if (el == null) el = this.$el;
  28. if (el && el.scrollHeight - el.clientHeight > this.scrollableValue) return el;
  29. else if (el) {
  30. for (const child of el.children) {
  31. const scrollable = this.findScrollableElement(child);
  32. if (scrollable) return scrollable;
  33. }
  34. }
  35. return null;
  36. },
  37. unrefElement(element) {
  38. if (!element) element = this.$refs.scrollableElement;
  39. return element && element._isVue ? element.$el : element;
  40. },
  41. /**
  42. * 滚动容器滚动
  43. * @param {number} top
  44. * @param {'instant' | 'smooth'} behavior
  45. */
  46. scroll(top, behavior = 'smooth') {
  47. const element = this.unrefElement() || this.scrollableElement;
  48. if (top == null) top = this.scrollTop;
  49. if (element != null && top != null) element.scrollTo({ top, behavior });
  50. },
  51. },
  52. };
  53. export default useScroll;