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方法的参数.

posted @ 2021-11-23 13:56  yingzi__block  阅读(413)  评论(0编辑  收藏  举报