ES6模块命令:export和import

在做前端开发时,我们使用import引入需要的模块时会发现一个问题,有的需要使用 {},有的不需要:

import { AUDIT } from './constants.js'
import tools from '@/utils/tools'

这其实前端ES6的模块命令,初次接触的小白肯定会很疑惑,这里就具体讲一下ES6的模块命令,学习完就能解答上面的问题了。

概述: 在ES6之前的模块加载方案主要有CommonJS 和 AMD 两种。但这两种都只能在运行时加载,无法做到在编译时静态优化。ES6新增了两个模块命令:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

模块

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。

// constants.js
const AUDIT = {
    COLUMNS: [
        {
            title: '操作人员',
            dataIndex: 'operator'
        },
        {
            title: '时间',
            dataIndex: 'datetime'
        },
        {
            title: '操作类型',
            dataIndex: 'operation'
        }
    ]
}

这里constants.js就是一个模块,它的变量AUDIT此时是无法被外部获取使用的。如果你希望外部能够读取constants.js模块中的AUDIT变量,就必须使用export关键字输出该变量。

export 命令

export命令显式指定输出的代码

// constants.js
export { AUDIT }

这里用export命令对外部输出了AUDIT常量。

除了上面那种写法,还有另外一种写法:

// constants.js
export const AUDIT = {
    COLUMNS: [
        {
            title: '操作人员',
            dataIndex: 'operator'
        },
        {
            title: '时间',
            dataIndex: 'datetime'
        },
        {
            title: '操作类型',
            dataIndex: 'operation'
        }
    ]
}

export命令除了输出变量,还可以输出函数或类(class)。

export function multiply (x, y) {
  return x * y
}

对外输出一个函数multiply

关键字as的使用:

function v1() { ... }
function v2() { ... }

export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
}

上面代码使用as关键字,重命名了函数v1和v2的对外接口。重命名后,v2可以用不同的名字输出两次。

import 命令

使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。

import { AUDIT } from './constants.js'

上面的import命令,用于加载constants.js文件,并从中获取变量。import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(constants.js)对外接口的名称相同。

注意:
1、import命令输入的变量都是只读的,不允许在外部改写。

2、import后面的from指定模块文件的位置,可以是相对路径,也可以是绝对路径。如果不带有路径,只是一个模块名,那么必须有配置文件,告诉 JavaScript 引擎该模块的位置。

import { mapActions } from 'vuex'

export default 命令

上面介绍了exportimport,我们发现使用import命令的时候,我们必须知道所要使用的模块中的变量名或函数名,否则无法引入。为了解决这个问题,就要用到export default命令,为模块指定默认输出。

// settings.js
const list = {
    url: `/settings/`,
    method: 'get'
}

const add = {
    url: `/settings/`,
    method: 'post'
}
export default {
    list,
    add
}

引入使用时,不需要使用{},而且可以为该变量指定任意名字customName

import customName from './settings'

注意:export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此export default命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能唯一对应export default命令。

这里就解释了我们开头遇到的问题,tools引入不需要大引号:

import tools from '@/utils/tools'
// tools.js
const tools = {
    /**
     * 判断传入值是否为空
     * @param {Any} value 值
     */
    isEmpty (value) {
        const dataType = checkDataType(value)
        let isEmpty
        switch (dataType) {
            case 'String':
                isEmpty = value === ''
                break
            case 'Array':
                isEmpty = !value.length
                break
            case 'Object':
                isEmpty = !Object.keys(value).length
                break
            default:
                isEmpty = false
        }
        return isEmpty
    },
    
    /*
      对象数组根据某个key进行排序
    */
    compare (key) {
        return (a, b) => {
            const val1 = a[key]
            const val2 = b[key]
            return val1 - val2
        }
    }
}

export default tools

import() 命令

前面说过,import命令是静态的,固然有利于编译器提高效率,但也导致无法在运行时加载模块,所以它无法做到按需加载条件加载,要想满足这两种场景,我们可以使用import()函数。

import()函数相当于NODE中的require方法,它返回一个Promise对象。

例一:按需加载

button.addEventListener('click', event => {
  import('./dialogBox.js')
  .then(dialogBox => {
    dialogBox.open();
  })
  .catch(error => {
    /* Error handling */
  })
});

上面代码中,import()方法放在click事件的监听函数之中,只有用户点击了按钮,才会加载这个模块。

例二:条件加载

if (condition) {
  import('moduleA').then(...);
} else {
  import('moduleB').then(...);
}

根据不同的情况,加载不同的模块。

注意:import()加载模块成功以后,这个模块会作为一个对象,当作then方法的参数.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容