置顶 Vue路由开启keep-alive时的注意点

解决方案 前端 随笔

Vue

2020-07-03 15:52:32

550

作者:黑夜男神

是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM 有时候我们为了提升页面性能的时候会使用该组件。虽然提升了页面性能 但是仍需要注意几个地方

需求场景:

当我们想在vue页面想做向下加载数据的时候这个时候我们会用到监听绑定浏览器的滚动条事件,如果我们在当前路由下包裹了keep-alive 组件的当我们在A页面加载完数据的话 想切换到B页面的时候, 会发现A页面之前绑定的下来加载的数据还是会触发,因为 keep-alive的时候会一直保持监听document的监听事件确切来说是独立于vue项目之外的,如果你不销毁会一直存在。所有当我们在切换路由的时候 需要将之前绑定的滚动条事件进行移除。这个时候我们我们还可以在 vue 生命周期钩子函数去销毁刚才所绑定的事件 。

销毁绑定事件

 // 卸载绑定事件防止切换路由再次触发
  deactivated() {
    window.removeEventListener('scroll', this.isWindowBottom)
  },

这样我们在切换到B页面的时候 这样就不会再次调用到A页面的的加载方法了。

激活事件

但是任然存在一个问题,虽然我们在切换到B页面的时候销毁了A页面的绑定滚动条数据 此时我们再回到A页面发现滚动事件失效了, 这个时候我们需要重新激活绑定滚动条事件 因为再keep-alive 这个组件当再次加重A页面的时候不会再次出发create 函数了 ,页面第一次进入,钩子的触发顺序created-> mounted-> activated, 当再次进入(前进或者后退)时,只触发activated。 所以我们需要在deactivated 这个函数再次去绑定激活滚动条事件

// 再次激活
  activated() {
    window.addEventListener('scroll', this.isWindowBottom)
  },

下拉滑动加载数据封装

<template>
  <div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  props: {
    // 下拉加载方法
    infiniteScroll: {
      type: Function,
      required: true
    },
    // 是否加载完毕
    isLoading: {
      type: Boolean,
      required: true
    },
    // 距离底部的位置
    distance: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      isload: false
    }
  },
  created() {
    // 初始化加载
    this.infiniteScroll()
  },
  // 再次激活
  activated() {
    window.addEventListener('scroll', this.isWindowBottom)
  },
  // 卸载绑定事件防止切换路由再次触发
  deactivated() {
    window.removeEventListener('scroll', this.isWindowBottom)
  },
  methods: {
    isWindowBottom() {
      // 页面滚动距离
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop
      // 可视区域高度
      const windowHeight =
        document.documentElement.clientHeight || document.body.clientHeight
      // 总高度
      const scrollHeight =
        document.documentElement.scrollHeight || document.body.scrollHeight
      // 滚动条到底部
      if (scrollTop + windowHeight > scrollHeight - this.distance) {
        if (!this.isload) {
          this.infiniteScroll()
        }
      }
    }
  },
  watch: {
    // 监听是否数据加载完毕
    isLoading(val) {
      this.isload = val
    }
  }
}
</script>

<style></style>

评论 (0)

用户名
邮箱
评论

    Copyright © 2020 darkNightMan All Rights Reserved Pro 黔ICP备20005477号