强制 Vue 组件重新渲染的方法(一)

1,768 阅读2分钟

前言

在本文中,我们将回顾一些能够重新渲染 Vue 组件的方法,这样我们就可以避免重新加载整个页面。以下四种基本实践适用于 Vue 2 和 Vue 3。让我们开始吧!

  • 热重载
  • v-if 指令
  • Vue 内置的 forceUpdate 方法
  • Key 更改

热重载

热重载,当我们在启用热重载的情况下修改 *.vue 文件中的组件时,Vue 将交换该组件的所有实例而不刷新页面

因此,它会保留我们当前状态,体验非常好。

使用热重载

使用 Vue CLI 构建项目时,热重载将开箱即用。此外,当您手动设置新项目时,使用 webpack-dev-server --hot 热重载会自动启用。

想知道更多配置,我建议查看  vue-hot-reload-api 内部使用的 vue-hot-reload-api 。

禁用热重载

以下情况热重载不启用:

  • webpack target 为 node (SSR)
  • webpack 压缩代码
  • process.env.NODE_ENV === 'production'

禁用热重载,使用 hotReload: false 选项:

module: {
  rules: [
    {
      test: /.vue$/,
      loader: 'vue-loader',
      options: {
        hotReload: false 
      }
    }
  ]
}

State 保存规则

重新渲染组件时,热重载过程遵循state保存规则

编辑组件的 <template> 时,被编辑组件的实例将在本地重新渲染,保持所有现有的私有状态。这可以通过组合模板创建新渲染函数来实现。

当组件的 <script> 部分发生更改时,修改后的组件的实例将被销毁并在本地重新创建。这是由于 <script> 中的生命周期钩子可能产生副作用,需要重新加载。

因此,在组件生命周期中使用计时器或其他全局副作用时应注意。有时,如果一个组件有全局副作用,就重新加载了整个页面。

请记住,state 不受 <style> 热重载的影响,因为它通过 vue-style-loader 独立运行。

v-if 指令

v-if 等于 true 时呈现组件。如果是 false ,组件将不会出现在 DOM 中。因此,使用 v-if 指令是好的解决方案。

在这个模板中,让我们设置一个 v-if 指令:

<template>
  <MyComponent v-if="renderComponent" />
</template>

在 script 部分,我们将添加一个名为 forceRender 的方法,它使用 script ,一个用于等待下一次 DOM 更新刷新的实用程序:

import { nextTick, ref } from 'vue';
const renderComponent = ref(true);

const forceRender = async () => {
  // 这里移除组件 MyComponent
  renderComponent.value = false;

   // 等待下一次 DOM 更新
  await nextTick();

  // 添加组件
  renderComponent.value = true;
};

Vue2 中的 script 代码:

export default {
  data() {
    return {
      renderComponent: true,
    };
  },
  methods: {
    async forceRender() {
   // 这里移除组件 MyComponent
   this.renderComponent = false;

   // 等待下一次 DOM 更新
      await this.$nextTick();

      // 添加组件
      this.renderComponent = true;
    }
  }
};

在上面的代码片段中, renderComponent 最初设置为 true ,呈现 MyComponent 。每当我们调用 forceRender 时, renderComponent 都会被设置为 false 。这样做会停止渲染 MyComponent ,因为 v-if 指令现在为 false 。

在 MyComponent 停止渲染后,我们立即等待 nextTick,然后将 renderComponent 设置回 true 。这还将 v-if 指令设置为 true ,它呈现 MyComponent 

nextTick() 运作方式至关重要。首先,我们必须等到下一个 nextTick(),除非我们自行取消 renderComponent 的更新,并且我们不会注意到任何变化。

在 Vue 中,您可以在状态更改后立即使用 nextTick() 来等待 DOM 更新完成。我们可以将回调作为参数传递,也可以等待返回的 promise

Vue 会销毁之前的组件,因为它会在我们第二次渲染它时创建一个全新的组件。因此,我们的新 MyComponent 将经历其所有生命周期, created 、 mounted 等等。

另外两种方法放到下一篇文章讲

  • Vue 内置的 forceUpdate 方法
  • Key 更改