Skip to content

VUE 框架

专题版块详见 VUE 专题

1. 事件总线

1. 事件总线

事件总线:通过创建一个全局事件管理器,允许跨组件通信。

事件总线适用于小型或中型项目,用于快速的跨组件通信,但在大型应用中,使用 Vuex 或其他状态管理工具会更加规范和高效。事件总线没有集中管理状态的能力,容易导致代码的难以维护。

js
const EventBus = new Vue();

// 在一个组件中
EventBus.$emit("someEvent", data);

// 在另一个组件中
EventBus.$on("someEvent", (data) => {
  console.log(data);
});

一般是单独放在一个文件中,如 eventBus.js,然后在需要的地方引入。

js
// src/event-bus.js
import Vue from "vue";
export const EventBus = new Vue();
vue
<!-- 发送事件(触发事件) -->
<template>
  <button @click="sendEvent">发送事件</button>
</template>

<script>
import { EventBus } from "@/event-bus";

export default {
  methods: {
    sendEvent() {
      // 触发事件
      EventBus.$emit("myEvent", "Hello from Component A!");
    },
  },
};
</script>
vue
<!-- 监听事件(接收事件) -->
<template>
  <div>{{ message }}</div>
</template>

<script>
import { EventBus } from "@/event-bus";

export default {
  data() {
    return {
      message: "",
    };
  },
  created() {
    // 监听事件
    EventBus.$on("myEvent", (data) => {
      this.message = data;
    });
  },
  beforeDestroy() {
    // 记得在组件销毁前取消监听
    EventBus.$off("myEvent");
  },
};
</script>

2. 虚拟滚动

2.1 原理以及步骤

虚拟滚动的原理: 当用户滚动列表时,只渲染当前视口内的元素,而不是渲染整个数据列表。随着滚动的进行,不断更新显示在视口内的内容,并销毁那些不再可见的元素。

虚拟滚动通常包括以下步骤:

  • 计算可视区域:首先,需要计算出容器的高度、每个元素的高度(或宽度)(如果每一个元素的高度不一致?),以及当前可视区域的滚动位置。
    • 元素高度不一致时:
      • heightCache:为每个元素存储了其高度,并在 calculateTotalHeight() 方法中进行缓存。这样在每次更新时,只需要使用缓存的高度进行计算,避免重复的高度计算。
      • updateVisibleItems():在滚动时直接使用缓存的高度数据来计算可视区域,避免了每次都要重新计算 DOM 的高度。
  • 按需渲染:只渲染可视区域内的元素。通过计算,确定哪些元素在视口范围内,将这些元素渲染出来。
  • 元素复用与销毁:当用户滚动时,新的元素会被加载进视口,超出视口的元素会被销毁或隐藏,避免不必要的渲染。

2. 虚拟滚动

虚拟滚动:一些 UI 组件库(如 Vuetify 和 Ant Design Vue)提供虚拟滚动组件,通过按需渲染可见部分的元素来提高性能。

vue
<!-- 以下是一个简单的虚拟滚动实现的伪代码示例: -->
<!-- 
核心逻辑:
    1) 计算开始和结束的索引:根据滚动的偏移量 (scrollTop),计算当前视口内需要显示的元素的索引范围。
    2) 更新可见元素:通过 slice() 方法从数据源中取出可见部分的数据,并渲染出来。
    3) 动态调整渲染范围:根据滚动事件 (onScroll) 不断更新可见元素列表,实现滚动时元素的动态更新。

关键参数:
    1) itemHeight:每个列表项的高度(可以是固定值,也可以动态计算)。
    2) scrollTop:当前容器的滚动位置,用于计算当前可视区域。
    3) buffer:设置缓存区,表示在视口外但靠近视口的元素也会被提前渲染,避免用户快速滚动时出现空白。
 -->
<template>
  <div class="scroll-container" @scroll="onScroll">
    <div class="virtual-list" :style="{ height: totalHeight + 'px' }">
      <!-- 动态生成可见的虚拟元素 -->
      <div v-for="item in visibleItems" :key="item.id" class="list-item">
        {{ item.content }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: Array.from({ length: 10000 }, (_, index) => ({
        id: index,
        content: `Item ${index + 1}`,
      })), // 模拟数据源
      visibleItems: [],
      itemHeight: 30, // 假设每个项的高度为 30px
      containerHeight: 0,
      scrollTop: 0,
      buffer: 10, // 缓冲区,即在视口外渲染一些元素
    };
  },
  mounted() {
    this.containerHeight = this.$el.clientHeight;
    this.updateVisibleItems();
  },
  methods: {
    onScroll() {
      this.scrollTop = this.$el.scrollTop;
      this.updateVisibleItems();
    },
    updateVisibleItems() {
      const startIndex = Math.max(
        0,
        Math.floor(this.scrollTop / this.itemHeight) - this.buffer
      );
      const endIndex = Math.min(
        this.items.length - 1,
        Math.floor((this.scrollTop + this.containerHeight) / this.itemHeight) +
          this.buffer
      );
      this.visibleItems = this.items.slice(startIndex, endIndex);
    },
  },
};
</script>

<style scoped>
.scroll-container {
  overflow-y: auto;
  height: 400px; /* 设置容器的高度 */
}
.virtual-list {
  position: relative;
}
.list-item {
  height: 30px; /* 假设每个列表项的高度 */
  line-height: 30px;
  border-bottom: 1px solid #ddd;
}
</style>

2.2 应用场景

虚拟滚动通常用于以下几种场景:

  • 长列表或大量数据渲染:例如数据表格、商品列表、聊天记录等,列表中包含大量数据时,使用虚拟滚动可以有效提高渲染性能,避免浏览器卡顿。
  • 无限滚动:当数据需要从服务器端分页加载时,虚拟滚动非常适合与“懒加载”结合使用,随着滚动的进行,动态加载更多数据并呈现给用户。
  • 大数据展示:当页面上需要显示的数据量很大,例如大规模的图表、图像、文件列表等,虚拟滚动能够提供良好的用户体验。
  • 性能优化:虚拟滚动是提高长列表性能的标准技术之一,尤其在移动端设备上,由于硬件性能的限制,虚拟滚动尤为重要。

2.3 适用的组件库

许多 UI 组件库和框架都支持虚拟滚动组件。例如:

  • Vuetify:通过 v-virtual-scroll 实现虚拟滚动。
  • Ant Design Vue:通过 VirtualList 组件实现虚拟滚动。
  • React Virtualized:一个常用于 React 应用的虚拟滚动库,适合处理大型数据集。
  • Vue Virtual Scroller:一个轻量级的 Vue 组件库,用于虚拟滚动。

3. 懒加载

专题版块详见 图片优化

3.1 原理

懒加载(Lazy Loading) 是一种延迟加载资源的技术,指的是只在需要时才加载资源,从而提高页面加载速度,节省带宽,改善用户体验。在 UI 开发中,懒加载通常用于图片、视频等资源的加载,或者在滚动到可视区域时才加载某些内容。

3.2 实现方式

  • IntersectionObserver:一种浏览器原生 API,提供了一种方法来检测元素与视口的交叉情况,适合用于懒加载的实现。
  • 滚动监听:通过监听滚动事件,判断元素是否进入视口范围,从而触发加载。

3. 懒加载

懒加载:对于需要大量图片或资源的组件,可以使用懒加载技术(如 IntersectionObserver)仅加载用户当前视图中的元素。

4. 自定义指令和插件扩展

4. 自定义指令和插件扩展

自定义指令和插件扩展:对于需要大量图片或资源的组件,可以使用懒加载技术(如 IntersectionObserver)仅加载用户当前视图中的元素。

js
Vue.directive("focus", {
  // 当绑定元素插入到 DOM 中时
  inserted: function (el) {
    el.focus();
  },
});

// 使用:<input v-focus>

自定义指令的生命周期钩子

  • bind:指令与元素绑定时调用。
  • inserted:元素插入父节点时调用。
  • update:组件更新时调用。
  • componentUpdated:组件更新完成后调用。
  • unbind:指令与元素解绑时调用。