轻松掌握Vue.js中 import、export模块用法
一 Vue.js模块化概述
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情。
Vue.js使用了ES6模块机制中的import和export关键词来导入导出模块,模块化的目的是一是隐藏代码实现细节,让不同来源的代码块,可以组成要程序;二是避免代码块重写其他代码块的变量或函数,防止污染数据。
注意,在Node 13之前,Node环境下的JavaScript使用全局exports对象进行导入导出,为倡导JavaScript的模块机制,Node 13之后开始支持ES6的模块,本文只讨论ES6的模块机制的用法。
构建一个Vue.js脚手架项目用于示例,在项目src源代码文件夹内,新建一个export的文件夹,并创建一个index.js,用于导出数据,使用App.vue来导入数据。
二 export 导出用法
2.1 常规导出
如果想从模块导出常量、变量、函数或类,只要在声明前加上export关键字即可。
示例 //index.js
// 导出常量
export const Num = 100;
// 导出字符串变量
export let str = 'Hello World!'
// 导出数组
export let arr = [1, 3, 5, 7, 9]
//导出对象
export let obj = {
name: '张三',
age: 20,
say() {
alert(this.name)
}
}
// 导出函数
export function add(a,b){
return a+b
}
也可以不加关键词export,先正常定义常量、变量等,然后在只用一个export导出需要的值,上诉代码也等同于下面这行代码:
// 定义常量
const Num = 100;
// 定义字符串变量
let str = 'Hello World!'
// 定义数组
let arr = [1, 3, 5, 7, 9]
// 定义对象
let obj = {
name: '张三',
age: 20,
say() {
alert(this.name)
}
}
// 定义函数
function add(a, b) {
return a + b
}
// 一句话导出多个数据
export { Num,str,arr,obj,add }
这里看起来好似用花括号导出了一个对象,实际上它是一个以逗号分割的标识符列表,不会定义对象字面量。
2.2 默认导出
一个模块中导出一个函数或类是导出的应用,在这里,我们要用到default关键字,即:
// 定义函数
function add(a, b) {
return a + b
}
// 默认导出 例子1
export default add
与常规导出相比,两者的区别有两点:
- 一个js模块中,有且只能有一个export default,但是,在一个js模块中,可以有多个export。export default用于只需导出一个值时使用,也是常见的用法。
- 常规导出export的花括号中,只对有名字的声明有效,即花括号里的名字,必须欲声明;而默认导出export default则可以导出任何表达式,包括匿名函数或者匿名类,如果在export default 后面接花括号的话,说明导出的时一个实实在在的对象。
// 导出对象
export default {
name: '张三',
age: 20,
say() {
alert(this.name)
}
}
// 导出匿名方法
export default (a,b) => {
return a + b
}
使用导出时,应当注意export关键字只能出现在JavaScript代码的顶层,不能在类、函数、代码块中导出值。
三 import 导入用法
ES6中,使用import关键字来进行导入。
3.1 导入常规导出 (多个值)
// 导出多个值
const Num = 100;
let str = 'Hello World!'
let arr = [1, 3, 5, 7, 9]
let obj = {
name: '张三',
age: 20,
say() {
alert(this.name)
}
}
function add(a, b) {
return a + b
}
export { Num,str,arr,obj,add }
在App.vue文件中,用import来导入数据。
import {Num,str,arr,obj,add} from './export/index.js';
console.log(Num,str,arr,obj); // => 100 "Hello World!" (5) [1, 3, 5, 7, 9] {name: "张三", age: 20, say: ƒ}
console.log(add(4,5)); // => 9
我们用import关键字,跟着一个花括号,花括号是导入的数据名列表,再跟着一个from关键字,最后的字符串是要导入模块的文件路径。
需要注意的时,import 花括号里的数据命名要和导出 export 花括号里的数据命名一致,可以全部导入,也可以部分导入。
3.2 利用别名* as 导入多个值
在全部导入时,也可以利用* as 别名的方式来轻松导入所有值,这是创建了一个core的对象,所有的导出值都会编程cord对象的一个属性,上述例子用别名接收:
import * as core from './export/index.js';
console.log(core.Num,core.str,core.arr,core.obj); // => 100 "Hello World!" (5) [1, 3, 5, 7, 9] {name: "张三", age: 20, say: ƒ}
console.log(core.add(4,5));// => 9
3.3 导入默认导出的模块 (一个值)
export default 默认导出的值,用以下一句话代码导入:
// 默认导出 一个函数
function add (a,b) {
return a + b
}
export default add
// 导入
import add from './export/index.js';
console.log(add(4,5)); // => 9
这里用import关键字,跟着一个标识符,再跟着一个from关键字,最后的字符串是要导入模块的文件路径。标识符是一个自定义的一个常量,不必和导出的数据命名一致。所以上述导入代码中的add可以改成其他名字,如myAdd。
import myAdd from './export/index.js';
3.4 导入模块路径
import from后接的字符串,是相对于导入模块位置的路径。
模块标识符字符串必须是一个以“/”开头的绝对路径,或者是一个以“./”或“../”开头的相对路径,又或者是一个带有协议及主机名的完整URL。ES6规范不允许类似“util.js”的非限定模块标识符字符串,因为它存在歧义:它是当前模块同级目录下的一个模块呢,还是安装在特殊位置的某个系统模块呢?
如果想从当前模块的同级目录导入模块,只需要在模块名前面加上“./”,也就是使用“./util.js”而非“util.js”。
我们可以在路径字符串中,用使用@来表示src根路径,避免写错相对路径。
3.5 Vue.js 项目导入应用场景
3.5.1 导入插件
import VueRouter from 'vue-router'
import Axios from 'axios'
这里from后面接的是插件文件夹名称,从node_modules模块文件夹中查找同名文件夹,导入其内部的index.js。
3.5.2 导入组件
import HelloWorld from './components/HelloWorld.vue'
import Header from './components/Header.vue'
export default {
name: 'app',
components: {
HelloWorld,
Header
}
}
</script>
3.5.3 导入 css文件
// 导入elementui的css
import 'element-ui/lib/theme-chalk/index.css';
// 在vue单页面组件中的style标签里导入
<style>
@import './index.css';
</style>
3.6 利用别名 as 解决导入时重命名
假如两个模块使用了相同的名字导出了两个不同的值,而我们需要同时导入这两个值,可以采用as 别名的方式,将其中一个或两个重命名,解决冲突。
import { add as indexAdd } from './export/index.js'; //将add重命名
import add from './other/index.js';
四 import()函数
前面我们讲到,export import 要在模块的顶层,不能再代码块中。如果我们需要按条件加载不同的模块时,下述代码中会报错。
// 报错
if (login = true){
import loginFun from './loginFun.js'
}
ES2020引入了import()函数,2020年年初,所有支持ES6的模块的浏览器均支持了这一函数,它可以用再任何地方,不仅限于模块,非模块脚本也可以使用。
import()是运行时执行,即运行到这一句是便会加载指定的模块,上述代码就可以修改为:
// 报错
if (login = true){
import ('./loginFun.js').then(...)
}
在vue中,最常见应用在路由规则里,动态加载组件。
// 定义路由规则
const routes = [{
name: 'index',
path: '/',
component: () => import("@/pages/index")
},
{
name: 'province',
path: '/province',
component: () => import("@/pages/province")
},
{
name: 'city',
path: '/city',
component: () => import("@/pages/city")
},
{
name: '404',
path: '*',
component: () => import("@/pages/404")
}
]
\