Vue 组件生命周期

发布于 2022-08-25 12:34:03 字数 7128 浏览 194 评论 0

Vue 生命周期钩子 让您有机会在 Vue 对您的组件执行特定操作时运行代码。Vue 为每个组件公开的钩子是:

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed

上面的列表是有序的。 所以 Vue 总是调用 beforeCreatecreated,然后 Vue 调用 createdbeforeMount,要告诉 Vue 在给定的生命周期钩子上调用函数,您只需向 Vue 实例或 Vue 组件 ,并将钩子名称作为属性名称:

// The below Vue instance has a `created` hook
const app = new Vue({
  created: function() {
    console.log('Called!');
  },
  template: `
    <h1>Hello, World</h1>
  `
});

// Prints "Called!"
app.$mount('#content');

created

created 钩子 Vue 创建 Vue 实例或组件的实例之后运行。 尤其是 created 之前运行 mounted 在组件的第一次渲染之前。 由于组件尚未渲染, $el 属性 将未定义。

您可以使用异步函数作为 created 钩子,但 Vue 在渲染组件之前不会等待异步函数完成。

// This Vue instance has an async created hook
const app = new Vue({
  data: () => ({ answer: null }),
  created: async function() {
    await new Promise(resolve => setTimeout(resolve, 100));
    this.answer = 42;
  },
  // Will first render "The answer is N/A", and then
  // "The answer is 42" after 100 ms
  template: `
    <h1>The answer is {{answer == null ? 'N/A' : answer}}</h1>
  `
});

同样 beforeCreate 钩子 之前  Vue 创建实例 之间的一个主要区别 beforeCreatecreate 就是它 beforeCreate 运行 之前 Vue 实例 data 函数运行,因此任何反应属性都将在 beforeCreate

// This Vue instance has an beforeCreate hook
const app = new Vue({
  data: () => ({ data: 'test' }),
  beforeCreate: function() {
    this.data; // undefined
  },
  template: `<div></div>`
});

mounted

mounted 钩子是最常用的钩子。 Vue 运行 mounted Vue 将组件“挂载”到 DOM 。 之间有两个主要区别 mountedcreated:

  1. 当 Vue 调用时 mounted$el 属性 被定义并设置为 DOM 元素 组件附加到 当 Vue 调用时 created$el 未设置。
  2. Vue 的官方 服务端渲染 vue-server-renderer 运行 created 钩子但 不是 mounted 钩子。 这是有道理的,因为在服务器端渲染中,Vue 实例实际上从未附加到 DOM 元素,vue-server-renderer 只是输出一个包含 HTML 的字符串。

mounted 钩子通常用于 发送 HTTP 请求以加载数据以供组件显示 。 例如下面是一个使用 mounted 钩子发送 HTTP 请求以加载 有关 user

const url = 'https://jsonplaceholder.typicode.com/users/1';

const app = new Vue({
  data: () => ({ user: null, error: null }),
  // Display username if available, and error message if not
  template: `
    <div>
      <div v-if="user != null">
        {{user.name}}
      </div>
      <div v-if="error != null">
        {{error.message}}
      </div>
    </div>
  `,
  mounted
});

async function mounted() {
  try {
    this.user = await axios.get(url).then(res => res.data);
    this.error = null;
  } catch (error) {
    this.user = null;
    this.error = error;
  }
}

无论您使用 created 或者 mounted 通过 HTTP 获取数据是有争议的。 created 钩子首先运行,这意味着您可以并行化获取和渲染。 但是,另一方面,Vue 的服务器端渲染不会等待异步 created hooks 完成运行,所以你需要自己处理它。

另一方面, mounted 在组件安装后运行,这意味着您可以确保在将数据发送到服务器之前显示加载屏幕。 另外很容易手动调用 mounted 用于服务器端渲染的钩子,只要 mounted hook 不依赖 DOM 元素 $el, 例如以下是您如何调用 mounted() 服务器端上一个示例中的函数:

await mounted.call(app);
const data = await renderToString(app);
// The HTML output contains the user data
assert.ok(data.includes('Leanne Graham'));

beforeMount 钩子不同于 mounted 在那个 $el 属性仍未设置。 但是另一方面,Vue 也没有运行 beforeMount 在进行服务器端渲染时。

updated

Vue 运行 updated 挂钩 在组件安装后需要重新渲染组件的一部分时,Vue 不运行 updated 使用服务器端渲染时的钩子。

  window.numUpdated = 0;

  const app = new Vue({
    data: () => ({ count: 0 }),
    updated: function() {
      // Will print every time you click on the h1
      console.log(++window.numUpdated);
    },
    template: '<h1 v-on:click="++count">Clicked {{count}}</h1>'
  });

  app.$mount('#content');

updatedbeforeUpdate 挂钩通常仅用于分析和调试。 例如您可以插入打印语句来查看 Vue 何时需要更新,或者通过存储 当前时间来跟踪 Vue 更新的时间 Date.now()beforeUpdate 并计算差异 updated
您无法 获得必要更新的描述

destroyed

Vue 调用 destroyedbeforeDestroy 当 Vue 实例从 DOM 中卸载时钩子。 Vue 调用 beforeDestroy 在卸载实例之前,以及 destroyed 之后立马。 例如如果您为数组中的每个元素创建一个组件 elements 使用 v-for,Vue 会调用 destroyed 每次从 elements

  window.numDestroyed = 0;

  Vue.component('test', {
    destroyed: () => ++window.numDestroyed,
    props: ['num'],
    template: '<div class="test-element">{{num}}</div>'
  });

  const app = new Vue({
    data: () => ({ elements: [1, 2, 3, 4] }),
    destroyed: function() {
      // Will print every time you click on the button, because
      // Vue unmounts a `test` component every time you remove
      // an element from `elements`.
      console.log(++window.numDestroyed);
    },
    template: `
      <div>
        <test v-for="el in elements" :num="el"></test>
        <button v-on:click="elements.splice(0, 1)">
          Remove First
        </button>
      </div>
    `
  });

  app.$mount('#content');

destroyed hook 通常用于清理全局状态,例如 调用 clearInterval() 如果你开始一个间隔 mounted

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

枫以

暂无简介

文章
评论
26 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文