Vue.js 子组件的异步加载及其生命周期控制-------异步加载子组件,子组件的生命周期控制过程不一样

小编 2026-07-01 阅读:1745 评论:0
异步组件讨论异步加载,需要先了解下异步组件。Vue.js 的异步组件是把组件定义为一个工厂函数,...

异步组件

讨论异步加载,需要先了解下异步组件。Vue.js 的异步组件是把组件定义为一个工厂函数,在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。例如注册一个全局异步组件:

Vue.component('async-demo', function(resolve, reject) {

setTimeout(function() {

// 将组件定义传入 resolve 回调函数

resolve({

template: '<div>I am async!</div>'

// 组件的其他选项

})

}, 1000)

})

异步子组件和全局注册很类似:

Vue.component('parent-demo', {

// 父组件的其他选项

components: {

'async-demo': function(resolve, reject) {

setTimeout(function() {

// 将组件定义传入 resolve 回调函数

resolve({

template: '<div>I am async!</div>'

// 子组件的其他选项

})

}, 1000)

}

}

})

工厂函数的第一个参数 resolve成功后的回调,第二个参数 reject失败后的回调,可以在这里提示用户加载失败等。

这里使用 setTimeout 只是为了模拟异步,在实际项目中,应该配合 webpack 的代码分离功能来实现异步加载。

异步加载

在实际的项目中,如果不使用异步加载,则 Vue.js 组件的 JS、CSS 和模板都会打包到一个 .js 文件中,这个文件可能达到几 MB 甚至更多,严重影响首屏加载时间。所以在项目中我们需要启用组件的异步加载。

webpack 代码分离

webpack 的代码分离有两种,第一种,也是优先选择的方式是,使用符合 ECMAScript 提案的 import() 语法。第二种,则是使用 webpack 特定的 require.ensure。让我们先看看第一种:

import() 调用会在内部用到 promises。如果在旧有版本浏览器中使用 import(),记得使用一个 polyfill 库(例如 es6-promise 或 promise-polyfill),来 shim Promise。

Vue.component(

'async-demo',

// 该 import 函数返回一个 Promise 对象。

() => import('./async-demo')

)

上面的例子中,前文提到的工厂函数支持返回一个 Promise 对象,所以可以使用 import() 这种代码分离方式。

局部注册也是类似的:

Vue.component('parent-demo', {

// 父组件的其他选项

components: {

'async-demo': () => import('./async-demo')

}

})

本质上,import() 函数返回一个 Promise 实例,你可以自定义这个过程,下文会有说明。

第二种 webpack 代码分离是这样的:

Vue.component('async-demo', function(resolve) {

require.ensure([], function(require) {

resolve(require('./async-demo'))

}, function(error) {

// 加载出错执行这里

})

})

看起来比较繁琐,如果你使用 webpack 2 及以上版本,则不建议使用第二种方式。

生命周期控制

在使用子组件(或者叫局部注册)时,我们可能需要在子组件实例化(或者叫创建完毕)后做某些事情。在非异步的子组件中,我们很容易做这件事:

<template>

<div>

<my-demo ref="demo"></my-demo>

</div>

</template>

<script>

import Demo from './Demo'

export default {

mounted() {

// 在这里可以通过组件的 $refs 获取到子组件的实例

// 可以认为,在这里子组件实例化完毕

console.log(this.$refs.demo)

},

components: {

MyDemo: Demo

}

}

</script>

上例中使用了 Vue.js 的子组件引用,所以可以在生命周期函数 mounted 中很方便的获取到子组件的实例,这样就可以在这个函数中处理一些子组件实例化后要做的事情。

但是在异步子组件中,mounted 函数中是无法获取到子组件的实例的,所以我们需要一些技巧来实现这个功能。

<template>

<div>

<my-demo ref="demo"></my-demo>

</div>

</template>

<script>

export default {

components: {

MyDemo: () => import('./Demo').then(component => {

// 清理已缓存的组件定义

component.default._Ctor = {}

if (!component.default.attached) {

// 保存原组件中的 created 生命周期函数

component.default.backupCreated = component.default.created

}

// 注入一个特殊的 created 生命周期函数

component.default.created = function() {

// 子组件已经实例化完毕

// this 即为子组件 vm 实例

console.log(this)

if (component.default.backupCreated) {

// 执行原组件中的 created 生命周期函数

component.default.backupCreated.call(this)

}

}

// 表示已经注入过了

component.default.attached = true

return component

})

}

}

</script>

上例中,可以看到我们对组件异步加载做了一些特殊的控制,其中 import().then() 则是在加载完子组件的 .js 文件后,实例化子组件之前的回调,如果需要处理出错的情况,则 import().then().catch() 即可。

以上代码只是注入了一个 created 函数,如果要注入其他生命周期函数,例如 mounted,也是类似的:

<template>

<div>

<my-demo ref="demo"></my-demo>

</div>

</template>

<script>

export default {

components: {

MyDemo: () => import('./Demo').then(component => {

component.default._Ctor = {}

if (!component.default.attached) {

component.default.backupMounted = component.default.mounted

}

component.default.mounted = function() {

if (component.default.backupMounted) {

component.default.backupMounted.call(this)

}

}

component.default.attached = true

return component

})

}

}

</script>

通过上面的讨论,我们可以做到完全控制 Vue.js 组件的异步加载的全过程,这对于需要精确控制子组件加载的组件,会有很大的帮助。

原文发布时间:06月29日

原文作者:zgpeterliu

本文来源csdn如需转载请紧急联系作者

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表