【图文并茂,点赞收藏哦!】重学巩固你的Vuejs知识体系(上)
前沿
置身世外只为暗中观察!!!Hello大家好,我是魔王哪吒!重学巩固你的Vuejs知识体系,如果有哪些知识点遗漏,还望在评论中说明,让我可以及时更新本篇内容知识体系。欢迎点赞收藏!






谈谈你对MVC、MVP和MVVM的理解?
https://github.com/webVueBlog/interview-answe/issues/156
转角遇到Vuejs
- 你为啥学习Vuejs 
- 前端开发的复杂化 
- Vuejs的特点 
- 安装Vuejs 
- 体验Vuejs 
- MVVM架构:data和Vue对象的分离,Vue中的MVVM 

目录:

起步
- 插值语法:Mustache,v-once,v-html,v-text,v-pre,v-block。 
- 绑定属性:v-bind的介绍,v-bind的基础,v-bind的语法糖,绑定class,绑定样式。 
- 计算属性 
- 事件监听:v-on介绍,v-on基础,v-on参数,v-on修饰符 
- 条件和循环:条件渲染,v-show指令,v-if和v-show对比 
- 表单绑定:基本使用,v-model原理,其他类型,值绑定,修饰符。 
组件化开发:
什么是组件化,Vue组件化开发思想
- 注册的步骤 
- 全局和局部组件 
- 父组件和子组件 
- 注册组件语法糖 
- 模板的分离写法 
- 组件的其他属性 
- 父级向子级传递 
- 子级向父级传递 
- 父子组件的访问 
- 非父子组件通信 
组件化高级语法:
- 插槽slot:编译作用域,为什么使用slot,slot的基本使用,slot的具名插槽,slot的作用域插槽。 
- 动态组件 
- 异步组件 
- 组件声明周期 
Vue Cli
- 什么是webpack 
- webpack和gulp对比 
- 手动webpack的配置 
- Vue Cli是什么 
- Vue Cli依赖环境 
- Vue Cli的安装 
网络封装
- 使用传统的Ajax是基于XMLHttpRequest(XHR) 
- 使用jQuery-Ajax 
- Vue-resource 
- 使用axios 
axios的使用
- 了解axios:axios请求方式 
- 发送请求,发送get请求,发送并发请求,axios全局配置,常见配置选项。 
- axios实例,为什么创建axios实例,如何创建axios实例,axios的封装。 
- axios的拦截器:请求和响应 
vuejs原理相关:响应式原理,源码。
vue.js是什么
- vue是一套用于构建用户界面的渐进式框架。 
- 从自底向上逐层应用,核心库是只关注图层。 
- 易于学习,便于与第三方库或既有项目整合。 
Vue基础语法
对于基础知识需要掌握,简单写写✍
vue.js安装
直接CDN引入:
- 对于制作原型或学习 
代码:
- 对于生产环境 
代码:
- NPM 
代码:
# 最新稳定版
$ npm install vue
vue响应式初体验
声明式编程:
代码:
 
  "utf-8">
  
  
  
 
 
  "app">
    {{ a }}
  
  
  
 


小案例-计算器
- 新的属性: - methods,该属性是用于- Vue对象中定义的方法。
- 新的指令: - @click,该指令是用于监听某个元素的点击事件,并且需要指定当发生点击时,执行的方法。
代码:
"app">
    当前计数{{counter}}
    
    
Vue中的MVVM
MVVM的思想
- view是我们的DOM 
- Model是我们抽离出来的obj 
- ViewModel是我们创建的Vue对象实例 
它们之间是如何工作的呢?
- ViewModel通过Data Binding让obj中的数据实时在DOM中显示 
- ViewModel通过DOM Listener来监听DOM事件,并且通过methods中的操作,来改变obj中的数据 

- el:类型:- string | HTMLElement
- 作用:决定之后Vue实例会管理哪一个 - DOM
- data:类型:- Object | Function
- 作用:Vue实例对应的数据对象 
- methods:类型:- {[key:string]:Function}
- 作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用。 
什么是Vue的生命周期
生命周期:☞ 事物从诞生到消亡的整个过程
- release稳定版本
- debug版本
- Mustache语法也就是双大括号 
- 插值操作 
- 绑定属性 
- 计算属性 
- 事件判断 
- 循环遍历 
- 阶段案例 
- v-model 
v-once指令的使用
"app">
 {{message}}
 {{message}}
v-once:
- 该指令后面不需要跟任何表达式 
- 该指令表示元素和组件只渲染一次,不会随着数据的改变而改变 
v-html:
当我们从服务器请求到的数据本身就是一个HTML代码时
- 如果直接通过 - {{}}来输出,会将- HTML格式进行解析,并且显示对应的内容。
- 可以使用 - v-html指令
- 该指令后跟上一个 - string类型
- 会将 - string的- html解析处理并且进行渲染
"url">
v-text的作用和Mustache比较相似,独使用于将数据显示在界面中,一般情况下,接受一个string类型。
"app">
 "message">
 {{message}}
v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
"app">
 {{message}}
v-cloak斗篷的意思。
"app">
 hello{{name}}
v-bind的介绍
v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值。
绑定class有两种方式:
- 对象语法 
- 数组语法 
对象语法:
用法一:直接通过{}绑定一个类
"{'active': isActive}">hello
用法二,传入多个值
"{'active': isActive, 'line': isLine}">hello
用法三:
"title" :class="{'active': isActive}">
用法四:
可以放在一个methods或者computed中
"title" :class="classes">hello
v-bind动态绑定class,数组语法
"app">
 "title" :class="[active, line]">{{mesg}}
 "title" :class="getClasses()">{{mesg}}
v-bind动态绑定style
对象语法和数组语法两种绑定。
绑定方法:对象语法:
:style="{ color: currentColor, fontSize: fontSize + 'px' }"
style后面跟的是一个对象类型,对象的key是css属性名称,对象的value是具体赋的值,值可以来自于data中的属性。
绑定方法:数组语法:
"[baseStyles, overStyles]">
style后面跟的是一个数组的类型,多个值,分割即可。
计算属性的基本属性
计算属性,写在实例的computed选项中:
"app">
 {{firstName}}{{lastName}}
"app">
 {{fullName}}
计算属性的缓存:
为什么使用计算属性这个东西?
原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次。
setter和getter
每个计算属性都包含一个getter和一个setter
"app">
 {{fullName}}
 {{firstName}}
 {{lastName}}
computed: {
    fullName: function() {
        return this.firstName+" "+this.lastName
    }
    
    // 计算属性一般是没有set方法,只读属性。
    fullName: {
        get: function() {
            return this.firstName + " " + this.lastName
        }
    }
}
const的使用
const的使用,在JavaScript中使用const修饰的标识符为常量,不可以再次赋值。
在es6开发中,优先使用const,只有需要改变一个标识符的时候才使用let。
在使用cost定义标识符,必须进行赋值。
常量的含义是指向的对象不能修改,但是可以改变对象内部的属性。
什么时候使用const呢?
当我们修饰的标识符不会被再次赋值时,就可以使用const来保证数据的安全性。
const的使用:
const a=20;
a = 10; // 错误:不可以修改
const name; // 错误,const修饰的标识符必须赋值
let和var
块级作用域:
JS中使用var来声明一个变量,变量的作用域主要是和函数的定义有关。
对于其他块定义来说是没有作用域的,比如if/for等,开发中往往会引发一些问题。
// 监听按钮的点击
var btns = document.getElementsByTagName('button');
for(var i=0; i    (function(i){
        btns[i].onclick = function(){
            alert('点击了'+i+"个")
        }
    })(i)
}
 let btns = document.getElementsByTagName('button');
for(let i=0;i    btns[i].onclick = function(){
        alert('点击了'+i+'个')
    }
}
 块级作用域
变量作用域:变量在什么范围内是可用的。
var func;
if(true) {
    var name = 'web';
    func = function() {
        console.log(name); // web
    }
    
    func(); // web
}
// name = 'it'
func(); // web -> it
console.log(name); // web -> it
没有块级作用域引起的问题,for的块级
var btns = document.getElementsByTagName('button');
for(var i=0; i    btns[i].addEventListener('click', function(){
        console.log('第'+i+'个按钮被点击');
    })
}
 闭包:
var btns = document.getElementsByTagName('button');
for(var i=0; i    (function(i){
        btns[i].addEventListener('click', function(){
          console.log('第'+i+'个按钮');  
        })
    })(i)
}
 为什么闭包可以解决问题,因为函数是一个作用域。
对象的增强写法
属性初始化简写和方法的简写:
// 属性的简写
// es6前
let name = 'web'
let age = 12
let obj1 = {
    name: name,
    age: age,
}
console.log(obj1);
// es6后
let obj2 = {
    name, age
}
console.log(obj2)
// 方法的简写
// es6之前
let obj1 = {
    test: function() {
        console.log('obj1')
    }
}
obj1.test();
// es6后
let obj2 = {
    test() {
        console.log('obj2')
    }
}
obj2.test();
v-on基础
v-on:click="counter++"
"app">
 点击次数:{{counter}}
 
 
let app = new Vue({
 el: '#app',
 data: {
     counter: 0
 },
 methods: {
     btnClick(){
         this.counter++
     }
 }
})
v-on修饰符的使用
"app">
 "divClick">
 web
 
Vue提供了一些修饰符:
.stop 调用event.stopPropagation()
.prevent 调用event.preventDefault()
.native 监听组件根元素的原生事件
.once 只触发一次回调
// 停止冒泡
// 阻止默认行为
// 阻止默认行为,没有表达式
// 串联修饰符
// 键修饰符,键别名
"onEnter">
// 键修饰符,键代码
"onEnter">
// 点击回调智慧触发一次
v-if,v-else-if,v-else
简单使用:
"app">
 "score>=90">优秀
 "score>=80">良好
 "score>=60">及格
 "score<60">不及格
登录切换:
"app">
 "type==='username'">
  
  "用户账户">
 
 
  
  "邮箱地址">
 
 
"app">
 "isUser">
  
  type="text" id="username" placeholder="用户账户">
 
 
 
  ="email">用户邮箱
  type="text" id="email" placeholder="用户邮箱">
 
 
v-for遍历对象
"app">
 
  - "(value, key, index) in info">
 {{value}}-{{key}}-{{index}}
 
 
组件的Key属性
使用v-for时,给对应的元素或组件添加上一个:key属性。
key的作用主要是为了高效的更新虚拟dom。
数组中哪些方法是响应式的
push()
pop() 删除数组中的最后一个元素
shift() 删除数组中的第一个元素
unshift() 在数组最前面添加元素
splice()
sort()
reverse()
购物车
"app">
书籍名称 
出版日期 
价格 
购买数量 
操作 
"item in books">
"value in item">{{value}} 
 
表单绑定v-model
vue中使用v-model指令来实现表单元素和数据的双向绑定。
"app">
 type="text" v-model="message">
 {{message}}
reduce作用对数组中所有的内容进行汇总。

JavaScript reduce() 方法
var numbers = [65, 44, 12, 4];
 
function getSum(total, num) {
    return total + num;
}
function myFunction(item) {
    document.getElementById("demo").innerHTML = numbers.reduce(getSum);
}
定义和用法
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 可以作为一个高阶函数,用于函数的 compose。
注意: reduce() 对于空数组是不会执行回调函数的。
语法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
v-model的使用以及原理
type="text" :value="message" @input="message = $event.target.value">
v-model是语法糖,本质:
- v-bind绑定一个- value属性
- v-on指令给当前元素绑定- input事件
代码:
type="text" v-model="message">
type="text" v-bind:value="message" v-on:input="message = $event.target.value">


v-model:checkbox

复选框分为两种情况,单个勾选框和多个勾选框。
单个勾选框:
v-model即为布尔值。input的value并不影响v-model的值。
多个复选框:
当是多个复选框时,对应的data中属性是一个数组。
当选中某一个时,就会将input的value添加到数组中。
"app">
 
 
 
v-model:select
select分单选和多选两种情况
单选:只能选中一个值,多选:可以选择多个值。


v-model结合select类型
和checkbox一样,select分单选和多选两种情况。
单选,只能选择一个值,v-model绑定的是一个值。当我们选中option中的一个时,会将它对应的value赋值到mySelect中。
多选,可以选中多个值。v-model绑定的是一个数组。当选中多个值时,就会将选中的option对应的value添加到数组mySelects中。
// 选择一个值
您最喜欢的{{mySelect}}
// 选择多个值
您最喜欢的{{mySelects}}
input中的值绑定
修饰符
lazy修饰符:
- 默认情况下,- v-model默认是在- input事件中同步输入框的数据的。
 
- 一旦有数据发生改变对应的- data中的数据就会自动发生改变。
 
- lazy修饰符可以让数据在失去焦点或者回车时才会更新。
number修饰符:
- 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。 
- 但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。 
- number修饰符可以让在输入框中输入的内容自动转成数字类型。
trim修饰符:
- 如果输入的内容首尾有很多空格,通常我们希望将其去除 
- trim修饰符可以过滤内容左右两边的空格
示例:
"app">
 type="text" v-model.lazy="message">
 {{message}}
什么是组件化
- 组件化是vue.js中的重要思想 
- 它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用 
- 任何的应用都会被抽象成一颗组件树 

注册组件的基本步骤:
- 创建组件构造器 
- 注册组件 
- 使用组件 
示例:
调用Vue.extend()方法创建组件构造器
调用Vue.component()方法,注册组件
在Vue实例的作用范围内使用组件
组件示例:
"app">
全局组件和局部组件
- Vue.extend()调用- Vue.extend()创建一个组件构造器。
- 通常在创建组件构造器时,传入- template代表我们自定义组件的模板。
 
- 该模板在使用到组件的地方,显示的- html代码。
 
- 这种写法在- Vue2.x的文档几乎看不到了。
 
- Vue.component()是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。
- 注册组件的标签名,组件构造器。 
示例:
组件标题
"app">
 
 
  
 
示例:
"app1">
 
"app2">
 
父组件和子组件
组件树
- 组件和组件之间存在层级关系 
- 其中一种非常重要的关系就是父子组件的关系 
示例:
"app">
 
"app">
 
// 注册局部组件的语法糖
const app = new Vue({
 el: '#app',
 data: {
     message: 'web'
 },
 components: {
     'cpn2': {
         template: `
         
          web
         
         `
     }
 }
})
vue简化了注册组件的方式,提供了注册的语法糖。
组件模板抽离的写法
vue提供了两种定义html模块内容:
- 使用
 
 
 
 
- template标签
 - "cpn">
 
 - web
 
 
 // 注册一个全局组件
 Vue.component('cpn', {
 template: '#cpn'
 })
 
 - 组件可以访问vue实例数据吗 
 - 组件是一个单独的功能模块封装,有属于自己的- html模板和自己的数据- data。
 - 组件对象有一个- data属性,- methods属性,这个- data属性必须是一个函数,函数返回一个对象,对象内部保存着数据。
 - "app">
 
 
 
 "myCpn">
 {{message}}
 
 
 
 
 - 在 - Vue中,父子组件的关系
 - props向下传递,事件向上传递。
 - 父组件通过 - props给子组件下发数据,子组件通过事件给父组件发送消息。
  
- props支持的数据类型:
 - String
 
 Number
 
 Boolean
 
 Array
 
 Object
 
 Date
 
 Function
 
 Symbol
 
  
- 示例: - Vue.component('my-component',{
 props: {
 // 基础的类型检查
 propA: Number,
 // 多个可能的类型
 propB: [String, Number],
 // propC: {
 type: String,
 required: true
 },
 // 带有默认值的数字
 propD: {
 type: Number,
 default: 100
 },
 // 带有默认值的对象
 propE: {
 type: Object,
 default: function(){
 return {message: 'web'}
 }
 },
 // 自定义验证函数
 propF: {
 vfunc: function(value) {
 return value > 1
 }
 }
 }
 })
 
 - 子传父 
 - 代码: - this.$emit('item-click',item)
 
 - props用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中。
 - 自定义事件: - 在子组件中,通过- $emit()来触发事件。
 
- 在父组件中,通过- v-on来监听子组件事件。
 
 - 自定义事件代码: - "app">
 - "changeTotal" @decrement="changeTotal"> 
 - 点击次数
 
 
 "childCpn">
 
 
 
 
 
 
 let app = new Vue({
 el: '#app',
 data: {
 total: 0
 },
 methods: {
 changeTotal(counter) {
 this.total = counter
 }
 },
 components: {
 'child-cpn': {
 template: '#childCpn',
 data(){
 return{
 counter: 0
 }
 },
 methods: {
 increment(){
 this.counter++;
 this.$emit('increment', this.counter)
 },
 decrement(){
 this.counter--;
 this.$emit('decrement',this.counter)
 }
 }
 }
 }
 })
 
 - 父子组件的访问方式:- $children
- 有时候需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问父组件。 - 父组件访问子组件,使用- $children或者- $refs
 
- 子组件访问父组件,使用- $parent
 
 - 对于- $children的访问:
 - this.$children是一个数组类型,它包含所有子组件对象。
- 通过遍历,取出所有子组件的- message状态。
 
 - 示例: - "app">
 
 
 
 // 父组件template
 "parentCpn">
 
 
 
 
 
 
 
 // 子组件
 "childCpn1">
 - 我是子组件1
 
 // 子组件
 "childCpn2">
 - 我是子组件2
 
 
 Vue.component('parent-cpn',{
 template: '#parentCpn',
 methods: {
 showChildCpn(){
 for(let i=0; i- $children.length; i++){
 console.log(this.$children[i].message)
 }
 }
 }
 })
 
 
 - 父子组件的访问方式:- $parent
- 子组件中直接访问父组件,可以通过- $parent
 - 虽然可以通过- $parent来访问父组件,但是尽量不要这样做
 
- 子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了。 
 - 父子组件的访问方式- $refs
 
 - $children的缺陷:
 - 通过- $children访问子组件,是一个数组类型,访问其子组件要通过索引值。
 
- 子组件过多时,需要拿其中一个时,不能确定它的索引值,还可能发生变化。 
- 获取其中一个特定的组件,可以使用- $refs
 
 - $refs的使用:
 - $refs和- ref指令通常一起使用
- 通过- ref给某个子组件绑定一个特定的- id
 
- 通过- this.$refs.id可以访问到该组件
 
 - 示例: - "child1"> 
 - "child2"> 
 
 
 show() {
 console.log(this.$refs.child1.message);
 console.log(this.$refs.child2.message);
 }
 
 - 看看一个- .vue文件项目
 
 
 "xxx">
 "xxx"
 :class="{active: currentIndex === index}"
 @click="itemClick(index)"
 v-for="(item,index) in titles">
 {{item}}
 
 
 
 
 
 
 
 
 - 三层部分:  
- slot插槽的使用- vue中的代码- slot是什么呢,它叫插槽,
 - v-slot用法:
 - 默认插槽 
- 具名插槽 
- 作用域插槽 
- slot以及- slot-scope的用法:子组件编写,父组件编写
 - 默认插槽 - 子组件: - // 子组件
 
 "content">
 // 默认插槽
 - "text">
 - 默认值 
 
 
 
 
 
 - slot基本使用
 - 在子组件中,使用 
- 该插槽插入什么内容取决于父组件如何使用。 
 - 子组件定义一个插槽: 
 - 示例: - "app">
 
 
 - web 
 
 
 
 "myCpn">
 
 - 我是谁 
 
 
 
 
  
- 使用具名插槽 - 给- slot元素添加一个- name属性
 
 - 示例: - "app">
 // 没有任何内容
 
 
 // 传入某个内容
 
 "left">left
 
 
 
 "left">left
 
 "center">center
 
 "right">right
 
 
 "myCpn">
 
 - "left">1 
 - "center">2 
 - "right">3 
 
 
 
 
 - 编译作用域 
 - Vue实例属性:
 - 父组件模板的所有东西都会在父级作用域内编译,子组件模板的所有东西都会在子级作用域内编译。 - 父组件替换插槽的标签,但是内容由子组件来提供。 - 模块化开发- 什么是模块化,将一组模块以正确的顺序拼接到一个文件中的过程,模块是实现特定功能的一组属性和方法的封装。 - 利用构造函数封装对象 - function web() {
 var arr = [];
 this.add = function(val) {
 arr.push(var)
 }
 this.toString = function() {
 return arr.join('')
 }
 }
 var a = new web();
 a.add(1); // [1]
 a.toString(); // "1"
 a.arr // undefined
 
 - 示例: - var ModuleA = (function(){
 // 定义一个对象
 var obj = {}
 // 在对象内部添加变量和方法
 obj.flag = true
 obj.myFunc = function(info) {
 console.log(info)
 };
 // 将对象返回
 return obj
 }
 
 - if(ModuleA.flag) {
 console.log('web')
 }
 
 ModuleA.myFunc('webweb')
 
 - 常见的模块化规范: - CommonJS,- AMD,- CMD,- ES6中的- Modules
 - 什么是- AMD,异步模块定义,它是在浏览器端实现模块化开发的规范,但是该规范不是原生- js支持的,使用- AMD规范进行开发的时候需要引入第三方的库函数,就是- RequireJS。
 - RequireJS解决了多个- js文件可能有依赖的关系,被依赖的文件需要早于依赖它的文件加载到浏览器;- js加载的时候浏览器会停止页面渲染,加载文件越多,页面就会失去响应时间越长。
 - CMD是什么,它是通用模块定义,解决的问题和- AMD一样,不过在模块定义方式和模块加载时机上不同,- CMD需要额外的引入第三方的库文件- SeaJS。
 - JavaScript模块化编程 
 - 可以解决项目中的全局变量污染问题 
- 开发效率高,利于多人协同开发 
- 职责单一,方便代码复用和维护 
- 解决了文件的依赖问题 
 - 那么什么是模块化呢 
 - 将一个项目按照功能划分,理论上一个功能一个模块,互不影响,在需要的时候载入,尽量遵循高内聚低耦合。  
- 了解- CommonJS
 - CommonJS 是一种思想,本质上是可复用的JavaScript,它导出特定的对象,提供其它程序使用。 - 使用- module.exports和- exports.obj来导出对象,并在需要它的程序中使用- require('module')加载。
 - 模块化的核心就是:导入和导出 - 导出:- CommonJS
 - module.exports = {
 flag: true,
 test(a,b) {
 return a+b
 },
 demo(a,b) {
 return a*b
 }
 }
 
 - 导入:- CommonJS
 - // CommonJS模块
 let {test, demo, flag} = require('moduleA');
 
 // =>
 let ma = require('moduleA');
 let test = ma.test;
 let demo = ma.demo;
 let flag = ma.flag;
 
 - 因为网站开发越来越复杂,js文件又很多,就会出现一些问题: - 变量名冲突 
- 文件依赖复杂度高 
- 页面加载过多,不利于维护 
 - CommonJS,定义模块,一个单独的- js文件就是一个模块,每个模块都有自己单独的作用域,在该模块内部定义的变量,无法被其他模块读取,除了定义为- global对象的属性。
 - 模块的导出:- exports和- module.exports
 - 模块的导入:- require
 - 在- node中,每个模块内部都有要给自己的- module对象
 
- 在- module对象中,有一个成员- exports也是一个对象
 
- 通过- exports对象导出当前方法或变量,也可通过- module.exports导出
 
- node简化了操作,- exports等于- module.exports,相当于- var exports = module.exports
 - es模块的导入和导出 
 - export function add(num1, num2) {
 return num1 + num2
 }
 
 - export function accString(param) {
 if (param == 0) {
 return '关'
 }else if(param == 1) {
 return '开'
 }
 }
 
 import {
 accString
 } from '../../utils'
 
 - const name = 'web'
 
 export default name
 
 - export default
 - 一个模块中包含某个功能,如果不希望给功能命名,可以让导入者自己来定: - export default function(){
 console.log('web')
 }
 
 - 使用: - import myFunc from '../web.js'
 
 myFunc()
 
 - export default在同一个模块中,不允许同时存在多个
 
 - import使用
 - export指令导出了模块对外提供的接口
 - import指令用于导入模块中的内容
 - import {name, age} from './web.js'
 
 - 通过- *可以导入模块中所有所有的- export变量
 - import * as web from './web.js'
 
 console.log(web.name);
 
 - 最后- 我是程序员哆啦A梦,蓝胖子,简书万粉优秀创作者,掘金优秀作者、CSDN博客专家,云+社区社区活跃作者,致力于打造一系列能够帮助程序员提高的优质文章。网站@http://www.dadaqianduan.cn 
 - 扫码关注公众号,订阅更多精彩内容。 
 
 
 
  
 
- 你点的每个赞,我都认真当成了喜欢 
