问题描述
当你在JavaScript中使用模块导入,你可以选择导入默认导出或者命名导出,这取决于你想要使用的功能和你的模块是如何组织的。两者之间具体有什么区别?
默认导出如下所示:
import getData from '@/api/base'
命名导出如下所示:
import { getData } from '@/api/base'
表面上两者只相差一对{}
,但是在区别和用法还是很不一样的。
解决方案:
import { getData } from ‘@/api/base’:这种语法用于导入名为getData的命名导出。在@/api/base模块中,getData必须是一个命名导出。这意味着在@/api/base.js文件中,你会找到类似export const getData = …或者export function getData(){…}的代码。这些代码都是将getData作为一个命名导出,可以被其他模块导入和使用。
如代码:
export function getData(url, data) {
return request({
url: url,
method: 'get',
params: data
})
}
import getData from ‘@/api/base’:这种语法用于导入默认导出。在@/api/base模块中,getData应该是默认导出。这意味着在@/api/base.js文件中,你会找到类似export default …的代码。这个代码将某个值(可以是一个函数、一个对象、一个类等)作为默认导出,可以被其他模块导入和使用。导入默认导出的时候,你可以给它任何你喜欢的名字,例如在这个例子中,你选择了getData作为名字。
如代码:
function getData(url, data) {
return request({
url: url,
method: 'get',
params: data
})
}
export default {
getData
}
在JavaScript模块系统中,一个模块可以有一个默认导出和任意数量的命名导出。默认导出用export default语句导出,而命名导出则用export语句导出。默认导出在导入时可以使用任何名字,而命名导出在导入时必须使用导出时的名字,或者使用as关键字来重命名。
例如,如果你有一个命名为getData的命名导出,你只能用import { getData } from '@/api/base’来导入它,或者用import { getData as myFunction } from '@/api/base’来导入并重命名它。而对于默认导出,你可以用import getData from '@/api/base’或者import myFunction from '@/api/base’来导入,这里的getData和myFunction都指向@/api/base的默认导出。
看代码:
import { getData, saveData } from '../base'
/**
* 编码规则
*/
export async function list(params) {
return getData('/fone-sys/code-rule/list', params)
}
/**
* 编码规则查看
*/
export async function info(id) {
return getData(`/fone-sys/code-rule/${id}`)
}
/**
* 批量保存编码规则
*/
export async function saveBatch(params) {
return saveData('/fone-sys/code-rule/batch', params)
}
export default {
list, info, saveBatch
}
这个代码中既包含默认导出,也包含命名导出,个人感觉不规范,如果使用了命名导出,在导入到需要使用的地方时,直接使用命名导入方式更具体直观。这样子思考,这个默认导出是否会显得多余。
但是换一个角度思考,如果项目里面的调用请求很多,我们的目的是让代码之间的耦合性小,此时我们完全可以将多个封装的请求(如,根据不同功能封装的不同接口请求)导出到同一个js
文件里面,然后再统一导出(特殊的命名导出),此时上述代码中的命名导出又显得多余。
如代码:
import codeRuleService from './sys/codeRule'
import codeRuleCfgService from './sys/codeRuleCfg'
import sourceManageService from './sys/sourceManage'
export {
sourceManageService,
codeRuleService,
codeRuleCfgService,
}
这个代码段是一个ES6模块,它导入了三个其他模块并将它们导出。让我们逐一分析这个模块的各个部分:
-
import codeRuleService from './sys/codeRule'
:这行代码从./sys/codeRule
模块导入了默认导出,并将其命名为codeRuleService
。 -
import codeRuleCfgService from './sys/codeRuleCfg'
:这行代码从./sys/codeRuleCfg
模块导入了默认导出,并将其命名为codeRuleCfgService
。 -
import sourceManageService from './sys/sourceManage'
:这行代码从./sys/sourceManage
模块导入了默认导出,并将其命名为sourceManageService
。 -
export { sourceManageService, codeRuleService, codeRuleCfgService }
:这行代码将前面导入的三个服务导出,其他模块可以导入这个模块并使用这三个服务。
这个模块的作用可能是将多个服务组合在一起,使得其他模块可以一次性导入所有这些服务。这是一种常见的模式,它可以使代码更易于管理和重用。
这种导出方式实际上是命名导出的一种形式。它的特点是可以导出多个变量,每个变量都有自己的名字。这与默认导出和命名导出的基本区别如下:
-
默认导出(Default Export):
- 每个模块只能有一个默认导出。
- 在导入时,可以为默认导出的内容指定任何名称。
- 语法:
export default something
,在导入时可以自定义名称,如import anyName from './module'
。
-
命名导出(Named Export):
- 一个模块可以有多个命名导出。
- 在导入时,必须使用导出时相同的名称,除非使用
as
关键字进行重命名。 - 语法:
export { name1, name2 }
,在导入时需要使用相同的名称,如import { name1, name2 } from './module'
。
代码中export { sourceManageService, codeRuleService, codeRuleCfgService }
是命名导出的方式,它导出了三个已经定义好的变量sourceManageService
,codeRuleService
和codeRuleCfgService
。这意味着当其他模块需要导入这三个变量时,需要使用同样的名称进行导入,例如:import { sourceManageService, codeRuleService, codeRuleCfgService } from './module'
。