Day03

YangeIT大约 40 分钟JavaWebvue

Day03

课程内容

  • 能够使用 VUE 中常用指令和插值表达式 ✏️ 🍐
  • 能够使用 VUE 生命周期函数 mounted 🍐
  • 能够进行简单的 Element 页面修改
  • 能够使用Axios发起网络请求 🍐 ✏️
  • 能够完成查询所有功能 ✏️

1. Vue概述及入门 🍐 ✏️

前面两天,我们已经学习了前端网页开发的三剑客:HTML、CSS、JSimage。那通过这三种技术呢,我们就可以开发出一个网页程序了,但是如果我们使用原生的JS来处理界面的交互行为,开发效率呢,是比较低的 。而在现在的企业项目开发中,一般会借助于Vue这样的js框架来简化操作、提高开发效率 。 那么我们今天呢,就来学习Vue这个框架。

Vue概述及入门

Vue(读音 /vjuː/, 类似于 view),是一款用于构建用户界面渐进式的JavaScript框架(官方网站:https://cn.vuejs.orgopen in new window)。

image-20231120103635322
image-20231120103635322

在上面的这句话中呢,出现了三个词,分别是:构建用户界面、渐进式、框架

1). 构建用户界面

构建用户界面是指,在Vue中,可以基于数据渲染出用户看到的界面。 那这句话什么意思呢?我们来举一个例子,比如将来服务器端返回给前端的原始数据呢,就是如下这个样子:

userList: [
    {"id": 1, "name": "谢逊", "image": "1.jpg", "gender": 1, "job": "班主任"},
    {"id": 2, "name": "韦一笑", "image": "2.jpg", "gender": 1, "job": "班主任"}
]

而上面的这些原始数据,用户是看不懂的。 而我们开发人员呢,可以使用Vue中提供的操作,将原始数据遍历、解析出来,从而渲染呈现出用户所能看懂的界面,如下所示:

image-20231120104643148

那这个过程呢,就是基于数据渲染出用户看到的界面,也就是所谓的 构建用户界面。

2). 渐进式

渐进式中的渐进呢,字面意思就是 "循序渐进"。Vue生态中的语法呢是非常多的,比如声明式渲染、组件系统、客户端路由(VueRouter)、状态管理(Vuex、Pinia)、构建工具(Webpack、Vite)等等。

image-20231120105506568

所谓渐进,指的是我们使用Vue框架呢,我们不需要把所有的组件、语法全部学习完毕才可以使用Vue。 而是,我们学习一点就可以使用一点了,比如:

  • 我们学习了声明式渲染,我们就可以使用Vue来构建用户界面了。
  • 我们再学习了组件系统,我们就可以使用Vue中的组件,从而来复用了。
  • 我们再学习了路由VueRouter,就可以使用Vue中的中的路由功能了。

也就是说,并不需要全部学习完毕就可以直接使用Vue进行开发,简化操作、提高效率了。 Vue是一个框架,但其实也是一个生态。

那由此呢,也就引出了Vue中两种常见的开发模式:👇

  1. 基于Vue提供的核心包,完成项目局部模块的改造了。
  2. 基于Vue提供的核心包、插件进行工程化开发,也就是做整站开发。

那上面的这两种Vue的使用形式,我们都会学习,今天我们先来学习第一种方式,就是使用Vue来完成局部模块改造。

3). 框架

  • 框架:就是一套完整的项目解决方案,用于快速构建项目半成品软件 。这是我们接触的第一个框架,那在我们后面的学习中,我们还会学习很多的java语言中的框架,那通过这些框架呢,就可以来快速开发java项目,提高开发效率。

  • 优点:大大提升前端项目的开发效率 。

  • 缺点:需要理解记忆框架的使用规则 。(参照官网)

今天内容

好,那我们知道了什么是Vue之后,接下来,就要正式进入Vue的学习,我们今天主要讲解以下几个方面:

  1. Vue快速入门
  2. Vue常用指令
  3. Ajax
  4. Vue生命周期

快速入门代码操作

需求

接下来我们通过一个vue的快速入门案例,来体验一下Vue开发,并掌握Vue的开发步骤 。那在这个入门程序中,我们就要完成刚才上面提到的,基于数据渲染出用户看到的页面,也就是数据驱动视图(这个视图指的就是页面的展示)操作。

在入门程序中,最终我们需要将准备的数据 message 的值,基于Vue渲染展示在页面中,最终呈现的形式如下:

image-20231120110529330
image-20231120110529330

步骤如下:

1). 准备工作:

  • 1.1 准备一个html文件,并在其中引入Vue模块 (参考官方文档open in new window,复制过来即可)【注意:模块化的js,引入时,需要设置 type="module"
  • 1.2 创建Vue程序的应用实例,控制视图的元素
  • 1.3 准备元素(div),交给Vue控制
image
image

这三步准备工作,是我们使用Vue时,都需要做的,是固定步骤。 这样我们就搭建好了一个基本的Vue的结构了。

总结

课堂作业

  1. 从官网中复制模板,然后完成入门案例,在data定义一个username:yangeit的数据,然后在div中显示出来!🎤

2. Vue指令

2.1 Vue指令之v-for 🍐 ✏️

Vue指令之v-for

刚才通过一个快速入门程序,大家快速感受了一下Vue的开发,并明确了Vue的开发步骤。那接下来,我们要来学习的是Vue中的常用指令,通过Vue中的指令,就可以将原始的数据,根据不同的需求,渲染展示在界面中🎯。

在讲解Vue指令的时候呢,将会通过一个小案例来贯穿始终。 那就是用户列表渲染的案例,需求如下所示:

  1. 将Vue中定义的数据userList,渲染展示在视图的表格之中。
  2. 在原始数据中,性别gender如果为1,展示为"男";如果为2,展示为"女"。
  3. 在原始数据中,职位job如果为1,展示为"讲师";如果为2,展示为"班主任";如果为3,展示为"其他"。
image-20231120114039162
image-20231120114039162

而要想完成这个需求,就需要用到Vue中的一些常用指令,那接下来呢,我们就来介绍一下Vue中的常用指令。

代码操作

  • 指令:v-for
  • 作用:列表渲染,遍历容器的元素或者对象的属性
  • 语法v-for = "(item,index) in items"
  • 参数
    • items 为遍历的数组
    • item 为遍历出来的元素
    • index 为索引/下标,从0开始 ;可以省略,省略index语法: v-for = "item in items"
  • 示例:

image-20231120114811431

演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-for入门</title>
</head>
<body>
  
  <div id="app">
    <p v-for="(name,index) in names">{{index + 1}}: {{name}}</p>
  </div>
  
  <script type="module">
    import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
    createApp({
      data(){
        return {
          names: ['张无忌', '张三丰', '韦一笑', '殷天正']
        }
      }
    }).mount('#app')
  </script>
</body>
</html>

经过浏览器的解析渲染之后,展示出如下界面:

image-20231120115000289
image-20231120115000289

v-for的key:

  • 作用:给元素添加的唯一标识,便于vue进行列表项的正确排序复用
  • 语法v-for="(item,index) in items" :key="唯一值"
  • 注意点:
    • key的值只能是字符串 或 数字类型
    • key的值必须具有唯一性
    • 推荐使用id作为key(唯一),不推荐使用index作为key(会变化,不对应)
  • 写法:image-20231120115312997

提示:官方推荐在使用 v-for 时提供一个key属性,以遍可以追踪每个节点,提升渲染性能。

总结

课堂作业

  1. v-for的作用🎤
  2. 参考上述案例需求,完成编码!

2.2 Vue指令之v-bind 🍐 ✏️

Vue指令之v-bind

  • 作用 :动态为HTML标签绑定属性值,如设置href,src,style样式等。
  • 语法v-bind:属性名="属性值"
  • 简化:属性名="属性值"
  • 注意v-bind 所绑定的数据,必须在data中定义。

代码操作

演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-bind入门</title>
</head>
<body>
  
  <div id="app">
    <a v-bind:href="url">链接1</a> <br><br>
    <a :href="url">链接2</a>
  </div>
  
  <script type="module">
    import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
    createApp({
      data(){
        return {
          url: 'https://www.itcast.cn'
        }
      }
    }).mount('#app')
  </script>
</body>
</html>








 
 
 
 






 






通过上述代码,已经为a标签的href属性绑定上了url变量,如果数据 url 发生变化,v-bind绑定的属性也会自动发生变化。 我们可以F12打开浏览器的开发者工具,通过Vue插件,来修改Vue的数据url,我们会看到超链接的链接的地址会自动发生变化 。

image-20231120154321380
image-20231120154321380

总结

课堂作业

  1. v-bind有什么作用? 🎤
  2. 在完成v-for案例后,在原有的项目中,完成图片的显示

2.3 Vue指令之v-if & v-show 🍐 ✏️

Vue指令之v-if & v-show

作用:这两类指令,都是用来控制元素的显示与隐藏的

v-if:

  • 语法 :v-if="表达式",表达式值为 true,显示;false,隐藏
  • 原理 :基于条件判断,来控制创建或移除元素节点(条件渲染)
  • 场景 :要么显示,要么不显示,不频繁切换的场景
  • 其它 :可以配合 v-else-if / v-else 进行链式调用条件判断

v-show:

  • 语法:v-show="表达式",表达式值为 true,显示;false,隐藏
  • 原理:基于CSS样式display来控制显示与隐藏
  • 场景:频繁切换显示隐藏的场景

注意: v-else-if必须出现在v-if之后,可以出现多个; v-else 必须出现在v-if/v-else-if之后 。

代码操作

案例-性别职位展示

那接下来,我们就通过 v-ifv-show 指令来完成性别 、职位数据的展示。

<!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>Vue3-案例1</title>
  <style>
    table,th,td {
      border: 1px solid #000;
      border-collapse: collapse;
      line-height: 50px;
      text-align: center;
    }

    #center,table {
      width: 60%;
      margin: auto;
    }

    #center {
      margin-bottom: 20px;
    }

    img {
      width: 50px;
    }

    input,select {
      width: 17%;
      padding: 10px;
      margin-right: 30px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }

    .btn {
      background-color: #ccc;
    }
  </style>
</head>

<body>
  <div id="app">
    <div id="center">
      姓名: <input type="text" name="name">
      性别:
      <select name="gender">
        <option value="1"></option>
        <option value="2"></option>
      </select>
      职位:
      <select name="job">
        <option value="1">讲师</option>
        <option value="2">班主任</option>
        <option value="3">其他</option>
      </select>

      <input class="btn" type="button" value="查询">
    </div>

    <table>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>头像</th>
        <th>性别</th>
        <th>职位</th>
        <th>入职时间</th>
        <th>更新时间</th>
      </tr>

      <tr v-for="(user, index) in userList" :key="user.id">
        <td>{{index + 1}}</td>
        <td>{{user.name}}</td>
        <td> <img :src="user.image"> </td>
        <td>
          <!-- v-if 控制显示或隐藏 -->
          <span v-if="user.gender == 1"></span>
          <span v-else-if="user.gender == 2"></span>
          <span v-else>其他</span>
        </td>
        <td>
          <!-- v-show 控制显示或隐藏 -->
          <span v-show="user.job == 1">讲师</span>
          <span v-show="user.job == 2">班主任</span>
          <span v-show="user.job == 3">其他</span>
        </td>
        <td>{{user.entrydate}}</td>
        <td>{{user.updatetime}}</td>
      </tr>
    </table>
  </div>

  <script type="module">
    import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'

    createApp({
      data() {
        return {
          userList: [
            {
              "id": 1,
              "name": "谢逊",
              "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg",
              "gender": 1,
              "job": 1,
              "entrydate": "2023-06-09",
              "updatetime": "2023-07-01 00:00:00"
            },
            {
              "id": 2,
              "name": "韦一笑",
              "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/2.jpg",
              "gender": 1,
              "job": 1,
              "entrydate": "2023-06-09",
              "updatetime": "2023-07-01 00:00:00"
            },
            {
              "id": 3,
              "name": "黛绮丝",
              "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/3.jpg",
              "gender": 2,
              "job": 2,
              "entrydate": "2023-06-09",
              "updatetime": "2023-07-01 00:00:00"
            },
            {
              "id": 4,
              "name": "殷天正",
              "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/4.jpg",
              "gender": 1,
              "job": 3,
              "entrydate": "2023-06-09",
              "updatetime": "2023-07-01 00:00:00"
            }
          ]
        }
      },
    }).mount("#app");
  </script>
</body>

</html>













































































 
 
 
 
 
 
 
 
 
 
 
 

























































浏览器打开此页面后,经过浏览器的解析,数据可以正确的显示出来了 。

image-20231120160352396

通过F12,打开浏览器的开发者工具,我们可以看到 v-if 控制元素的显示与隐藏时,如果条件不成立,压根就不会渲染对应的元素。 而通过 v-show 控制元素的显示或隐藏,基于 CSS 样式display来控制显示与隐藏。

image-20231120161013292
image-20231120161013292

所以,对于 v-if 适用于控制显示或隐藏不频繁的场景。 而 v-show 适用于显示与隐藏切换频繁的场景。

总结

课堂作业

  1. v-ifv-show 区别?🎤
  2. 结合 v-ifv-show 的特性,各自可以应用在哪些场景?🎤
  3. 结合 v-ifv-show 的特性,完成上述案例中职位和性别的中文显示!!

2.4 Vue指令之v-model 🍐 ✏️

Vue指令之v-model

  • 作用 :在表单元素上使用,双向数据绑定 。可以方便的 获取设置 表单项数据
  • 语法v-model="变量名"

这里的双向数据绑定,是指 Vue中的数据变化,会影响视图中的数据展示。 视图中的输入的数据变化,也会影响Vue的数据模型 。

image-20231120161524488
image-20231120161524488

注意:v-model 中绑定的变量,必须在data中定义。

代码操作

指令演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-model入门</title>
</head>
<body>
  <div id="app">
    <input type="text" v-model="name"> <br>
    {{name}}
  </div>
  
  <script type="module">
    import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
    createApp({
      data(){
        return {
          name: 'Vue'
        }
      }
    }).mount('#app')
  </script>
</body>
</html>

最终的效果如下: 视图中的数据变化,会影响Vue的数据模型。 Vue的属性模型变化,也会影响视图的展示 。

image
image

总结

课堂作业

  1. v-model有哪些作用?🎤
  2. v-model和v-bind的区别是什么?🎤
  3. 结合v-model的特性,完成案例中表单的数据获取,为下面的查询做准备!!

2.5 Vue指令之v-on 🍐 ✏️

Vue指令之v-on

  • 作用: 为html标签绑定事件(添加时间监听)

  • 语法:

    • v-on:事件名="内联语句"

      • <input type="button" value="点我一下试试" v-on:click="console.log('试试就试试');">
        
    • v-on:事件名="函数名"

      • <input type="button" value="点我一下试试" v-on:click="handle">
        

        这里的handle函数,就需要在Vue应用实例创建的时候创建出来,在methods定义。

    • 简写为 @事件名="…"

代码操作

演示

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>v-on入门</title>
</head>
<body>
  
  <div id="app">
    <input type="button" value="点我一下试试" v-on:click="handle">
    <input type="button" value="再点我一下试试" @click="handle">
  </div>
  
  <script type="module">
    import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
    createApp({
      data(){
        return {
          name: 'Vue'
        }
      },
      methods: {
        handle(){
          console.log('试试就试试');
        }
      }
    }).mount('#app')
  </script>
</body>
</html>










 
 









 
 
 
 
 




总结

课堂作业

  1. v-on指令有什么用?🎤
  2. 结合需求,完成案例中事件的绑定 🎤

4. Ajax

4.1 Ajax概述以及同步异步的概念 🍐

Ajax概述以及同步异步的概念

  1. 我们前端页面中的数据,如下图所示的表格中的学生信息,应该来自于后台,那么我们的后台和前端是互不影响的2个程序
  2. 那么我们前端应该如何从后台获取数据呢? 因为是2个程序,所以必须涉及到2个程序的交互,所以这就需要用到我们接下来学习的Ajax技术
image-20231121091712173

Ajax 全称Asynchronous JavaScript And XML,异步的JavaScript和XML。其作用有如下2点:

  • 与服务器进行数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。
  • 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等。

我们详细的解释一下Ajax技术的2个作用

  • 与服务器进行数据交互

    如下图所示前端资源被浏览器解析,但是前端页面上缺少数据,前端可以通过Ajax技术,向后台服务器发起请求,后台服务器接受到前端的请求,从数据库中获取前端需要的资源,然后响应给前端,前端在通过我们学习的vue技术,可以将数据展示到页面上,这样用户就能看到完整的页面了。此处可以对比JavaSE中的网络编程技术来理解。

image-20231121091921868

  • 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。

    如下图所示,当我们再百度搜索java时,下面的联想数据是通过Ajax请求从后台服务器得到的,在整个过程中,我们的Ajax请求不会导致整个百度页面的重新加载,并且只针对搜索栏这局部模块的数据进行了数据的更新,不会对整个页面的其他地方进行数据的更新,这样就大大提升了页面的加载速度,用户体验高局部刷新

image-20231121092007961

代码操作

对于Ajax技术有了充分的认知了,我们接下来通过代码来演示Ajax的效果。此处我们先采用原生的Ajax代码来演示。因为Ajax请求是基于客户端发送请求,服务器响应数据的技术。所以为了完成快速入门案例,我们需要提供服服务器端和编写客户端。

1). 服务器端

因为我们暂时还没学过服务器端的代码,所以此处已经直接提供好了服务器端的请求地址,我们前端直接通过Ajax请求访问该地址即可。后台服务器地址https://mock.apifox.cn/m1/3083103-0-default/emps/listopen in new window

上述地址我们也可以直接通过浏览器来访问,访问结果如图所示:只截取部分数据

image-20231121092415198
image-20231121092415198

总结

课堂作业

  1. Ajax的作用是什么?🎤
  2. Ajax原生代码简洁吗?能记住吗?🎤

4.2 Axios 🍐

Axios

上述原生的Ajax请求的代码编写起来还是比较繁琐的,所以接下来我们学习一门更加简单的发送Ajax请求的技术Axios 。Axios是对原生的AJAX进行封装,简化书写。

Axios官网是:https://www.axios-http.cnopen in new window

Axios的基本使用

Axios的使用比较简单,主要分为2步:

  • 引入Axios文件

    <!-- 使用本地的js文件 -->
    <script src="js/axios-0.18.0.js"></script>
    
    <!-- 也可以使用网络上的js文件 二选一 -->
    <!-- <script src="https://unpkg.com/axios/dist/axios.min.js"></script> -->
    
  • 使用Axios发送请求,并获取响应结果,官方提供的api很多,此处给出2种,如下

    • 发送 get 请求

      axios({
          method:"get",
          url:"https://mock.apifox.cn/m1/3083103-0-default/emps/list"
      }).then(function (resp){
         console.log(resp.data);
      })
      
    • 发送 post 请求

      axios({
          method:"post",
          url:"https://mock.apifox.cn/m1/3083103-0-default/emps/update",
          data:"id=1"
      }).then(function (resp){
          console.log(resp.data);
      });
      

    axios()是用来发送异步请求的,小括号中使用 js的JSON对象传递请求相关的参数:

    • method属性:用来设置请求方式的。取值为 get 或者 post。
    • url属性:用来书写请求的资源路径。如果是 get 请求,需要将请求参数拼接到路径的后面,格式为: url?参数名=参数值&参数名2=参数值2。
    • data属性:作为请求体被发送的数据。也就是说如果是 post 请求的话,数据需要作为 data 属性的值。

    then() 需要传递一个匿名函数。我们将 then()中传递的匿名函数称为 回调函数,意思是该匿名函数在发送请求时不会被调用,而是在成功响应后调用的函数。而该回调函数中的 resp 参数是对响应的数据进行封装的对象,通过 resp.data 可以获取到响应的数据。

Axios入门程序代码操作

Axios入门程序

  • 后端实现

  • 前端实现

    • A. 引入axios.min.js 【联网加载 或 引入下载好的本地的JS都可以】
    • B. 为两个 "按钮" 绑定事件
    • C. 触发事件之后,基于axios发送异步请求,分别发送GET请求、POST请求获取数据

    完整代码如下:

    <!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>Ajax-Axios</title>
    </head>
    <body>
        
        <input type="button" value="获取数据GET" id="btnGet">
        <input type="button" value="删除数据POST" id="btnPost">
    
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
        <script>
            //GET请求
            document.querySelector('#btnGet').addEventListener('click', ()=>{
                axios({
                    url: 'https://mock.apifox.cn/m1/3083103-0-default/emps/list',
                    method: 'GET'
                }).then(result => {
                    console.log(result.data);
                }).catch(err => {
                    console.log(err);
                })
            })
    
            //POST请求
            document.querySelector('#btnPost').addEventListener('click', ()=>{
                axios({
                    url: 'https://mock.apifox.cn/m1/3083103-0-default/emps/update',
                    method: 'POST',
                    data:'id=1'
                }).then(result => {
                    console.log(result.data);
                }).catch(err => {
                    console.log(err);
                })
            })
        </script>
    </body>
    </html>
    

    浏览器打开,f12抓包,然后分别点击2个按钮,查看控制台效果如下:

    image-20231121094840708
    image-20231121094840708

总结

课堂作业

  1. axios是什么?和ajax原生代码相比,有什么不一样?🎤
  2. axios发送get和post请求时,参数位置有什么注意事项?🎤

4.3 案例-Axios异步获取数据 🍐 ✏️

Axios异步获取数据

通过上面的学习,我们已经清楚了什么是Ajax,已经如何发送Ajax异步请求。 那解下来呢,我们就要完成员工列表数据加载的这个案例。

需求:当点击查询按钮 时,发送Ajax异步请求,根据传递的查询条件,动态获取数据,渲染列表页面。

image-20231121095345723

服务端地址:https://web-server.itheima.net/emps/listopen in new window

代码操作

具体代码如下:

<!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>Vue3-案例1</title>
  <style>
    table,th,td {
      border: 1px solid #000;
      border-collapse: collapse;
      line-height: 50px;
      text-align: center;
    }

    #center,table {
      width: 60%;
      margin: auto;
    }

    #center {
      margin-bottom: 20px;
    }

    img {
      width: 50px;
    }

    input,select {
      width: 17%;
      padding: 10px;
      margin-right: 30px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }

    .btn {
      background-color: #ccc;
    }
  </style>
</head>

<body>
  <div id="app">
    <div id="center">
      姓名: <input type="text" v-model="name">
      性别:
      <select v-model="gender">
        <option value="1"></option>
        <option value="2"></option>
      </select>
      职位:
      <select v-model="job">
        <option value="1">讲师</option>
        <option value="2">班主任</option>
        <option value="3">其他</option>
      </select>
      
      <!-- <input class="btn" type="button" value="查询" v-on:click="handle"> -->
      <input class="btn" type="button" value="查询" @click="handle">
    </div>
    
    <table>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>头像</th>
        <th>性别</th>
        <th>职位</th>
        <th>入职时间</th>
        <th>更新时间</th>
      </tr>

      <tr v-for="(user, index) in userList" :key="user.id">
        <td>{{index + 1}}</td>
        <td>{{user.name}}</td>
        <td> <img :src="user.image"> </td>
        <td>
          <span v-if="user.gender == 1"></span>
          <span v-else-if="user.gender == 2"></span>
          <span v-else>其他</span>
        </td>
        <td>
          <span v-if="user.job == 1">讲师</span>
          <span v-else-if="user.job == 2">班主任</span>
          <span v-else>其他</span>
        </td>
        <td>{{user.entrydate}}</td>
        <td>{{user.updatetime}}</td>
      </tr>
    </table>
  </div>

  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script type="module">
    import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'

    createApp({
      data() {
        return {
          name: '',
          gender: '',
          job: '',
          userList: []
        }
      },
      methods: {
       handle: function(){
         console.log(`查询啦, 查询条件: name=${this.name}, gender=${this.gender}, job=${this.job}`);
         axios.get(`https://web-server.itheima.net/emps/list?name=${this.name}&gender=${this.gender}&job=${this.job}`).then((result) => {
            this.userList = result.data.data;
         })
       } 
      }
    }).mount("#app");
  </script>
</body>

</html>




























































 

































 













 
 
 
 
 
 
 





打开浏览器测试:

image
image

经过上面的测试之后,我们看到:

  1. 当我们点击 "查询" 按钮时,确实可以发送Ajax异步请求,动态获取数据。
  2. 但是,我们打开这个页面时,表格内容却是一片空白,只有点击了查询按钮才会展示出数据
  3. 而在正常的系统中,应该是进入页面时,就会展示出表格中的数据的。

那如何在页面打开之后,就自动执行查询呢? 那此时,我们就需要用到Vue中生命周期的相关函数了。那接下来,我们就来学习Vue的声明周期。

总结

课堂作业

  1. methods: { 定义函数 } 中,定义一个函数,通过axios获取后台的数据,然后绑定到查询按钮上 进行点击触发!🎤

5. 生命周期 🍐

5.1 生命周期概述 🍐

生命周期概述

vue的生命周期:指的是vue对象从创建到销毁的过程。

vue的生命周期包含8个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法,这些生命周期方法也被称为钩子方法。其完整的生命周期如下图所示:

状态阶段周期
beforeCreate创建前
created创建后
beforeMount挂载前
mounted挂载完成
beforeUpdate更新前
updated更新后
beforeDestroy销毁前
destroyed销毁后

下图是 Vue 官网提供的从创建 Vue 到效果 Vue 对象的整个过程及各个阶段对应的钩子函数:

image-20231121100701193
image-20231121100701193

其中我们需要重点关注的是mounted, 其他的我们了解即可。

mounted:挂载完成,Vue初始化成功,HTML页面渲染成功。以后我们一般用于页面初始化自动的ajax请求后台数据

代码演示

案例-员工列表查询

那我们要想在页面加载完毕,就查询出员工列表,就可以在mounted钩子函数中,发送异步请求查询员工数据了。

具体代码如下:

<!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>Vue3-案例1</title>
  <style>
    table,th,td {
      border: 1px solid #000;
      border-collapse: collapse;
      line-height: 50px;
      text-align: center;
    }

    #center,table {
      width: 60%;
      margin: auto;
    }

    #center {
      margin-bottom: 20px;
    }

    img {
      width: 50px;
    }

    input,select {
      width: 17%;
      padding: 10px;
      margin-right: 30px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }

    .btn {
      background-color: #ccc;
    }
  </style>
</head>

<body>
  <div id="app">
    <div id="center">
      姓名: <input type="text" v-model="name">
      性别:
      <select v-model="gender">
        <option value="1"></option>
        <option value="2"></option>
      </select>
      职位:
      <select v-model="job">
        <option value="1">讲师</option>
        <option value="2">班主任</option>
        <option value="3">其他</option>
      </select>
      
      <!-- <input class="btn" type="button" value="查询" v-on:click="handle"> -->
      <input class="btn" type="button" value="查询" @click="handle">
    </div>
    
    <table>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>头像</th>
        <th>性别</th>
        <th>职位</th>
        <th>入职时间</th>
        <th>更新时间</th>
      </tr>

      <tr v-for="(user, index) in userList" :key="user.id">
        <td>{{index + 1}}</td>
        <td>{{user.name}}</td>
        <td> <img :src="user.image"> </td>
        <td>
          <span v-if="user.gender == 1"></span>
          <span v-else-if="user.gender == 2"></span>
          <span v-else>其他</span>
        </td>
        <td>
          <span v-if="user.job == 1">讲师</span>
          <span v-else-if="user.job == 2">班主任</span>
          <span v-else>其他</span>
        </td>
        <td>{{user.entrydate}}</td>
        <td>{{user.updatetime}}</td>
      </tr>
    </table>
  </div>

  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script type="module">
    import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'

    createApp({
      data() {
        return {
          name: '',
          gender: '',
          job: '',
          userList: []
        }
      },
      methods: {
       handle: function(){
         console.log(`查询啦, 查询条件: name=${this.name}, gender=${this.gender}, job=${this.job}`);
         axios.get(`https://web-server.itheima.net/emps/list?name=${this.name}&gender=${this.gender}&job=${this.job}`).then((result) => {
            this.userList = result.data.data;
         })
       } 
      },
      mounted() {
        // Vue初始化成功,HTML页面渲染成功后 mounted执行,发起网络请求
        this.handle();
      },
    }).mount("#app");
  </script>
</body>

</html>



















































































































 
 
 
 





打开浏览器,进行测试,我们看到,当我们访问这个页面之后,会自动查询所有的员工数据 。

未命名项目4
未命名项目4

5.2 案例-省市区 🍐 ✏️

前言

1.需求:页面加载完毕后,默认加载并展示出第一个省、第一个市、第一个区。

  • 如图所示:

image-20231121101712141

2.分析

  1. 要想在页面加载完成后,默认加载出第一个省、第一个省对应的第一个市、第一个市对应的第一个区。 就应该用到vue的钩子函数 mounted。
  2. 那要想加载出省市区,就需要发送3次异步请求,第一次获取省。
  3. 那什么时候发送第二次异步请求,获取市呢 ? 应该是在第一次异步请求完成之后,我们获取到第一个省份,然后再根据省份的ID查询市。
  4. 那什么时候发送第三次异步请求,获取区呢 ?应该是在第二次异步请求完成之后,我们获取到第一个市,然后再根据市的ID查询区。从获取到区 。

思考:如何在第一次异步请求成功后,再发送第二次异步请求获取数据呢 ?

​ 那么此时,我们就可以在第一个请求的成功回调函数中,来发送第二次请求 。这样就可以保证,是第一个请求成功,才发送的第二次请求。

代码操作

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Vue3-案例-省市区</title>
    <style>
      #center {
        margin-bottom: 20px;
      }

      input,
      select {
        width: 17%;
        padding: 10px;
        margin-right: 30px;
        border: 1px solid #ccc;
        border-radius: 4px;
      }
    </style>
  </head>

  <body>
    <div id="app">
      <div id="center">
        省:
        <select v-model="province">
          <option v-for="p in provinces" :key="p.id" :value="p.id">{{p.name}}</option>
        </select>
        市:
        <select v-model="city">
          <option v-for="c in cities" :key="c.id" :value="c.id">{{c.name}}</option>
        </select>
        区:
        <select v-model="area">
          <option v-for="a in areas" :key="a.id" :value="a.id">{{a.name}}</option>
        </select>
      </div>
    </div>

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script type="module">
      import { createApp } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";
      createApp({
        data() {
          return {
            province: '',
            city: '',
            area: '',

            provinces: [],
            cities: [],
            areas: [],
          };
        },
        methods: {
          search() {
            axios.get(`https://web-server.itheima.net/province`).then((result) => {
                this.provinces = result.data.data;
                this.province = this.provinces[0].id;
                axios.get(`https://web-server.itheima.net/city?pid=${this.province}`).then((result) => {
                    this.cities = result.data.data;
                    this.city = this.cities[0].id;
                    axios.get(`https://web-server.itheima.net/area?cid=xxx${this.city}`).then((result) => {
                        this.areas = result.data.data;
                        this.area = this.areas[0].id;
                      });
                  });
              });
          }
        },
        mounted() {
          this.search();
        },
      }).mount("#app");
    </script>
  </body>
</html>
























































 
 
 
 
 
 
 
 
 
 
 
 
 
 









打开浏览器测试:

image
image

经过测试我们看到,通过这种方案,确实可以实现该功能

  1. 在页面加载完毕后,确实默认将第一个省、第一个省对应的第一个市、第一个市对应的第一个区展示出来。
  2. 但是呢,上面我们编写的代码呢,类似于 "套娃",一层套一层,可读性、可维护性都是比较差的 。 这种问题呢,也被称为 回调地狱

那如果出现这样的驱动,我们如何来优化我们的代码,以增强程序的可读性和可维护性呢

那这里呢,我们是可以借助于JS中给我们提供的async/await 来解决这个问题的。