【Vue】加载异步组件时的resolve函数

见识到了一些没见过的写法, 网上找不到满意的答案, 只好自己找咯,希望能够帮到其他人, 学习ing+++

原代码

const router = new VueRouter({
    routes: [{
        path: '/foo', 
        component: resolve => require(['/foo'], resolve)
    }]
})

问题

  1. resolve => require(['/foo'], resolve) 中的 resolve 是什么?
  2. require 的二参是什么?

答案

  1. resolve 函数
var resolve = function (resolvedDef) {
    if (isESModule(resolvedDef)) {
        resolvedDef = resolvedDef.default;
    }
    def.resolved = typeof resolvedDef === 'function' ?
        resolvedDef :
        _Vue.extend(resolvedDef);
    match.components[key] = resolvedDef;
    pending--;
    if (pending <= 0) {
        next();
    }
};
  1. 模块引入后的回调函数, 接收一参引入的模块作为参数, 引入多个模块时以多参而非数组形式传递

探寻步骤

  1. component 中打印 resolve, 发现其值是 node_modules\_vue-router@3.3.4@vue-router\dist\vue-router.esm.js 文件中 once 函数返回的匿名函数
// 确保函数只执行一次
function once(fn) {
  var called = false;
  return function () {
    var args = [],
      len = arguments.length;
    while (len--) args[len] = arguments[len];

    if (called) {
      return
    }
    called = true;
    return fn.apply(this, args)
  }
}
  1. vue-router.esm.js 文件中找到 once 函数及调用 onceresolveAsyncComponents 函数

resolveAsyncComponents 函数代码片段

var resolve = once(function (resolvedDef) {
    if (isESModule(resolvedDef)) {
        resolvedDef = resolvedDef.default;
    }
    def.resolved = typeof resolvedDef === 'function' ?
        resolvedDef :
        _Vue.extend(resolvedDef);
    match.components[key] = resolvedDef;
    pending--;
    if (pending <= 0) {
        next();
    }
});

var reject = once(function (reason) {
    var msg = "Failed to resolve async component " + key + ": " + reason;
    process.env.NODE_ENV !== 'production' && warn(false, msg);
    if (!error) {
        error = isError(reason) ?
            reason :
            new Error(msg);
        next(error);
    }
});
  1. 可以看出最开始问题中的 resolve 函数就是上述代码中 once 函数中的匿名函数, 即:
var resolve = function (resolvedDef) {
    if (isESModule(resolvedDef)) {
        resolvedDef = resolvedDef.default;
    }
    def.resolved = typeof resolvedDef === 'function' ?
        resolvedDef :
        _Vue.extend(resolvedDef);
    match.components[key] = resolvedDef;
    pending--;
    if (pending <= 0) {
        next();
    }
};

var reject = function (reason) {
    var msg = "Failed to resolve async component " + key + ": " + reason;
    process.env.NODE_ENV !== 'production' && warn(false, msg);
    if (!error) {
        error = isError(reason) ?
            reason :
            new Error(msg);
        next(error);
    }
};

结论

  1. 最开始问题里的 resolve (注意 resolve 只是形参) 是 vue-router 返回的方法, 只执行一次, 用于(挂载组件?), 接收 require 引入的模块为参数

  2. require 的一参为要引入的模块, 为多个时用数组形式传入, 二参为引入完成后的回调函数, 该回调函数的参数为一参引入的模块, 多个模块时为多个参数而不是数组

  • 改写为以下形式也可执行
const router = new VueRouter({
    routes: [{
        path: '/foo', 
        component: mount => require(['/foo'], (mod) => {
            mount(mod);
        })
    }]
})
  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值