mounted() hook 是 Vue 中最常用的 生命周期钩子 。 Vue 调用 mounted() 将组件添加到 DOM 时挂钩。 它最常用于 发送 HTTP 请求以获取 组件随后将呈现的数据。

例如下面的 Vue 组件使用 mounted() 钩子向 JSONPlaceholder API

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;
  }
}

使用异步/等待

请注意,上面的示例使用异步函数 mounted 钩。 Vue 不会 阻塞 在挂载的函数运行完成之前, mounted() 以上同时运行 axios.get(),与许多其他框架不同,Vue 提供了一种处理异步函数中的错误的机制。 Vue 都会调用 全局错误处理程序 每当生命周期钩子抛出错误时,无论错误是同步还是异步,

Vue.config.errorHandler = function (err) {
  console.log(err.message); // Oops
};

new Vue({
  template: `<h1>Hello</h1>`,
  mounted: async function() {
    await new Promise(resolve => setTimeout(resolve, 1000));
    throw new Error(Oops);
  }
}).$mount(#content);

相对于 created()

Vue 有另一个 生命周期钩子 ,类似于 mounted()created() Hook。 Vue 运行 created() 在组件对象被创建时钩子, 组件被挂载到 DOM 之前。

Vue 文档推荐使用 mounted() 勾住 created() 用于获取数据的钩子。 这一点 经常被争论 。 但是 Mastering JS 推荐使用的一个关键原因是 mounted() 用于数据获取:因为服务器端渲染。

Vue 调用 created() 在服务器端渲染期间钩子, 不是 mounted() 钩。 所以这是一个赞成的观点 created(),正确的?

问题来自于数据获取几乎总是异步的,而 的服务端渲染 Vue 等待异步 created() 完成。

// 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>
  `
});

let data = await renderToString(app);
data; // Renders answer is N/A

另一方面,很容易手动运行 mounted() 使用服务器端渲染时的钩子。

await app.$options.mounted[0].call(app);
let data = await renderToString(app);
data; // Renders answer is 42

或者,如果您有参考 mounted() 你注册的钩子,你可以在应用程序上调用它:

await mounted.call(app);
let data = await renderToString(app);
data; // Renders answer is 42

或者,您可以编写单独的逻辑以使用服务器端呈现进行获取,例如直接调用数据库而不是通过 HTTP。 使用 mounted() for data fetching 在使用服务器端渲染时为您提供了更大的灵活性,而不会牺牲任何便利性。

© 版权声明
评论 抢沙发

请登录后发表评论