vue入门到实战

2022年05月10日 阅读数:12
这篇文章主要向大家介绍vue入门到实战,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

Vue是目前最火的前端框架,与Angular、React并称为前端三大框架。是一个轻量级的MVVM框架,经过数据驱动和组件化进行前端开发,经过简单地API就能实现响应式的数据绑定和组合的视图组件。php

  1. Vue是目前很是火的一个前端框架,是前端程序员必备的一个技能。
  2. Vue发展迅速,在大多数后端程序员中,也须要会Vue。
  3. Vue简单易学,而且性能高效,能够很大程度上提升代码开发效率。

1、准备工做

1.vscode的下载与安装教程:https://blog.csdn.net/weixin_44195615/article/details/113856706

另附:VSCode-win32-x64-1.53.2的下载百度网盘连接css

连接:https://pan.baidu.com/s/1aHQVIWfOlmgCX89PLI2e6A 
提取码:dr1j 

2.推荐使用火狐浏览器,并安装插件Vue.js devtools
(1)搜索:vue
在这里插入图片描述
点击Vue.js devtools
在这里插入图片描述
点击安装
在这里插入图片描述
3.在vscode安装Open in Browser插件
(1)点击拓展,输入Open in Browser,而后点击安装html

在这里插入图片描述

2、快速上手

2.1 HelloVue

2.1.1编写项目
(1)新建文件HelloVue.html,而后按!选择第一个选项前端

在这里插入图片描述
在这里插入图片描述
(2)引入js文件vue

<script src="./lib/vue-2.4.0.js"></script>

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
  <div id="app">
    <h2>Hello {
  
  {name}}</h2>
  </div>
</body>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      name: 'Vue'
    }
  })
</script>
</html>

知识讲解:java

  1. 建立了一个Vue对象,此时在浏览器的内存中就有了一个Vue。
  2. 建立Vue的时候,传入了一个参数,这个参数是一个对象options
  3. 参数中有el属性。该属性决定了这个Vue对象挂载到哪个元素上。
  4. 参数中有data属性,该属性定义存储大部分的数据。这些数据能够本身直接定义,也能够从网络中获取。

2.1.2运行:右键1.HelloVue.html,选择Open with default application
注意:是在安装插件Vue.js devtools的浏览器打开
在这里插入图片描述
2.1.3.运行结果
在这里插入图片描述python

2.2 列表案例

2.2.1编写代码
在这里插入图片描述mysql

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
  <div id="booksId">
    <ul>
      <li v-for="content in books">{
  
  {content}}</li>
    </ul>
  </div>
</body>
<script>
  let app = new Vue({
    el: '#booksId',
    data: {
      books: ['Vue从入门到精通', 'java', 'html从入门到精通','mysql从入门到精通']
    }
  })
</script>
</html>

知识讲解:
(1)将一个列表展现到HTML代码中,应该使用v-for指令。
(2)传统的操做方式是使用JavaScript/JQuery获取到ul的dom,而后构造li的dom,拼接到ul中进行渲染。而Vue中则只须要在data中定义这个数组,咱们就可使用v-for指令在页面中循环输出。更重要的是,它是响应式的ios

2.2.2 运行及结果程序员

在这里插入图片描述
在这里插入图片描述

2.3 计数器案例

2.3.1 新建文件
在这里插入图片描述
而后按!选择第一个选项

在这里插入图片描述
在这里插入图片描述

2.3.2 引入vue-2.4.0.js文件

 <script src="./lib/vue-2.4.0.js"></script>

2.3.3 编写代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计数器案例</title>
    <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
    <div id="countId">
        <h2>当前计数是:{
  
  {count}}</h2>
        <button @click="addCount">加</button>
        <button @click="delCount">减</button>
   
    </div>
</body>
<script>
    let app = new Vue({
        el: '#countId',
        data: {
            count: 0
        },
        methods:{
            addCount(){
                this.count++
            },
            delCount(){
                this.count--
            }
        }
    })
</script>
</html>

知识讲解:
使用到了@click,这是vue中监听点击事件的方式,而@click须要指定发生点击时所执行的方法,该方法是在methods中定义的。
Methods是vue实例中options的一个属性,和data平级,该属性用于定义Vue对象中的方法。

2.3.4 运行及运行结果
在这里插入图片描述
在这里插入图片描述

项目代码百度网盘连接:

连接:https://pan.baidu.com/s/1N-F-hTbzQtiqvt9eXk7UoA 
提取码:pt3y 

3、前端框架的发展历程

3.1 什么是框架

框架:半成品的项目,提升开发效率。

3.2 前端框架发展

DOM:原生JS->ExtJS、JQuery->easyui、layui等等(简化DOM操做,可是下降了ajax请求的复用性)
MVVM:Angular、Vue、React。可以帮助咱们减小没必要要的DOM操做,提升渲染效率。数据绑定(单向、双向),经过框架提供的一些指令,咱们只须要关注数据的业务逻辑,不须要关注DOM是如何渲染的。在vue中,一个最核心的思想就是不让用户去操做DOM元素。

3.3 MVVM

Model:对应数据层的域模型,它主要作数据的管理,经过ajax/fetch/axios等api完成客户端和服务端的Model同步,在层间关系里,它主要用于抽象出ViewModel中的Model。
View:View是做为视图模板,用于定义结构、布局。它本身不处理数据,只是将ViewModel中的数据展示出来。
ViewModel:ViewModel起着连接View和Model的做用,同时用于处理View中的逻辑。ViewModel从Model中取数据,渲染到View中。
在这里插入图片描述

4、基础语法

4.1插值操做

4.1.1 插值运算符
语法:{ {数据}}
插值运算符能够对数据进行显示,也能够在插值运算符中进行表达式计算。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>插值操做</title>
    <script src="./lib/vue-2.4.0.js"></script>
    <style>
        [v-clock]{
            display: none;
        }
    </style>
</head>
<body>
    <div id="dataId">
        <h1>{
  
  {name}}</h1>
        <h1>{
  
  {firstName}}{
  
  {lastName}}</h1>
        <h1>{
  
  {count*5}}</h1>
        <h2 v-once>{
  
  {firstName}}{
  
  {lastName}}</h2>
        <h2 v-html="htmlData">hello</h2>
        <h1 v-text="name"></h1>
        <h2 v-clock>{
  
  {firstName}}{
  
  {lastName}}</h2>
        
    </div>
</body>
<script>
    let app = new Vue({
        el:'#dataId',
        data:{
            name:'vue',
            firstName:'张',
            lastName:'三',
            count:20,
            htmlData:'<p style="color: red;">html代码</P>'
        }
    })
</script>
</html>

在这里插入图片描述
分析:
(1)v-once
该指令后面不须要跟任何的表达式,该指令表示元素和组件之间只会渲染一次,不会随着数据的改变而改变。

<h2 v-once>{
  
  {firstName}}{
  
  {lastName}}</h2>

(2)v-html
在某些状况下,从服务端请求到的数据自己是一个HTML代码。
若直接使用{ {}}输出,会将HTML代码一块儿输出。
使用html格式进行输出,可以使用v-html指令。

<h2 v-html="htmlData">hello</h2>

(3)v-text

v-text做用和插值运算符比较相似,都是用于将数据显示在页面中。一般状况下,v-text接受一个string类型。v-text会替换标签内的内容。

<h1 v-text="name"></h1>

(4)v-clock
在某些状况下,浏览器可能会直接显示出未编译的插值运算符。

   <style>
        [v-clock]{
            display: none;
        }
    </style>
<h2 v-clock>{
  
  {firstName}}{
  
  {lastName}}</h2>

在这里插入图片描述
(5)过滤器
Filters属性与data和methods平级,用于定义过滤器。过滤器本质上是一个方法,接收一个参数。在页面中,使用插值运算符,语法:{ {数据 | 过滤器名称}},不须要写参数,不须要写括号,过滤器默认会把前面的数据做为参数传递给方法。
过滤器的方法须要返回一个数据,返回的数据做为最终结果渲染到页面中。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>过滤器</title>
    <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
    <div id="appId">
        <h1>{
  
  {count1|filterEven}}</h1>
        <h1>{
  
  {count2|filterEven}}</h1>
    </div>
    
</body>
<script>
    let app = new Vue({
        el:'#appId',
        data:{
            count1:10,
            count2:11
        },
        filters:{
            filterEven(num){
                if(num%2 == 0){
                    return num;
                }else{
                    return '非法数字';
                }
            }
       }
    })
</script>
</html>

4.2 属性绑定

4.2.1 v-bind 绑定a标签

前面咱们学习的指令主要做用是将数据插入到咱们模板的内容中,可是 除了内容须要动态决定之外,某些属性咱们也但愿动态来绑定,好比a标签的href、img标签的src等。这时候咱们可使用v-bind指令。
v-bind指令用于绑定一个值或者多个值
v-bind有简写方式,直接使用冒号:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>属性绑定</title>
    <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
    <div id="dataId">
        <a v-bind:href="baidu">百度</a>
    </div>
</body>
<script>
    let app = new Vue({
        el:'#dataId',
        data:{
            baidu:'https://www.baidu.com/'
        }
    })
</script>
</html>

在这里插入图片描述

在这里插入图片描述

4.2.2 v-bind 绑定class

v-bind绑定class,能够接受一个对象,也能够接受一个数组。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>v-bind绑定class</title>
  <script src="/lib/vue-2.4.0.js"></script>
  <style>
    .active {
      color: red;
    }
    .size {
      font-size: 30px;
    }

    .h2-border {
      border: 1px solid red;
    }
  </style>
</head>
<body>
  <div id="app">
    <!-- 方式1:直接经过{}绑定一个类 -->
    <h2 v-bind:class="{'active':isActive}">Hello Vue</h2>
    <!-- 方式2:这种方式能够经过判断,传入多个值 -->
    <h2 v-bind:class="{'active':isActive, 'size': big}">Hello Vue</h2>
    <!-- 方式3:和普通类同时存在,并不冲突 -->
    <h2 class="h2-border" v-bind:class="{'active':isActive, 'size': big}">Hello Vue</h2>
    <!-- 方式4:若是过于复杂,能够放到一个data中 -->
    <h2 class="h2-border" v-bind:class="classes">Hello Vue</h2>
  </div>
</body>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      isActive: true,
      big: true,
      classes: ['active', 'size']
    }
  })
</script>
</html>

在这里插入图片描述

4.2.3 v-bind绑定style

经过:style的方式动态的绑定一些css的内联样式。在写CSS属性名的时候,好比font-size,咱们在v-bind须要转换为驼峰规则来编写,或者使用横线分隔,使用横线的状况下,须要加上引号。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>v-bind绑定style</title>
  <script src="/lib/vue-2.4.0.js"></script>
</head>
<body>
  <div id="app">
    <!-- 方式1:直接绑定对象 -->
    <h2 :style="{color: 'red', fontSize: '15px'}">Hello Vue</h2>
  </div>
</body>
<script>
  let app = new Vue({
    el: '#app',
    data: {
    }
  })
</script>
</html>

在这里插入图片描述

4.2.4 v-model

Vue中使用v-model来实现表单元素和数据的双向绑定。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>v-model</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
  <div id="app">
    <input type="text" name="name" v-model="name">
    <h2>{
  
  {name}}</h2>
    <textarea v-model="name"></textarea>
  </div>
</body>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      name: '张三'
    }
  })
</script>
</html>

在这里插入图片描述

当咱们输入表单中的数据时,data中也会随之改变,data被改变后,插值运算符中的显示内容也会随之改变。

4.2.5 v-model绑定select

选中option的时,会将它对应的value赋值给mySelect。当mySelect的值改变时,option会自动选中对应value的那一项

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>v-model绑定select</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>
<body>
  <div id="app">
    <select v-model="mySelect">
      <option value="java">Java从入门到精通</option>
      <option value="python">python从入门到精通</option>
      <option value="php">php从入门到精通</option>
      <option value="mysql">mysql从删库到跑路</option>
    </select>
  </div>
</body>
<script>
  let app = new Vue({
    el: '#app',
    data: {
      mySelect: 'php'
    }
  })
</script>
</html>

在这里插入图片描述

4.3 监听器

监听器的属性名称是watch,和data平级。监听器中的数据是方法,接收两个参数,分别为改变后的值和改变前的值。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>监听器</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <input type="text" v-model="user.firstName">
    <input type="text" v-model="user.lastName">
    <h2>{
   
   {
   
   user.fullName}}</h2>
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      user: {
   
   
        firstName: '张',
        lastName: '三',
        fullName: ''
      }
    },
    watch: {
   
   
      'user.firstName': function (newVal, oldVal) {
   
   
        this.user.fullName = this.user.firstName + this.user.lastName
      }
    }
  })
</script>

</html>

运行及运行结果
在这里插入图片描述
在这里插入图片描述

4.4 计算属性

某些状况,可能须要对数据进行一些转换后再现实,或者须要将多个数据结合起来进行现实。
(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>计算属性</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <h2>{
   
   {
   
   fullName}}</h2>
    <h2>{
   
   {
   
   fullName}}</h2>
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      firstName: '张',
      lastName: '三'
    },
    computed: {
   
   
      fullName() {
   
   
        console.log('进入了计算属性')
        // 写法是个方法,可是使用的时候是做为属性使用的,和data一致。
        return this.firstName + this.lastName
      }
    }
  })
</script>

</html>

(2)运行
在这里插入图片描述
(3)运行结果
在这里插入图片描述
分析:
计算属性是一个属性,而不是方法。虽然写法是方法,可是使用时是直接视为一个属性去操做的,使用方式和data一致。
计算属性中使用到的data中的数据只要发生了变化,计算属性就会从新计算。若是两次获取计算属性的时候,里面使用到的属性没有发生变化,计算属性会直接使用以前缓存的值。

4.4.2 计算属性的getter和setter

每个计算属性都包含get方法和set方法。在上面的例子中,只是使用get去读取计算属性的值,在某些状况下,可能会须要人工改变计算属性的数据,这时就须要使用setter方法。
计算属性若是须要定义set和get方法,这时候计算属性就使用对象进行编写。
(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>计算属性的get和set</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <input type="text" v-model="firstName">
    <input type="text" v-model="lastName">
    <input type="text" v-model="fullName">
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      firstName: '张',
      lastName: '三'
    },
    computed: {
   
   
      fullName: {
   
   
        get() {
   
   
          console.log('调用了get方法')
          return this.firstName+' '+this.lastName
        },
        set(val) {
   
   
          console.log('调用了set方法')
          const names = val.split(' ')
          this.firstName = names[0]
          this.lastName = names[1]
        }
      }
    }
  })
</script>

</html>

(2)运行
在这里插入图片描述
(3)运行结果
在这里插入图片描述
分析
计算属性。在computed中,能够定义一些属性,这些属性叫作计算属性,他本质上就是一个方法,可是,咱们使用的时候是当作属性来使用。计算属性使用的过程当中,必定不要加(),它就是一个属性,和data里的属性用法同样。
只要极速暗属性中所用到的data中的属性发生了变化,就会当即去从新计算属性的值。
计算属性的结果会被缓存起来,方便下次调用,若是计算属性中用到的data都没有变化,就不会从新求值。
在计算属性中,不管如何都须要return一个值,用来表明这个属性的值。

计算属性和监听器的区别:
Computed用法视为一个属性,而且结果会被缓存。
Methods表示方法,表示一个具体的操做,主要用来写业务逻辑
Watch是一个对象,key是须要监听的表达式,value是对应的回调函数,主要用来监听某些数据的变化,从而执行某些具体的业务逻辑。能够看作是计算属性和methods的结合体。

4.5 事件监听

4.5.1 v-on

v-on也有简写方式,直接写成@
(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>按钮</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <h2>{
   
   {
   
   count}}</h2>
    <input type="text" v-on:focus="alertMsg">
    <button v-on:click="addCount">点我</button>
    <!-- v-on的简写方式 -->
    <!-- <button @click="addCount">点我</button> -->
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      count: 0
    },
    methods: {
   
   
      addCount() {
   
   
        this.count++
      },
      alertMsg() {
   
   
        alert('获取了焦点')
      }
    }
  })
</script>

</html>

(2)运行
在这里插入图片描述
(3)运行结果
在这里插入图片描述

分析:
当经过methods定义方法,以供@click调用时,须要注意参数问题
1.若是该方法不须要参数,那么方法后的括号不能够添加。由于存在某些框架,若是加了括号以后,可能在页面渲染完毕后当即加载一遍该方法。
2.若是须要传入某个参数,那么这个时候须要括号,而且须要在括号中传入参数。

4.6 条件判断

4.6.1 v-if

v-if、v-else-if、v-else。
这三个指令与JS中的条件判断if、else if、else相似。
v-if能够根据表达式中的值渲染或者销毁元素和组件。
(1)代码
(2)运行
在这里插入图片描述

(3)运行结果
在这里插入图片描述

4.6.2 v-show

v-show的用法与v-if相似,也是用于条件判断的。

(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>条件判断v-show</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <div v-show="score >= 90">优秀</div>
    <div v-show="score >= 75 && score < 90">良好</div>
    <div v-show="score >= 60 && score < 75">及格</div>
    <div v-show="score < 60">不及格</div>
    <button @click="delScore">减分</button>
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      score: 100
    },
    methods: {
   
   
      delScore() {
   
   
        this.score -= 10
      }
    }
  })
</script>

</html>

(2)运行

在这里插入图片描述
(3)运行结果
在这里插入图片描述

两者的区别:
v-if是彻底不建立DOM元素,而v-show则是建立了DOM元素,仅仅是使用display:none隐藏了该元素。
当须要频繁的显示、隐藏一些内容时,使用v-show。当咱们仅有一次切换,某些v-if场景根本不会显示出来的时候,用v-if。

4.7 循环遍历

4.7.1 遍历数组

当有一组数据须要进行渲染时,可以使用v-for完成。
v-for相似于JS中的for循环。
格式:item in items。后面的items表明着你须要遍历的数组,item则表示每一项的名称。

(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>v-for遍历数组</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <ul>
      <li v-for="(item, index) in dataList">{
   
   {
   
   index + ':' + item}}</li>
    </ul>
    <ul>
      <li v-for="(value, key, index) in myInfo">{
   
   {
   
   index}}:{
   
   {
   
   key}}:{
   
   {
   
   value}}</li>
    </ul>
    <ul>
      <li v-for="item in userList">{
   
   {
   
   item.id}}--{
   
   {
   
   item.name}}--{
   
   {
   
   item.age}}</li>
    </ul>
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      dataList: [
        'Java从入门到精通',
        'php从入门到精通',
        'mysql从删库到跑路',
        'Vue从单身到脱单'
      ],
      myInfo: {
   
   
        id: 3,
        name: '张三',
        age: 23,
        hobby: '唱跳rap篮球'
      },
      userList: [
        {
   
   id: 3, name: '张三', age: 23},
        {
   
   id: 4, name: '李四', age: 24},
        {
   
   id: 5, name: '王五', age: 25},
        {
   
   id: 6, name: '赵六', age: 26}
      ]
    }
  })
</script>

</html>

(2)运行
在这里插入图片描述

(3)运行结果
在这里插入图片描述

4.7.2 遍历对象

v-for能够遍历对象。好比某个对象中存储着的信息,但愿用列表的形式显示出来。
语法:v-for="(value, key, index) in myInfo"

(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>v-for遍历对象</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <input type="text" v-model="user.id" placeholder="请输入id">
    <input type="text" v-model="user.name" placeholder="请输入name">
    <input type="text" v-model="user.age" placeholder="请输入age">
    <button @click="addUser">添加</button>
    <div v-for="item in userList" :key="item.id">
      <input type="radio" name="user" :value="item.id"> {
   
   {
   
   item.name}}
    </div>
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      userList: [
        {
   
   id: 3, name: '张三', age: 23},
        {
   
   id: 4, name: '李四', age: 24},
        {
   
   id: 5, name: '王五', age: 25},
        {
   
   id: 6, name: '赵六', age: 26}
      ],
      user: {
   
   }
    },
    methods: {
   
   
      addUser() {
   
   
        this.userList.unshift(this.user)
      }
    }
  })
</script>

</html>

(2)运行
在这里插入图片描述

(3)运行结果
在这里插入图片描述
Vue官方建议,若使用v-for去遍历一个对象、数组的话,建议给对应的元素或者组件上加一个key属性,而且要保证key的惟一。

4.8 过渡动画

Vue提供了简单的过渡动画效果,只须要按照vue提供的标准去写一套固定的CSS便可。

(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <style>
    /* v-enter 这个是一个时间点,表示动画进入以前,元素的起始状态,此时尚未进入 */
    /* v-leave-to 这是一个时间点,是动画离开以后,元素的终止状态,此时,元素动画已经结束了 */
    .div1-enter,
    .div1-leave-to {
   
   
      opacity: 0;
      transform: translateX(50px);
    }
    
    /* v-enter-active 表示入场动画的时间段 */
    /* v-leave-active 表示离场动画的时间段 */
    .div1-enter-active,
    .div1-leave-active {
   
   
      transition: all 0.8s ease;
    }
    /* v-enter 这个是一个时间点,表示动画进入以前,元素的起始状态,此时尚未进入 */
    /* v-leave-to 这是一个时间点,是动画离开以后,元素的终止状态,此时,元素动画已经结束了 */
    .div2-enter,
    .div2-leave-to {
   
   
      opacity: 0;
      transform: translateX(50px);
    }
    
    /* v-enter-active 表示入场动画的时间段 */
    /* v-leave-active 表示离场动画的时间段 */
    .div2-enter-active,
    .div2-leave-active {
   
   
      transition: all 0.2s ease;
    }
  </style>
</head>

<body>
  <div id="app">
    <button @click="flag = !flag">点击</button>
    <transition name="div1">
      <div v-show="flag">这个是第一个div</div>
    </transition>
    <transition name="div2">
      <div v-show="!flag">这个是第二个div</div>
    </transition>
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      flag: true
    },
    methods: {
   
   
    }
  })
</script>

</html>

(2)运行
在这里插入图片描述

(3)运行结果
在这里插入图片描述

4.9 Vue生命周期

在这里插入图片描述
在这里插入图片描述
(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>vue生命周期</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <style>
  </style>
</head>

<body>
  <div id="app">
    <div id="myId">页面尚未被渲染 --- {
   
   {
   
   msg}}</div>
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      msg: '页面渲染完毕'
    },
    methods: {
   
   
    },
    beforeCreate() {
   
   
      console.log('beforeCreate')
      var div = document.getElementById('myId')
      // 页面没有被渲染,如插值运算符等属于vue实例的东西暂时都视为字符串
      console.log(div.innerHTML)
      // data尚未被挂载到vue,此时的vue只是一个空对象。
      console.log(this.msg)
    },
    created() {
   
   
      console.log('created')
      var div = document.getElementById('myId')
      // 页面没有被渲染,如插值运算符等属于vue实例的东西暂时都视为字符串
      console.log(div.innerHTML)
      // data成功被挂载到vue中,咱们能够在这里使用到data中的数据。
      console.log(this.msg)
    },
    beforeMount() {
   
   
      console.log('beforeMount')
      var div = document.getElementById('myId')
      // 页面没有被渲染,如插值运算符等属于vue实例的东西暂时都视为字符串
      console.log(div.innerHTML)
      // data成功被挂载到vue中,咱们能够在这里使用到data中的数据。
      console.log(this.msg)
    },
    mounted() {
   
   
      console.log('mounted')
      var div = document.getElementById('myId')
      // 页面从新渲染
      console.log(div.innerHTML)
      // data成功被挂载到vue中,咱们能够在这里使用到data中的数据。
      console.log(this.msg)
    }
  })
</script>

</html>

(2)运行
在这里插入图片描述

(3)运行结果
在这里插入图片描述

5、layui增删改查

(1)代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>layui增删改查</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <link rel="stylesheet" href="./lib/layui.css">
</head>

<body>
  <div id="app">
    <div class="layui-form-item">
      <div class="layui-input-inline" style="width: 100px;">
        <input type="text" v-model="user.id" placeholder="请输入编号" class="layui-input">
      </div>
      <div class="layui-input-inline" style="width: 100px;">
        <input type="text" v-model="user.name" placeholder="请输入姓名" class="layui-input">
      </div>
      <div class="layui-input-inline" style="width: 100px;">
        <input type="text" v-model="user.age" placeholder="请输入年龄" class="layui-input">
      </div>
      <div class="layui-input-inline" style="width: 100px;">
        <input type="text" v-model="user.gender" placeholder="请输入性别" class="layui-input">
      </div>
      <div class="layui-input-inline" style="width: 100px;">
        <input type="text" v-model="user.remark" placeholder="请输入备注" class="layui-input">
      </div>

      <div class="layui-input-inline" style="width: 100px;">
        <button type="button" class="layui-btn" @click="addUser">添加</button>
      </div>
      <div class="layui-input-inline" style="width: 100px;">
        <input type="text" v-model="searchName" placeholder="请输入姓名" class="layui-input">
      </div>

      <div class="layui-input-inline" style="width: 100px;">
        <button type="button" class="layui-btn" @click="searchUser">搜索</button>
      </div>

    </div>

    <table class="layui-table">
      <thead>
        <tr>
          <th>编号</th>
          <th>姓名</th>
          <th>年龄</th>
          <th>性别</th>
          <th>备注</th>
          <th>操做</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in userList" :key="item.id">
          <td>{
   
   {
   
   item.id}}</td>
          <td>{
   
   {
   
   item.name}}</td>
          <td>{
   
   {
   
   item.age}}</td>
          <td>{
   
   {
   
   item.gender | handlerGender}}</td>
          <td>{
   
   {
   
   item.remark}}</td>
          <td>
            <button type="button" class="layui-btn layui-btn-danger" @click="delUser(item.id)">删除</button>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</body>
<script>
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      userList: [ // 用户列表
      ],
      data: [ // 数据库,存放用户数据
        {
   
    id: 1, name: '张三', gender: 1, age: 23, remark: '姓张名三' },
        {
   
    id: 2, name: '李四', gender: 2, age: 24, remark: '姓李名四' },
        {
   
    id: 3, name: '王五', gender: 1, age: 25, remark: '姓王名五' },
        {
   
    id: 4, name: '赵六', gender: 2, age: 26, remark: '姓赵名六' },
        {
   
    id: 5, name: '张5qi', gender: 1, age: 18, remark: '低调的学霸' }
      ],
      user: {
   
   },
      searchName: '' // 搜索用的名称
    },
    filters: {
   
   
      handlerGender(gender) {
   
   
        if (gender == 1) {
   
   
          return '男'
        } else {
   
   
          return '女'
        }
      }
    },
    methods: {
   
   
      getUserList(name) {
   
    // 加载用户数据
        // 若是name为空,赋予默认值:空字符串
        if (!name) {
   
   
          name = ''
        }
        const dataList = this.data.filter(e => e.name.indexOf(name) >= 0)
        this.userList = dataList
      },
      addUser() {
   
   
        // 添加用户
        const user = {
   
    ...this.user }
        // 等价于
        // const user = {id: this.user.id, name: this.user.name.....}
        // 添加到数据库里
        this.data.push(user)
        // 从新加载数据
        this.getUserList()
      },
      delUser(id) {
   
   
        // 查到指定id所在数组索引下标
        const index = this.userList.findIndex(e => e.id === id)
        // 删除指定索引位置的数据
        this.data.splice(index, 1)
        // 删除成功后,从新家在数据
        this.getUserList()
      },
      searchUser() {
   
    // 搜索用户
        // 遍历用户,找到全部复合条件的用户
        this.getUserList(this.searchName)
      }
    },
    created() {
   
   
      // 进入页面,组件建立以后,获取数据
      this.getUserList()
    }
  })
</script>

</html>

(2)运行
在这里插入图片描述

(3)运行结果

在这里插入图片描述

6、组件化开发

6.1 什么是组件化

6.2 Vue组件化思想

组件化是Vue的一个重要概念,它提供了一种抽象,让咱们能够开发出一个个独立可复用的小组件来构建咱们的应用。
任何的应用都会被抽象成一颗组件树
在这里插入图片描述

6.3 注册组件

组件的使用分红三个步骤:建立组件构造器、注册组件、使用组件。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>注册组件</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <my-component></my-component>
    <my-component2></my-component2>
    <my-component3></my-component3>
    <my-component4></my-component4>
  </div>
</body>

<template id="temp">
  <div>
    <p>我是p标签</p>
    <h1>我是h1标签</h1>
    <div style="color: red;">哈哈哈</div>
  </div>
</template>

<script>
  var num = 10
  /**
   * 1 使用Vue.extend来注册 组件
   * 按照了Java的开发思想,变量名每每是驼峰规则。
   * 可是使用组件的时候通常不使用驼峰规则
   * 而是将驼峰规则所有改为小写,而后中间用-链接
   */
  Vue.component('myComponent', Vue.extend({
   
   
    // template就是组件要展现的内容,能够是html标签
    template: '<h3>用extend注册的组件</h3>'
  }))

  /**
   * 2.不使用extend去注册组件
   */
  Vue.component('myComponent2', {
   
   
    // template就是组件要展现的内容,能够是html标签
    template: '<div><h3>不用extend注册的组件</h3><h3>我是第二个h3</h3></div>'
  })
  // 不论使用哪种注册方式,template属性只能有一个,而且有且仅有一个根节点。

  Vue.component('myComponent3', {
   
   
    // template就是组件要展现的内容,能够是html标签
    template: `<div><h3>组件中使用外部变量num:${
   
   num}</h3></div>`
  })

  // 3.使用template
  Vue.component('myComponent4', {
   
   
    template: '#temp'
  })

  let app = new Vue({
   
   
    el: '#app'
  })
</script>

</html>

在这里插入图片描述

6.4 私有组件

上面使用Vue.component注册组件时,注册的是全局的组件。这意味着可再任意的Vue实例中,使用该组件。
若是想要注册一个局部的私有组件,能够将组件挂载到某个实例上。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>私有组件</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app1">
    <my-component></my-component>
    <my-comp></my-comp>
  </div>
  <div id="app2">
    <my-component></my-component>
  </div>
</body>

<script>
  /**
   * 注册的是全局组件
   */
  Vue.component('myComponent', Vue.extend({
   
   
    // template就是组件要展现的内容,能够是html标签
    template: '<h3>用extend注册的组件</h3>'
  }))

  let myComp = Vue.extend({
   
   
    // template就是组件要展现的内容,能够是html标签
    template: '<h3>私有组件</h3>'
  })


  let app = new Vue({
   
   
    el: '#app1',
    components: {
   
   
      myComp
    }
  })
  let app2 = new Vue({
   
   
    el: '#app2'
  })

</script>

</html>

在这里插入图片描述

6.5 父组件与子组件

组件和组件之间存在层级关系,这就是父组件与子组件。组件中也有components关键字,一样是使用components将子组件注册到父组件。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>父组件与子组件</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <parent-com></parent-com>
  </div>
</body>

<script>

  // 1.建立一个子组件
  let childCom = Vue.extend({
   
   
    template: `<div>子组件内容。</div>`
  })

  // 2.建立一个父组件
  let parentCom = Vue.extend({
   
   
    template:
     `<div>
        <h1>父组件内容</h1>
        <child-com></child-com>
      </div>
    `,
    components: {
   
   
      childCom
    }
  })

  let app = new Vue({
   
   
    el: '#app',
    components: {
   
   
      parentCom
    }
  })
</script>

</html>

在这里插入图片描述

6.6 组件的数据

组件是一个单独的功能模块的封装,这个模块有属于本身的HTML模板,也应该有属于本身的data。

6.6.1 组件的数据

组件也有个data属性、methods、filters等等等等,使用方式与Vue一致(data不同。)
Data必须是一个方法,返回一个对象。其余的与Vue实例使用方式同样。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>组件的数据</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <my-com></my-com>
  </div>
</body>

<script>
  let myCom = Vue.extend({
   
   
    template: `<div>组件{
   
   {
   
   msg}}</div>`,
    data() {
   
   
      return {
   
   
        msg: '子组件的msg'
      }
    }
  })
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      msg: '哈哈哈'
    },
    components: {
   
   
      myCom
    }
  })
</script>

</html>

在这里插入图片描述

6.6.2 为何组件的data必须是一个方法

首先,若是不是一个方法,Vue直接会报错。
其次,缘由在于Vue让每个组件对象都返回一个新的对象,若是是同一个对象的,组件会在屡次使用后相互影响。若是不写成方法返回对象的话,那么就是全部组件公用一个data。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>为何组件的data必须是方法</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <my-com></my-com>
    <my-com></my-com>
    <my-com></my-com>
    <my-com></my-com>
  </div>
</body>
<template id="myTemp">
  <div>
    <button @click="addCount">点击</button>
    <span>当前数量:{
   
   {
   
   count}}</span>
  </div>
</template>
<script>
  let myCom = Vue.extend({
   
   
    template: '#myTemp',
    data() {
   
   
      return {
   
   
        count: 0
      }
    },
    methods: {
   
   
      addCount() {
   
   
        this.count++
      }
    }
  })
  let app = new Vue({
   
   
    el: '#app',
    components: {
   
   
      myCom
    }
  })
</script>

</html>

在这里插入图片描述

6.7 组件的通讯

组件中,可以使用props来声明须要从父级接受到的数据。
首先在父组件中使用v-bind将数据绑定给子组件,再在子组件中,使用props接收。
Props和data、methods平级,有两种使用方式。
字符串数组,数组中的字符串就是传递时的名称。

6.7.1 父组件向子组件传值

组件中,可使用props来声明须要从父级接受到的数据。
首先在父组件中使用v-bind将数据绑定给子组件,再在子组件中,使用props接收。
Props和data、methods平级,有两种使用方式。
1.字符串数组,数组中的字符串就是传递时的名称。
2.对象,对象能够设置传递时的类型和默认值。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>父组件向子组件传值</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <!-- 第一步,用绑定的方式,将父组件的数据绑定给子组件 -->
    <my-com :msg="msg"></my-com>
  </div>
</body>
<template id="myTemp">
  <div>
    <span>当前数量:{
   
   {
   
   count}}</span>
    <div>{
   
   {
   
   msg}}</div>
  </div>
</template>
<script>
  let myCom = Vue.extend({
   
   
    template: '#myTemp',
    data() {
   
   
      return {
   
   
        count: 0
      }
    },
    //第一种 字符串数组
    // props: [
    //   // 第二步,使用props接收.
    //   'msg'
    // ]
    // 第二种 对象
    props: {
   
   
      msg: {
   
   
        type: String,
        default: '默认值,父组件没有传msg'
      }
    }
  })
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      msg: '父组件的msg'
    },
    components: {
   
   
      myCom
    }
  })
</script>

</html>

Type支持的类型:
String、Number、Boolean、Array、Object、Date、Function、Symbol

6.7.2 父组件向子组件传递方法

Props用于父组件向子组件传递数据,还有一种比较常见的就是子组件传递数据或者事件到父组件中。
可以使用自定义事件来完成。
父组件调用子组件的方法,使用$emit来实现。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>父组件向子组件传递方法</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <!-- 第一步,在子组件上,使用@符号为该组件绑定一个事件 -->
    <my-com @alert-msg="alertMsg"></my-com>
  </div>
</body>

<template id="myTemp">
  <div>
    <button @click="handlerMethod">点击</button>
  </div>
</template>

<script>
  let myCom = Vue.extend({
   
   
    template: '#myTemp',
    methods: {
   
   
      handlerMethod() {
   
   
        // 第一个参数表示要调用的方法。
        // 第二个参数日后,就是咱们须要传递的参数
        this.$emit('alert-msg', '调用')
      }
    }
  })
  
  let app = new Vue({
   
   
    el: '#app',
    data: {
   
   
      msg: '父组件的msg'
    },
    methods: {
   
   
      alertMsg(msg) {
   
   
        alert(msg)
      }
    },
    components: {
   
   
      myCom
    }
  })
</script>

</html>

在这里插入图片描述

6.7.3 父组件调用子组件方法

$ refs
$ refs是和ref一块儿使用的。经过ref给某个子组件绑定一个特定的ID,而后使用$refs.ID就能够访问到子组件。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>父组件调用子组件的方法</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <button @click="countAdd">点击</button>
    <!-- 第一步,给子组件绑定一个ref -->
    <my-com ref="myComp"></my-com>
  </div>
</body>

<template id="myTemp">
  <div>
    {
  
  {count}}
  </div>
</template>

<script>
  let myCom = Vue.extend({
    template: '#myTemp',
    data() {
      return {
        count: 1
      }
    },
    methods: {
      addCount() {
        this.count++
      }
    }
  })
  let app = new Vue({
    el: '#app',
    methods: {
      countAdd() {
        // 第二步,在父组件中使用this.$refs.id就好了
        console.log(this.$refs.myComp.count)
        this.$refs.myComp.addCount()
      }
    },
    components: {
      myCom
    }
  })
</script>

</html>

在这里插入图片描述

6.8 插槽

6.8.1 为何使用插槽

Slot翻译为插槽。
在生活中咱们不少地方都有插槽,必读电脑的USB插槽,插板的电源插槽。
插槽的目的是让设备具有更多的扩展性。
组件的插槽:
组建的插槽也是为了让封装的组件更具备扩展性。让使用者能够决定组件内部的一些内容要展现什么。
好比移动web中的导航栏。导航栏的内容可能不同,所以这里就须要使用插槽了。

3.8.2 如何封装

如何去封装这类组件?
它们有不少的区别,可是也有不少的共性,
若是每个都单独去封装一个组件,显然不合适。可是若是只封装一个,也有些不合理。有些导航栏有左侧菜单,有些是返回按钮,有些是搜索框,有些是文字。
封装的思想就是,抽取共性,保留不一样。将共性抽取到组件中,将不一样的区域暴露为插槽,供用户本身去设置。

6.8.3 Slot基本使用

在子组件中,使用特殊的标签 < slot > 就能够为子组件开启一个插槽。该插槽中插入什么内容取决于父组件的使用。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>solt</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <my-com>
      <h2>替换插槽的内容</h2>
      <ul>
        <li>我也是</li>
        <li>我也是的</li>
        <li>俺也同样</li>
      </ul>
    </my-com>
  </div>
</body>

<template id="myTemp">
  <div>
    哈哈哈哈
    <slot>插槽中的默认内容</slot>
    哈哈哈
  </div>
</template>

<script>
  let myCom = Vue.extend({
   
   
    template: '#myTemp',
  })
  let app = new Vue({
   
   
    el: '#app',
    components: {
   
   
      myCom
    }
  })
</script>

</html>

在这里插入图片描述

6.8.3 具名插槽

当子组件功能复杂时,子组件的插槽可能不止一个。好比封装导航栏的组件,可能就须要三个插槽,分别表明左中右。那么外面在给咱们插槽插入内容时,如何区分插入的是哪个呢?
这时就须要使用具名插槽。具名插槽就是在slot上定义一个名字。而在父组件中若是想要给指定位置的插槽插入内容的话,应该给标签加上slot属性,好比< span slot=”left” >

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>具名插槽</title>
  <script src="./lib/vue-2.4.0.js"></script>
</head>

<body>
  <div id="app">
    <my-com>
      <span slot="left">返回按钮</span>
      <span slot="center">搜索框</span>
      <span slot="right">菜单内容</span>
    </my-com>
  </div>
</body>

<template id="myTemp">
  <div>
    <slot name="left">左边</slot>
    <slot name="center">中间</slot>
    <slot name="right">右边</slot>
  </div>
</template>

<script>
  let myCom = Vue.extend({
   
   
    template: '#myTemp',
  })
  let app = new Vue({
   
   
    el: '#app',
    components: {
   
   
      myCom
    }
  })
</script>

</html>

在这里插入图片描述

7、模块化开发

7.1

组件化开发,通常是将重复的代码抽取成一个组件,供其余地方复用,通常状况下,提到组件化开发,都是指前端的组件化开发。
模块化开发,通常是将同一类功能模块的代码放到一块儿统一进行管理,是基于代码层面的,通常状况下,提到模块化开发,都是指后端。

7.1.1

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>模块化</title>
  <script src="./js/aaa.js"></script>
  <script src="./js/bbb.js"></script>
  <script>
    console.log('flag的值是', moduleB)
  </script>
</head>

<body>

</body>

</html>
var moduleA = (function() {
   
   
  var obj = {
   
   }
  var flag = true
  obj.flag = flag
  return obj
})()
var moduleB = (function() {
   
   
  var obj = {
   
   }
  var flag = false
  obj.flag = flag
  return obj
})()

在这里插入图片描述
在这里插入图片描述

7.1.2

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="export和import" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./js/info.js" type="module"></script>
  <script src="./js/info2.js" type="module"></script>
  <script src="./js/main.js" type="module"></script>
</head>
<body>
  
</body>
</html>

8、Webpack入门