Vue基本使用
Vue.js之HelloWorld细节分析
实例参数分析
var vm = new Vue({
el: ‘#app’,
data: {
msg: ‘hello word’
}
})
- el:元素的挂载位置(值可以是CSS选择器或者DOM元素)
- data:模型数据(值是一个对象)
插值表达式用法
- 将数据填充到HTML标签中
- 插值表达式支持基本的计算操作
Vue的模板语法
模板语法概述
如何理解前端渲染?
把数据填充到HTML标签中
前端渲染方式
-
原生js拼接字符串
缺点:不同开发人员的代码风格差别很大,随着业务的复杂,后期的维护变得逐渐困难起来。
-
使用前端模板引擎
优点:大家都遵循同样的规则写代码,代码的可读性明显提高了,方便后期维护。
缺点:没有专门提供事件的机制。
-
使用vue特有的模板语法
模板语法浏览
- 差值表达式
- 指令
- 事件绑定
- 属性绑定
- 样式绑定
- 分支循环结构
指令
什么是指令
- 什么是自定义属性
- 指令的本质就是自定义属性
- 指令的个还是:以v-开始(比如v-cloak)
v-cloak指令用法
- 插值表达式存在的问题:‘闪动’
- 如何解决该问题:使用v-cloak指令
- 解决该问题的原理:先隐藏,替换好值之后再显示最终值
数据绑定指令
- v-text 填充纯文本
- 相比插值表达式更加简洁
- v-html填充HTML片段
- 存在安全问题
- 本网站内部数据可以使用,来自第三方的数据不可以用、
- v-pre填充原始信息
- 显示原始信息,跳过编译过程(分析编译过程)
数据响应式
- 如何理解响应式
- html5中的响应式(屏幕尺寸的变化导致样式的变化)
- 数据的响应式(数据的变化导致内容的变化)
- 什么是数据绑定
- 数据绑定:将数据填充到标签中
- v-once只编译一次
- 显示内容之后不再具有响应内容
作用:如果显示的信息不需要再修改,可以使用v-once,这样可以提高性能。
双向数据绑定分析
- v-model指令用法
MVVM设计思想
- M(model)
- V(view)
- VM(View-Model)
事件绑定
Vue如何处理事件
- v-on指令用法
<input type = ‘button’ v-on:click = ‘num ++’/>
- v-on简写形式
<input type = ‘button’ @click = ‘num ++’/>
- 事件函数的调用方式
<button v-on:click = ‘say’>Hello</buttton>
- 调用函数
<button @click = ‘say’>Hello</buttton>
事件函数参数传递
- 普通参数和事件对象
<button v-on:click=‘say(“hi”,$event)’>Say hi </button>
注意:
- 如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数
- 如果事件绑定函数调用,那么事件对象必须作为最后一个参数显示传递,并且事件对象的名称必须是$event
事件修饰符
- .stop阻止冒泡
<a v-on:click.stop = “handle”>跳转</a>
- .prevent阻止默认行为
<a v-on:click.prevent = “handle”>跳转</a>
按键修饰符
- .enter回车键
<input v-on:keyup.enter = ‘submit’>
- .delete删除键
<input v-on:keyup.delete = ‘handle’>
自定义按键修饰符
- 全局config.keyCodes对象
Vue.config.keyCodes.f1 = 112
属性绑定
Vue如何动态处理属性
- v-bind指令用法
<a v-bind:href = ‘url’>跳转</a>
- 缩写形式
<a :href = ‘url’>跳转</a>
v-model的底层实现原理分析
<input v-bind:value = “msg” v-on:input = “msg=$event.target.value”>
样式绑定
class样式处理
- 对象语法:
<div v-bind:class = “{active:isActive}”></div>
- 数组语法:
<div v-bind:class = “[activeClass,errorClass]”></div>
样式绑定相关语法细节:
- 对象绑定和数组绑定可以结合使用
- class绑定的值可以简化操作
- 默认的class会保留
style样式处理
- 对象语法
<div v-bind:style = “{color:activeColor,fontSize:fontSize}”></div>
- 数组语法
<div v-bind:style = “[baseStyles,overridingStyles]”></div>
分支循环结构
分支结构
- v-if
- v-else
- v-else-if
- v-show
v-if与v-show的区别
- v-if控制是否渲染到页面
- v-show控制元素是否显示(已经渲染到了页面)
循环结构
- v-for遍历数组
<li v-for=‘item in list’>{{item}}</li>
<li v-for=’{item,index} in list’>{{item}} + ‘----’ + {{index}}</li>
- key的作用:帮助Vue区分不同的元素,从而提高性能
<li :key = ‘item.id’ v-for = ‘{item,index} in list’>{{item}} + ‘—’ {{index}}</li>
- v-for遍历对象
< v-for=’(value,key,index) in object’></div>
- v-if和v-for结合使用
<div v-if = ‘value ==12’ v-for = ‘(value,key,index)in object’></div>
Vue常用特性
常用特性概览
- 表单操作
- 自定义指令
- 计算属性
- 过滤器
- 侦听器
- 生命周期
表单操作
基于Vue的表单操作
- Input 单行文本
- textarea 多行文本
- seect 下拉多选
- radio 单选框
- checkbox 多选框
表单域修饰符
- number:转化数值
- trim:去掉开始和结尾的空格
- lazy:将input事件切换为change事件
<input v-model.number = “age” type = “number”>
自定义指令
为何需要自定义指令?
内置指令不满足需求
自定义指令的语法规则(获取元素焦点)
Vue.directive(‘focus’ {
inserted:function(el){
el.focus
}
})
自定义指令用法
<input type = “text” v-focus>
带参数的自定义指令
Vue.directive(‘color’,{
inserted:function(el,binding){
el.style.backgroundColor = binding.value.color;
}
})
指令的用法
<input type = “text” v-color = ‘{color:“orange”}’>
计算属性
为何需要计算属性?
表达式的计算逻辑可能会比较复杂,使用计算属性可以使模板内容更加简洁
计算属性用法
computed:{
reversedMessage:function(){
return this.msg.split(’’).reverse().join(’’)
}
}
计算属性与方法的区别
- 计算属性是基于它们的依赖进行缓存的
- 方法不存在缓存
侦听器
侦听器的应用场景
侦听器变化时执行异步或开销比较大的操作
侦听器的用法
watch:{
firstName:function(val){
this.fullName = val + this.lastName;
},
lastName:function(val){
this.fullName = this.firstName + val;
}
}
过滤器
过滤器的作用是什么
格式化数据,比如将字符串格式化为首字母大写,将日期格式化为指定的格式等
自定义过滤器
Vue.filter(‘过滤器名称’,function(value){
//过滤器业务逻辑
})
过滤器的使用
<div>{{msg | upper}}</div>
<div>{{msg | upper | lower}}</div>
<div v-bind:id = “id | formatId”></div>
局部过滤器
filters:{
capitalize:function(){}
}
带参数的过滤器
Vue.filter(‘过滤器名称’,function(value,arg1){
第一个参数是过滤器传递过来的参数
})
过滤器使用
<div>{{date | format(‘yyyy-mm-dd’)}}</div>
生命周期
主要阶段
- 挂载(初始化相关属性)
- beforeCreate
- created
- beforeMount
- mounted
- 更新(元素或组件的变更操作)
- beforeUpdate
- updated
- 销毁(销毁相关属性)
- beforeDestroy
- destroyed
vue实例的产生过程
- beforeCreate在实例初始化之后,数据观测和事件配置之前被调用
- created在实例创建完成之后被立即调用
- beforeMount在挂载开始之前被调用
- mounted el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。
- beforeUpdate数据更新调用,发生在虚拟DOM打补丁之前
- updated 由于数据更改导致的虚拟DOM重新渲染和补丁,在这之后会调用该钩子。
- beforeDestroy实例销毁之前调用
- destroyed 实例销毁之后调用
补充知识
变异方法(修改原有数据)
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
替换数组(生成新的数组)
- filter()
- concat()
- slice()
修改响应式数据
- Vue.set(vm.item,indexOfltem,newValue)
- vm.$set(vm.items,indexOfltem,newValue)
- 参数1:表示要处理的数组名称
- 参数2:表示要处理的数组索引
- 参数3:表示要处理的数值值
组件开发思想
组件化规范:Web Components
- 我们希望尽可能多的重用代码
- 自定义组件的方式不太容易(html,css和js)
- 多次使用组件可能导致冲突
Web Components通过创建封装好的功能的定制元素解决上述问题
组件注册
全局组件注册语法
Vue.component(组件名称,{
data:组件数据,
template:组件模板内容
})
例子:
Vue.component(‘button-counter’, {
data: function () {
return { count: 0 }
},
template: ‘<button @click = “count++”>点击了{{count}}次’
})
组件注册注意事项
- data必须是一个函数
- 组件模板必须是单个根元素
- 组件模板内容可以是模板字符串
- 组件的命名方式
- 短横线方式
Vue.component(‘my-component’,{/* … */})
- 驼峰方式
Vue.component(‘MyComponent’,{/* … */})
如果使用驼峰方式命名,那么在使用的时候,只能在字符串模板中用驼峰的方式使用组件,但是在普通的标签模板中,必须使用短横线的方式使用组件。
局部组件注册
var ComponentA = {/* … */}
new Vue({
el:’#app’,
components:{
‘component-a’:ComponentA
}
})
局部注册的组件只能在注册它的父组件中使用
Vue调试工具用法
- 克隆仓库
- 安装依赖包
- 构建
- 打开Chrome扩展页面
- 选中开发者模式
- 加载已解压的扩展,选择shells/chrome
组件之间数据交互
父组件向子组件传值
组件内部通过props接收传递过来的值
Vue.component(‘menu-item’,{
props:[‘title’],
template:’<div>{{title}}</div>’
})
父组件通过属性将值传递给子组件
<menu-item title = ‘来自父组件的数据’></menu-tiem>
<menu-item : title =‘tiitle’><menu-item>
props属性名规则
- 在props中使用驼峰形式,模板中需要使用短横线的形式
- 字符串形式的模板没有这个限制
props属性值类型
- 字符串String
- 数组 Number
- 布尔值 Boolean
- 数组 Array
- 对象 Object
子组件向父组件传值
子组件通过自定义事件向父组件传递信息
<button v-on:click = ‘$emit(“enlarge-text”,0.1)’>扩大字体</button>
父组件监听子组件的事件
<menu-item v-on:enlarge-text = 'fortSize += $event '></menu-item>
非父子组件间传值
单独的事件中心管理组件间的通信
var eventHub = new Vue()
监听事件与销毁事件
eventHub.$on(‘add-todo’,addTodo)
eventHub.$off(‘add-todo’)
触发事件
eventHub.$emit(‘add-todo’,id)
组件插槽
组件插槽的作用
父组件向子组件传递内容
组件插槽的基本用法
插槽的位置
Vue.component(‘alert-box’,{
template:`
<div class = “demo-alert-box”>
<strong>Error!</strong>
<slot></slot>
</div>
`
})
插槽内容
<alert-box>Something bad happened </alert-box>
具名插槽用法
插槽定义
Vue.component(‘alert-box’, {
template: `
`
})
插槽用法
<p slot=‘header’>标题
<p>主体
<p slot=‘footer’>底部
作用域插槽
- 应用场景:父组件对子组件的内容进行加工处理
插槽定义
Vue.component(‘fruit-list’, {
props: [‘list’],
template: `
-
{{item.name}}
`
})
插槽用法
{{slotProps.info.name}}
{{slotProps.info.name}}
前后端交互模式
接口调用方式
- 原生ajax
- 基于jQuery的ajax
- fetch
- axios
URL地址格式
传统形式的URL
- 格式:sechema://host:port/path?query#fragment
- schema:协议。例如http、https、ftp等
- host:域名或IP地址
- port:端口号,http默认端口号是80,可以省略
- path:路径,例如/abc/a/b/c
- query:查询参数,例如uname = lisi&age=12
- fragment:锚点(哈希Hash),用于定位页面的某个位置
- 符合规则的URL
- http://www.baidu.cn
- http://www.baidu.cn/java/web
- http://www.baidu.cn/java/web?flag =1
- http://www.baidu.cn/java/web?flage = 1 # function
Restful形式的URL
- HTTTP请求方式
- GET 查询
- POST 添加
- PUT 修改
- DELETE 删除
- 符合规则的URL地址
- http://www.hello.com/books GET
- http://www.hello.com/books POST
- http://www.hello.com/books/123 PUT
- http://www.hello.com/books/123 DELETE
Promise用法
异步调用
异步效果分析
- 定时任务
- Ajax
- 事件函数
多次异步调用的依赖分析
- 多次异步调用的结果顺序不确定
- 异步调用结果如果存在依赖需要嵌套
Promise概述
Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作信息。
使用Promise主要的好处:
- 可以避免多层异步调用嵌套问题(回调地狱)
- Promise对象提供了简介的API,使得控制异步操作更加容易
Prromise基本用法
- 实例化Promise对象,构造函数中传递函数,该函数用于处理异步任务
- resolve和reject两个参数用于处理成功和失败两种情况,并通过p.then获取处理结果。
var p = new Promise(function(resolve,reject){
//成功时调用resolve()
//失败时调用reject()
});
p.then(function(ret){
//从resolve得到正常结果
}),function(ret){
//从reject得到错误结果
}
基于Promise处理Ajax请求
处理原生Ajax
function queryData(url) {
var p = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest()
xhr.open(‘get’, url)
xhr.send(null)
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.responseText)
} else {
reject(‘服务器出现错误’)
}
}
return p
})
}
queryData(url).then(function (data) {
console.log(data);
}, function (info) {
console.log(info);
})
发送多次Ajax请求
queryData(url - 1).then(function (data) {
console.log(data);
return queryData(url - 2)
}).then(function (data) {
console.log(data);
return queryData(url - 3)
}).then(function (data) {
console.log(data);
})
then参数中的参数返回值
返回Promise实例对象
- 返回的该实例对象会调用下一个then
返回普通值
- 返回的普通值会直接传递给下一个then,通过then参数中的函数的参数接收该值
Promise常用的API
实例方法
- p.then()得到异步任务的正确结果
- p.catch()获取异常信息
- p.finally()成功与否都会执行(尚且不是正式标准)
对象方法
- Promise.all()并发处理多个异步任务,所有任务都执行完成才能得到结果
- Promise.race()并发处理多个异步任务,只要有一个任务完成就能得到结果
Promise.all({p1,p2,p3}.then(result) =>{
console.log(result)
})
Promise.race({p1,p2,p3}.then(result) =>{
console.log(result)
})
接口调用-fetch用法
fetch概述
基本特性
- 更加简单的数据获取方式,功能更加强大、灵活、可以看做是xhr的升级版
- 基于Promise实现
语法结构
fetch(url).then(fn2)
.then(fn3)
…
.catch(fn)
fetch的基本用法
fetch(’/abc’).then(data =>{
return data.text()
}).then(ret=>{
//注意这里得到的才是最终数据
console.log(ret)
})
fetch请求参数
常用配置选项
- method(String):HTTP请求方法,默认为GET(GET,POST,PUT,DELETE)
- body(String):HTTP的请求参数
- headers(Object):HTTP的请求头,默认为{}
fetch(’/abc’,{
method: ‘get’
}).then(data =>{
return data.text()
}).then(ret=>{
console.log(ret)
})
GET请求方式的参数传递
fetch(’/abc/123’,{
method: ‘get’
}).then(data =>{
return data.text()
}).then(ret=>{
console.log(ret)
})
POST请求方式的参数传递
fetch(’/abc/123’,{
method: ‘post’,
body:‘uname = list &pwd = 123’,
headers:{
‘Content-Type’:‘application/x-www-form-urlencoded’,
}
}).then(data =>{
return data.text()
}).then(ret=>{
console.log(ret)
})
PUT请求方式的参数传递
fetch(’/abc/123’,{
method: ‘put’,
body:JSON.stringfy({
uname:‘lisi’
age:12
}),
headers:{
‘Content-Type’:‘application/json’,
}
}).then(data =>{
return data.text()
}).then(ret=>{
console.log(ret)
})
fetch响应结果
响应数据格式
- text():将返回体处理成字符串类型
- json():返回结果和JSON.parse(responseText)一样
接口调用-axios用法
axios的基本特性
axios是一个基于Promise用于浏览器和node.js的HTTP客户端。
它具有以下特征:
- 支持浏览器和node.js
- 支持promise
- 能拦截请求和响应
- 自动转换JSON数据
axios的基本用法
axios.get(’/adata’).then(ret=>{
//data属性名称是固定的,用于获取后台响应数据
console.log(ret.data)
})
axios的常用API
- get : 查询数据
- post:添加数据
- put:修改数据
- delete:删除数据
axios的参数传递
GET传递参数
- 通过URL传递参数
- 通过parms选项传递参数
axios.get(’/adata?id=123’).then(ret=>{
console.log(ret.data)
})
axios.get(’/adata’,{
params:{
id:123
}
}).then(ret=>{
.then(ret=>{
console.log(ret.data)
})
})
DELETE传递参数
- 参数传递方式与GET类似
axios.delete(’/adata?id=123’).then(ret=>{
console.log(ret.data)
})
POST传递参数
- 通过选项传递参数(默认传递的是json格式的数据)
axios.post(’/adata’,{
uname:‘tom’,
pwd:123
}).then(ret=>{
console.log(ret.data)
})
- 通过URLSearchParams传递参数(applicattion/x-www-form-urlencoded)
const params = new URLSearchParams();
params.append(‘param1’,‘value1’)
params.append(‘param2’,‘value2’)
axios.post(’/api/text’,params).then(ret=>{
console.log(ret.data)
})
put传递参数
- 参数传递方式与POST类似
axios.put(’/adata/123’,{
uname:‘tom’,
pwd:123
}).then(ret=>{
console.log(ret.data)
})
axios的响应结果
响应结果的主要属性
- data:实际响应回来的数据
- headers:响应头信息
- status:响应状态码
- statusText:响应状态信息
axios的全局配置
- axios.defaults.timeout = 3000; //超时时间
- axios.defaults.baseURL = ‘http://localhost:3000/app’; 默认地址
- axios.defaults.headers[ ‘mytoken’ ] = ‘awadwaadasdawdasdcasdawd’ //设置请求头
axios拦截器
请求拦截器
在请求发出之前设置的一些信息
//添加一个请求拦截器
axios.interceptors.request.use(function(config){
//在请求发送之前进行一些信息设置
return config;
},function(err){
//处理响应的错误信息
})
响应拦截器
在获取数据之前对数据做一些加工处理
//添加一个响应拦截器
axios.interceptors.responseuse(function(config){
//在请求发送之前进行一些信息设置
return config;
},function(err){
//处理响应的错误信息
})
接口调用-async/await用法
- async/await是ES7引入的新语法,可以更加方便的进行异步操作。
- async关键用于函数上(async函数的返回值是Promise实例对象)
- await关键字用于async函数当中(await可以得到异步的结果)
async function queryData(id){
const ret = await axios.get(’/data’);
return ret;
}
queryData.then(ret =>{
console.log(ret)
})
async/await处理多个异步请求
多个异步请求场景
async function queryData(id){
const info = await axios.get(’/async1’);
const ret = await axios.get(‘async2?info=’+info.data)
return ret;
}
queryData.then(ret =>{
console.log(ret)
})
路由的基本概念和原理
路由
路由是一个比较广义和抽象的概念,路由的本质就是对应的关系。
在开发中,路由分为:
- 后端路由
- 前端路由
后端路由
- 概念:根据不同的用于 URL请求,返回不同的内容。
- 本质:URL请求地址与服务器资源之间的对应关系。
SPA
- 后端渲染(存在性能问题)
- Ajax前端渲染(前端渲染提高性能,但是不支持路由器的前景后退操作)
- SPA(Single Page Application)单页面应用程序:整个网站只有一个页面,内容的变化通过Ajax局部更新实现、同时支持路由器地址的前进和后退操作。
- SPA实现原理之一:基于URL地址的hash(hash的变化会导致路由器记录访问历史的变化、但是hash的变化不会触发新的URL请求)
- 在实现SPA过程中,最核心的技术就是前端路由。
前端路由
- 概念:根据不同的用户事件,显示不同的页面内容。
- 本质:用户事件与事件处理函数之间的对应关系
实现简易的前端路由
- 基于URL中的hash实现(点击菜单的时候改变的hash,根据hash的变化控制组件的切换)
监听window的onhashchange事件,根据获取到的最新的hash值,切换要显示的组件的名称
window.onhashchange = function(){
//通过location.hash获取到最新的hash值
}
Vue Router
Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,可以非常方便的用于SPA应用程序的开发。
Vue Router包含的功能有:
- 支持HTML5历史模式或hash模式
- 支持嵌套路由
- 支持路由参数
- 支持编程式路由
- 支持命名路由
vue-router的基本使用
基本使用步骤
- 引入相关的库文件
- 添加路由链接
- 添加路由填充位
- 定义路由组件
- 配置路由规则并创建路由实例
- 把路由挂载到Vue根实例中
例子:
User
Register
路由重定向
路由重定向指的是:用户在访问地址A的时候,强制用户跳转到地址c,从而展示特点的组件页面
通过路由规则的redirect属性,指定一个新的路由地址,可以方便地设置路由的重定向。
var router = new VueRouter({
routes: [
{ path: ‘/’, redirect: /user },
]
})vue-router嵌套路由
嵌套路由用法
嵌套路由功能分析
- 点击父级路由链接显示模板内容
- 模板内容中有子级路由链接
- 点击子级路由链接显示子级模板内容
1.父路由组件模板
- 父级路由模板
- 父组件路由填充位
2.子级路由模板
- 子级路由链接
- 子级路由填充位
3.嵌套路由配置
- 父级路由通过children属性配置子级路由
vue-router动态路由匹配
动态匹配路由的基本用法
应用场景:通过动态由参数的模式进行路由匹配
var router = new VueRouter({
routes:[
//动态路径参数 以冒号开头
{path:’/user/:id’,component:User }
]
})
const User = {
//路由组件中通过$route.params获取路由参数
template:’<div>User{{$route.params.id}}</div>
}
路由组件传递参数
$route与对应路由形成高度耦合,不够灵活,所以可以使用props将组件和路由解耦
1.props的值为布尔值
props:true
2.props的值为对象类型
props:{uname:‘lisi’,age:20}
3.props的值为函数类型
props:route=>({uname:‘zs’,age:20,id:route.params.id})
命名路由的配置规则
为了更加方便的表示路由的路径,可以给路由规则起一个别名,即为"命名路由"
var router = new VueRouter({
routes: [
{ path: ‘/’, redirect: ‘/user’ },
{ name: ‘user’, path: ‘/user/:id’, component: User, props: true },
{
path: ‘/register’, component: Register, children: [
{ path: ‘/register/tab1’, component: tab1 },
{ path: ‘/register/tab2’, component: tab2 }
]
}
]
})
vue-router编程式导航
页面导航的两种方式
- 声明式导航:通过点击链接事件导航的方式,叫做声明式导航
例如:普通页面中的<a></a>链接或vue中的<router-link></router-link>
- 编程式导航:通过调用JavaScript形式的API实现导航的方式,叫做编程式导航
例如:普通页面中的location.href
编程式导航基本用法
常用的编程式导航API如下:
- this.$router.push(‘hash地址’)
- this.$router.go(n)
模块化相关规范
模块化概述
传统开发模式的主要问题
- 命名冲突
- 文件依赖
通过模块化解决上述问题
- 模块化就是把单独的一个功能装到一个模块(文件)中,模块之间相互隔离,但是可以通过特定的接口公开内部成员,也可以依赖别的模块。
- 模块开发的好处:方便代码的重用,从而提升了开发效率,并且方便后期的维护
浏览器模块化的规范
AMD
代表:require.js
CMD
代表:Sea.js
服务器模块化规范
CommonJS
- 模块化分为单文件模块与包
- 模块成员导出:module.exports和exports
- 模块成员导入:require(‘模块标识符’)
大一统的模块化规范-ES6模块化
在ES6模块化诞生之前,JavaScript社区已经尝试并提出了AMD、CMD、CommonJS等模块规范。
但是,这些社区提出的模块化标准,还是存在一定的差异性和局限性、并不是浏览器与服务器通用的模块化标准,例如:
- AMD和CMD适用于浏览器端的JavaScript模块化
- CommonJS适用于服务器端的JavaScript模块化
因此,ES6语法规范中,在语言层面上定义了ES6模块化规范,是浏览器与服务器通用的模块化开发规范。
ES6模块化规范中定义:
- 每个js文件都是一个独立的模块
- 导入模块成员使用import关键字
Node.js中通过babel体验ES6模块化
-
npm install --sava-dev @babel/core @babel/cli @babel/preset-env @babel/node
-
npm install --save @bael/polyfill
-
项目更目录创建文件babel.config.js
const presets = [ ["@babel/env",{ targets:{ edge:"17", firefox:"60", chrome:"67", safari:"11.1" } }] ] //暴露 module.exports = { presets }
-
babel.config.js文件内容如右侧代码
-
通过npx babel-node index.js执行代码
ES6模块化的基本语法
默认导出与默认导入
- 默认导出语法export default默认导出的成员
- 默认导入语法import接收命名from’模块标识符’
注意:每个模块中,只允许使用唯一的一次export default,否则会报错!
按需导出与按需导入
- 按需导出语法 export let s1 = 10
- 按需导入语法 import {s1} from ‘模块标识符’
直接导入并执行模块代码
有时候,我们只想单纯执行某个模块中的代码,并不需要得到模块中向外暴露的成员,此时,可以直接导入并执行模块代码。