轻松掌握Vue.js中 import、export模块用法

5,899 阅读6分钟

轻松掌握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来导入数据。

image-20220601112532221.png

二 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

与常规导出相比,两者的区别有两点:

  1. 一个js模块中,有且只能有一个export default,但是,在一个js模块中,可以有多个export。export default用于只需导出一个值时使用,也是常见的用法。
  2. 常规导出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")
     }
 ]

\