JavaWeb-02-前端Web开发(JS+Vue+Ajax)

目录

一、JS核心语法

1.1 JS的引入方式

1.2 基础语法 

1.2.1 输出语句

1.2.2 变量和常量

1.2.3 数据类型

 1.2.4 函数

1.2.4.1 方式一(具名)

 1.2.4.2 方式二(匿名)

1.2.4.3 自定义对象

1.2.4.4 josn 

​编辑 1.2.5 控制流程

1.2.6 JS DOM 

1.2.6.1 介绍

1.2.6.2 DOM操作 

二、JS事件监听

2.1 事件介绍

2.2 事件监听语法

2.3 隔行换色案例

2.4 常见事件 

三、Vue介绍

3.1 概述

3.2 入门程序

3.2.1 需求

3.2.2 步骤 

3.2.3 实现 

四、Vue指令

4.1 概述

4.2 案例

4.2.1 基本实现

4.2.2 指令详解

4.2.2.1 v-for

4.2.2.2 v-bind

4.2.2.3 v-if & v-show 

 4.2.2.4 v-model

 4.2.2.5 v-on

五、Ajax

5.1 概述

5.2 同步异步

5.3 Axios 

5.3.1 入门程序 

5.3.2 请求方法别名

5.4 案例-异步获取数据

六、Vue生命周期

6.1 介绍

​编辑6.2 案例演示


JavaScript(简称:JS) 是一门跨平台、面向对象的脚本语言,是用来控制网页行为的,实现人机交互效果。JavaScript 和 Java 是完全不同的语言,不论是概念还是设计。但是基础语法类似。

  • 组成:

    • ECMAScript: 规定了JS基础语法核心知识,包括变量、数据类型、流程控制、函数、对象等。

    • BOM:浏览器对象模型,用于操作浏览器本身,如:页面弹窗、地址栏操作、关闭窗口等。

    • DOM:文档对象模型,用于操作HTML文档,如:改变标签内的内容、改变标签内字体样式等。

一、JS核心语法

1.1 JS的引入方式

同样,js代码也是书写在html中的,那么html中如何引入js代码呢?主要通过下面的2种引入方式:

例子如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>JS-引入方式</title>
</head>
<body>
  

<script>
    //1. 内部脚本
    alert('Hello JS');
  </script>

  <!-- 2. 外部脚本 -->
  <!-- <script src="js/demo.js"></script> -->
</body>
</html>

效果如下:

  • 第二种方式:外部脚本, 将JS代码定义在外部 JS文件中,然后引入到 HTML页面中

    • 外部JS文件中,只包含JS代码,不包含<script>标签

    • 引入外部js的<script>标签,必须是双标签

     在js目录下,定义一个js文件demo.js,在文件中编写js代码,如下:

    alert('Hello JS')

    在html文件中,通过<script></script>引入js文件demo.js,如下: 

    <script src="js/demo.js"></script>
    • 注意1:demo.js中只有js代码,没有<script>标签

    • 注意2:通过<script></script>标签引入外部JS文件时,标签不能自闭合,如:<script src="js/demo.js" />

    1.2 基础语法 

    1.2.1 输出语句

    在JS中有3种输出语句,分别是:

    1.2.2 变量和常量

    • JS中主要通过 let 关键字来声明变量的。

    • JS是一门弱类型语言,变量是可以存放不同类型的值的。

    • 变量名需要遵循如下规则:

      • 组成字符可以是任何字母、数字、下划线(_)或美元符号($),且数字不能开头

      • 变量名严格区分大小写,如:name和Name是不同的变量

      • 不能使用关键字作为变量名,如:let、if、for等

    变量的声明示例如下所示: 

    <script>
        //变量
        let a = 20;
        a = "Hello";
        alert(a);
    </script>

    效果图如下:

    上述的示例中,大家会看到变量a既可以存数字,又可以存字符串。 因为JS是弱类型语言。 

    在JS中,如果声明一个常量,需要使用const关键字。一旦声明,常量的值就不能改变 (不可以重新赋值)。

    如下所示:

    <body>
    
        <script>
            //常量
            const PI = 3.14;
            PI = 3.15;
            alert(PI);
        </script>
    </body>

     示例代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>JS-基础语法</title>
    </head>
    <body>
      
    
      <script>
        //1. 声明变量
        // let a = 10;
         a = "Hello";
        // a = true;
    
         alert(a); //弹出框
    
        //2. 声明常量
        const PI = 3.14;
        //PI = 5.0;
    
       // console.log(PI); //输出到控制台   浏览器控制台按下f12键
        // document.write(PI); //输出到body区域(不常用)
      </script>
    </body>
    </html>

    1.2.3 数据类型

    虽然JS是弱数据类型的语言,但是JS中也存在数据类型,JS中的数据类型分为 :原始数据类型 和 引用数据类型。那这部分,我们先来学习原始数据类型,主要包含以下几种类型:

    使用typeof 关键字可以返回变量的数据类型,接下来我们需要通过书写代码来演示js中的数据类型。代码如下:

    <!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>JS-数据类型</title>
    </head>
    <body>
    
        <script>
            //原始数据类型
            alert(typeof 3); //number
            alert(typeof 3.14); //number
    
            alert(typeof "A"); //string
            alert(typeof 'Hello');//string
    
            alert(typeof true); //boolean
            alert(typeof false);//boolean
    
            alert(typeof null); //object 
    
            let a ;
            alert(typeof a); //undefined
    
        </script>
    </body>
    </html>

     对于字符串类型的数据,除了可以使用双引号("...")、单引号('...')以外,还可以使用反引号 (``)。 而使用反引号引起来的字符串,也称为 模板字符串

    • 模板字符串的使用场景:拼接字符串和变量。

    • 模板字符串的语法:

      • `...` :反引号 (英文输入模式下键盘 tab 键上方波浪线 ~ 那个键)

      • 内容拼接时,使用 ${ } 来引用变量

    具体示例如下:

      <script>
        let name = 'Tom';
        let age = 18;
        console.log('大家好, 我是新入职的' + name + ', 今年' + age + '岁了, 请多多关照'); //原始方式 , 手动拼接字符串
        console.log(`大家好, 我是新入职的${name}, 今年${age}岁了, 请多多关照`); //使用模板字符串方式拼接字符串
      </script>

     1.2.4 函数

    函数(function)是被设计用来执行特定任务的代码块,方便程序的封装复用。 那我们学习函数,主要就是学习JS中函数的定义及调用的语法。

    1.2.4.1 方式一(具名)

    格式如下:

    function 函数名(参数1,参数2..){
        要执行的代码
    }

    因为JavaScript是弱数据类型的语言,所以有如下几点需要注意:

    • 形参不需要声明类型,并且JS中不管什么类型都是let去声明,加上也没有意义。

    • 返回值也不需要声明类型,直接return即可

    示例:

    function add(a, b){
        return a + b;
    }

    如果要调用上述的函数add,可以使用:函数名称(实际参数列表) (如下代码):

    let result = add(10,20);
    alert(result);

    我们在调用add函数时,再添加2个参数,修改代码如下:

    let result = add(10,20,30,40);
    alert(result);

    浏览器打开,发现没有错误,并且依然弹出30,这是为什么呢?

    因为在JavaScript中,函数的调用只需要名称正确即可,参数列表不管的。如上述案例,10传递给了变量a,20传递给了变量b,而30和40没有变量接受,但是不影响函数的正常调用。

    注意:由于JS是弱类型语言,形参、返回值都不需要指定类型。在调用函数时,实参个数与形参个数可以不一致,但是建议一致。

     1.2.4.2 方式二(匿名)

    刚才我们定义函数,是为函数指定了一个名字。 那我们也可以不为函数指定名字,那这一类的函数,我们称之为匿名函数。那接下来,方式二,就来介绍一下匿名函数的定义和调用。

    匿名函数:是指一种没有名称的函数,由于它们没有名称,因此无法直接通过函数名来调用,而是通过变量或表达式来调用。

    匿名函数定义可以通过两种方式:函数表达式 和 箭头函数。

    • 示例一(函数表达式):

      let add = function (a,b){
          return a + b;
      }
    • 示例二(箭头函数):

      let add = (a,b) => {
          return a + b;
      }

      上述匿名函数声明好了之后,是将这个函数赋值给了add变量。 那我们就可以直接通过add函数直接调用,调用代码如下:

      let result = add(10,20);
      alert(result);

    1.2.4.3 自定义对象

    在 JavaScript 中自定义对象特别简单,其语法格式如下:

    let 对象名 = {
        属性名1: 属性值1,
        属性名2: 属性值2,
        属性名3: 属性值3,
        方法名称: function(形参列表){}
    };

    我们可以通过如下语法调用属性:

    对象名.属性名

    通过如下语法调用函数:

    对象名.方法名()

    示例代码如下: 

    <script>
        //自定义对象
        let user = {
            name: "Tom",
            age: 10,
            gender: "男",
            sing: function(){
                 console.log("悠悠的唱着最炫的民族风~");
             }
        }
    
        console.log(user.name);
        user.eat();
    <script>

     

    上述代码也可以简化为以下: 

    <script>
        //自定义对象
        let user = {
            name: "Tom",
            age: 10,
            gender: "男",
            sing(){
                 console.log("悠悠的唱着最炫的民族风~");
             }
        }
        
        console.log(user.name);
        user.eat();
    <script>
    1.2.4.4 josn 

    JSON对象:JavaScript Object Notation,JavaScript对象标记法。JSON是通过JavaScript标记法书写的文本。其格式如下:

    {
        "key":value,
        "key":value,
        "key":value
    }

    其中,key必须使用引号并且是双引号标记,value可以是任意数据类型。 

    而由于语法简单,层级结构鲜明,现多用于作为数据载体,在网络中进行数据传输。 

    JSON.stringify(...):作用就是将js对象,转换为json格式的字符串。

    JSON.parse(...):作用就是将json格式的字符串,转为js对象。

    示例代码如下:

    //3. JSON - JS对象标记法
    let person = {
      name: 'itcast',
      age: 18,
      gender: '男'
    }
    alert(JSON.stringify(person)); //js对象 --> json字符串
    
    let personJson = '{"name": "heima", "age": 18}';
    alert(JSON.parse(personJson).name);

     

     1.2.5 控制流程

     在JS中,当然也存在对应的流程控制语句。常见的流程控制语句如下:

    在JS中,当然也存在对应的流程控制语句。常见的流程控制语句如下:

    • if ... else if ... else ...

    • switch

    • for

    • while

    • do ... while

    而JS中的流程控制语句与JAVA中的流程控制语句的作用,执行机制都是一样的。

    1.2.6 JS DOM 

    1.2.6.1 介绍

    DOM:Document Object Model 文档对象模型。也就是 JavaScript 将 HTML 文档的各个组成部分封装为对象。

    DOM 其实我们并不陌生,之前在学习 XML 就接触过,只不过 XML 文档中的标签需要我们写代码解析,而 HTML 文档是浏览器解析。封装的对象分为

    • Document:整个文档对象

    • Element:元素对象

    • Attribute:属性对象

    • Text:文本对象

    • Comment:注释对象

    如下图,左边是 HTML 文档内容,右边是 DOM 树

    主要作用如下:

    • 改变 HTML 元素的内容

    • 改变 HTML 元素的样式(CSS)

    • 对 HTML DOM 事件作出反应

    • 添加和删除 HTML 元素

    1.2.6.2 DOM操作 
    • DOM的核心思想:将网页的内容当做对象来处理,标签的所有属性在该对象上都可以找到,并且修改这个对象的属性,就会自动映射到标签身上。

    • document对象

      • 网页中所有内容都封装在document对象中

      • 它提供的属性和方法都是用来访问和操作网页内容的,如:document.write(…)

    • DOM操作步骤:

      • 获取DOM元素对象

      • 操作DOM对象的属性或方法 (查阅文档)

    • 我们可以通过如下两种方式来获取DOM元素。

      • 根据CSS选择器来获取DOM元素,获取到匹配到的第一个元素:document.querySelector('CSS选择器');

      • 根据CSS选择器来获取DOM元素,获取匹配到的所有元素:document.querySelectorAll('CSS选择器');

    注意:获取到的所有元素,会封装到一个NodeList节点集合中,是一个伪数组(有长度、有索引的数组,但没有push、pop等数组方法)

    示例代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>JS-DOM</title>
    </head>
    <body>
    
      <h1 id="title1">11111</h1>
      <h1>22222</h1>
      <h1>33333</h1>
    
      <script>
        //1. 修改第一个h1标签中的文本内容
        //1.1 获取DOM对象
        // let h1 = document.querySelector('#title1');
        // 1.2 修改
         
        h1.innerHTML = '修改后的内容'
        //let h1 = document.querySelector('h1'); // 获取第一个h1标签
    
        let hs = document.querySelectorAll('h1');
    
        //1.2 调用DOM对象中属性或方法
        hs[0].innerHTML = '修改后的文本内容';
      </script>
    </body>
    </html>

    二、JS事件监听

    2.1 事件介绍

    什么是事件呢?HTML事件是发生在HTML元素上的 “事情”,例如:

    • 按钮被点击

    • 鼠标移到元素上

    • 输入框失去焦点

    • 按下键盘按键

    • ........

    而我们可以给这些事件绑定函数,当事件触发时,可以自动的完成对应的功能,这就是事件监听。

    例如:对于我们所说的百度注册页面,我们给用户名输入框的失去焦点事件绑定函数,当我们用户输入完内容,在标签外点击了鼠标,对于用户名输入框来说,失去焦点,然后执行绑定的函数,函数进行用户名内容的校验等操作。

    JS事件是JS非常重要的一部分,接下来我们进行事件的学习。那么我们对于JavaScript事件需要学习哪些内容呢?我们得知道有哪些常用事件,然后我们得学会如何给事件绑定函数。

    所以主要围绕2点来学习:①. 事件监听、②. 常用事件

    2.2 事件监听语法

    JS事件监听的语法:

    事件源.addEventListener('事件类型', 要执行的函数);

    在上述的语法中包含三个要素:

    • 事件源: 哪个dom元素触发了事件, 要获取dom元素

    • 事件类型: 用什么方式触发, 比如: 鼠标单击 click, 鼠标经过 mouseover

    • 要执行的函数: 要做什么事

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>JS事件</title>
    </head>
    <body>
      
      <input type="button" id="btn1" value="点我一下试试1">
      <input type="button" id="btn2" value="点我一下试试2">
    
      <script>
        //事件监听 - addEventListener (可以多次绑定同一事件)
        document.querySelector('#btn1').addEventListener('click', () => {
          console.log('试试就试试~~');
        });
        document.querySelector('#btn1').addEventListener('click', () => {
          console.log('试试就试试22~~');
        });
    
        //事件绑定-早期写法 - onclick (如果多次绑定同一事件, 覆盖) - 了解
        document.querySelector('#btn2').onclick =  () => {
          console.log('试试就试试~~');
        }
        document.querySelector('#btn2').onclick =  () => {
          console.log('试试就试试22~~');
        }
      </script>
    </body>
    </html>

    效果如下: 

    addEventListener 与 on事件 区别:

    • on方式会被覆盖,addEventListener 方式可以绑定多次,拥有更多特性,推荐使用 addEventListener .

    2.3 隔行换色案例

    需求:实现鼠标移入数据行时,背景色改为#f2e2e2,鼠标移出时,再将背景色改为白色。案例为前一章节(3.4.5)

     代码如下:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tlias智能学习辅助系统</title>
        <style>
          body {
            margin: 0;
          }
    
          /* 顶栏样式 */
          .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background-color: #c2c0c0;
            padding: 20px 20px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
          }
          
          /* 加大加粗标题 */
          .header h1 {
            margin: 0;
            font-size: 24px;
            font-weight: bold;
          }
    
          /* 文本链接样式 */
          .header a {
            text-decoration: none;
            color: #333;
            font-size: 16px;
          }
    
          /* 搜索表单区域 */
          .search-form {
            display: flex;
            align-items: center;
            padding: 20px;
            background-color: #f9f9f9;
          }
    
          /* 表单控件样式 */
          .search-form input[type="text"], .search-form select {
            margin-right: 10px;
            padding: 10px 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 26%;
          }
    
          /* 按钮样式 */
          .search-form button {
            padding: 10px 15px;
            margin-left: 10px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
          }
    
          /* 清空按钮样式 */
          .search-form button.clear {
            background-color: #6c757d;
          }
    
          .table {
             min-width: 100%; 
             border-collapse: collapse;
          }
    
          /* 设置表格单元格边框 */
          .table td, .table th { 
            border: 1px solid #ddd; 
            padding: 8px; 
            text-align: center;
          }
          
          .avatar { 
            width: 30px; 
            height: 30px; 
            object-fit: cover; 
            border-radius: 50%; 
          }
    
          /* 页脚版权区域 */
        .footer {
            background-color: #c2c0c0;
            color: white;
            text-align: center;
            padding: 10px 0;
            margin-top: 30px;
        }
    
        .footer .company-name {
            font-size: 1.1em;
            font-weight: bold;
        }
    
        .footer .copyright {
            font-size: 0.9em;
        }
    
        #container {
          width: 80%;
          margin: 0 auto;
        }
        </style>
    </head>
    <body>
        
      <div id="container">
        <!-- 顶栏 -->
        <div class="header">
          <h1>Tlias智能学习辅助系统</h1>
          <a href="#">退出登录</a>
        </div>
    
        <!-- 搜索表单区域 -->
        <form class="search-form" action="#" method="post">
          <input type="text" name="name" placeholder="姓名" />
          <select name="gender">
              <option value="">性别</option>
              <option value="1">男</option>
              <option value="2">女</option>
          </select>
          <select name="job">
              <option value="">职位</option>
              <option value="1">班主任</option>
              <option value="2">讲师</option>
              <option value="3">学工主管</option>
              <option value="4">教研主管</option>
              <option value="5">咨询师</option>
          </select>
          <button type="submit">查询</button>
          <button type="reset" class="clear">清空</button>
        </form>
    
        <table class="table table-striped table-bordered">
          <thead>
              <tr>
                  <th>姓名</th>
                  <th>性别</th>
                  <th>头像</th>
                  <th>职位</th>
                  <th>入职日期</th>
                  <th>最后操作时间</th>
                  <th>操作</th>
              </tr>
          </thead>
          <tbody>
            <tr>
                <td>令狐冲</td>
                <td>男</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="令狐冲" class="avatar"></td>
                <td>讲师</td>
                <td>2021-03-15</td>
                <td>2023-07-30T12:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
                <td>任盈盈</td>
                <td>女</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="任盈盈" class="avatar"></td>
                <td>学工主管</td>
                <td>2020-04-10</td>
                <td>2023-07-29T15:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
                <td>岳不群</td>
                <td>男</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="岳不群" class="avatar"></td>
                <td>教研主管</td>
                <td>2019-01-01</td>
                <td>2023-07-30T10:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
                <td>宁中则</td>
                <td>女</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="宁中则" class="avatar"></td>
                <td>班主任</td>
                <td>2018-06-01</td>
                <td>2023-07-29T09:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
              <td>令狐冲</td>
              <td>男</td>
              <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="令狐冲" class="avatar"></td>
              <td>讲师</td>
              <td>2021-03-15</td>
              <td>2023-07-30T12:00:00Z</td>
              <td class="btn-group">
                  <button class="edit">编辑</button>
                  <button class="delete">删除</button>
              </td>
            </tr>
            <tr>
                <td>任盈盈</td>
                <td>女</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="任盈盈" class="avatar"></td>
                <td>学工主管</td>
                <td>2020-04-10</td>
                <td>2023-07-29T15:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
                <td>岳不群</td>
                <td>男</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="岳不群" class="avatar"></td>
                <td>教研主管</td>
                <td>2019-01-01</td>
                <td>2023-07-30T10:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
                <td>宁中则</td>
                <td>女</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="宁中则" class="avatar"></td>
                <td>班主任</td>
                <td>2018-06-01</td>
                <td>2023-07-29T09:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
              <td>令狐冲</td>
              <td>男</td>
              <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="令狐冲" class="avatar"></td>
              <td>讲师</td>
              <td>2021-03-15</td>
              <td>2023-07-30T12:00:00Z</td>
              <td class="btn-group">
                  <button class="edit">编辑</button>
                  <button class="delete">删除</button>
              </td>
            </tr>
            <tr>
                <td>任盈盈</td>
                <td>女</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="任盈盈" class="avatar"></td>
                <td>学工主管</td>
                <td>2020-04-10</td>
                <td>2023-07-29T15:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
                <td>岳不群</td>
                <td>男</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="岳不群" class="avatar"></td>
                <td>教研主管</td>
                <td>2019-01-01</td>
                <td>2023-07-30T10:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
            <tr>
                <td>宁中则</td>
                <td>女</td>
                <td><img src="https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg" alt="宁中则" class="avatar"></td>
                <td>班主任</td>
                <td>2018-06-01</td>
                <td>2023-07-29T09:00:00Z</td>
                <td class="btn-group">
                    <button class="edit">编辑</button>
                    <button class="delete">删除</button>
                </td>
            </tr>
          </tbody>
        </table>
    
        <!-- 页脚版权区域 -->
        <footer class="footer">
          <p class="company-name">橙序研</p>
          <p class="copyright">版权所有 Copyright</p>
        </footer>
    
        <script>
          //点击列表中每一条记录后面的删除按钮,弹出一个提示框,提示:您是否要删除这条记录? 如果确定,则移出这条记录
          const deleteButtons = document.querySelectorAll('.delete');
          for (let i = 0; i < deleteButtons.length; i++) {
            deleteButtons[i].addEventListener('click', function () {
              if (confirm('您是否要删除这条记录?')) {
                //点击确定按钮,删除当前记录
                this.parentNode.parentNode.remove();
              }
            });
          }
          
          //通过js实现鼠标移入移出效果,鼠标移入,背景色为 #f2e2e2,鼠标移出,背景色为 白色。
          const trs = document.querySelectorAll('tr');
          for (let i = 1; i < trs.length; i++) {
            trs[i].addEventListener('mouseenter', function () {
              this.style.backgroundColor = '#f2e2e2';
            });
            trs[i].addEventListener('mouseleave', function () {
              this.style.backgroundColor = '#fff';
            });
          }
        </script>
        
      </div>
        
    </body>
    </html>

    2.4 常见事件 

    上面案例中使用到了事件 clickmouseentermouseleave,那都有哪些事件类型供我们使用呢?下面就给大家列举一些比较常用的事件属性:

    <!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>JS-事件-常见事件</title>
    </head>
    
    <body>
        <form action="" style="text-align: center;">
            <input type="text" name="username" id="username">
            <input type="text" name="age" id="age">
            <input id="b1" type="submit" value="提交">
            <input id="b2" type="button" value="单击事件">
        </form>
    
        <br><br><br>
    
        <table width="800px" border="1" cellspacing="0" align="center">
            <tr>
                <th>学号</th>
                <th>姓名</th>
                <th>分数</th>
                <th>评语</th>
            </tr>
            <tr align="center">
                <td>001</td>
                <td>张三</td>
                <td>90</td>
                <td>很优秀</td>
            </tr>
            <tr align="center" id="last">
                <td>002</td>
                <td>李四</td>
                <td>92</td>
                <td>优秀</td>
            </tr>
        </table>
        
        <script>
            //click: 鼠标点击事件
            document.querySelector('#b2').addEventListener('click', () => {
                console.log("我被点击了...");
            })
            
            //mouseenter: 鼠标移入
            document.querySelector('#last').addEventListener('mouseenter', () => {
                console.log("鼠标移入了...");
            })
    
            //mouseleave: 鼠标移出
            document.querySelector('#last').addEventListener('mouseleave', () => {
                console.log("鼠标移出了...");
            })
    
            //keydown: 某个键盘的键被按下
            document.querySelector('#username').addEventListener('keydown', () => {
                console.log("键盘被按下了...");
            })
    
            //keydown: 某个键盘的键被抬起
            document.querySelector('#username').addEventListener('keyup', () => {
                console.log("键盘被抬起了...");
            })
    
            //blur: 失去焦点事件
            document.querySelector('#age').addEventListener('blur', () => {
                console.log("失去焦点...");
            })
    
            //focus: 元素获得焦点
            document.querySelector('#age').addEventListener('focus', () => {
                console.log("获得焦点...");
            })
    
            //input: 用户输入时触发
            document.querySelector('#age').addEventListener('input', () => {
                console.log("用户输入时触发...");
            })
    
            //submit: 提交表单事件
            document.querySelector('form').addEventListener('submit', () => {
                alert("表单被提交了...");
            })
        </script>
    </body>
    
    </html>

    代码的优化:

    主代码如下:

    <!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>JS-事件-常见事件</title>
    </head>
    
    <body>
        <form action="" style="text-align: center;">
            <input type="text" name="username" id="username">
            <input type="text" name="age" id="age">
            <input id="b1" type="submit" value="提交">
            <input id="b2" type="button" value="单击事件">
        </form>
    
        <br><br><br>
    
        <table width="800px" border="1" cellspacing="0" align="center">
            <tr>
                <th>学号</th>
                <th>姓名</th>
                <th>分数</th>
                <th>评语</th>
            </tr>
            <tr align="center">
                <td>001</td>
                <td>张三</td>
                <td>90</td>
                <td>很优秀</td>
            </tr>
            <tr align="center" id="last">
                <td>002</td>
                <td>李四</td>
                <td>92</td>
                <td>优秀</td>
            </tr>
        </table>
        
        <!-- type="module" 模块化JS -->
        <script src="./js/eventDemo.js" type="module"></script>
    </body>
    
    </html>

     eventDemo.js 代码如下:
     

    import { printLog } from "./utils.js";
    
    //click: 鼠标点击事件
    document.querySelector('#b2').addEventListener('click', () => {
        printLog("我被点击了...");
    })
    
    //mouseenter: 鼠标移入
    document.querySelector('#last').addEventListener('mouseenter', () => {
        printLog("鼠标移入了...");
    })
    
    //mouseleave: 鼠标移出
    document.querySelector('#last').addEventListener('mouseleave', () => {
        printLog("鼠标移出了...");
    })
    
    //keydown: 某个键盘的键被按下
    document.querySelector('#username').addEventListener('keydown', () => {
        printLog("键盘被按下了...");
    })
    
    //keyup: 某个键盘的键被抬起
    document.querySelector('#username').addEventListener('keyup', () => {
        printLog("键盘被抬起了...");
    })
    
    //blur: 失去焦点事件
    document.querySelector('#age').addEventListener('blur', () => {
        printLog("失去焦点...");
    })
    
    //focus: 元素获得焦点
    document.querySelector('#age').addEventListener('focus', () => {
        printLog("获得焦点...");
    })
    
    //input: 用户输入时触发
    document.querySelector('#age').addEventListener('input', () => {
      printLog("用户输入时触发...");
    })
    
    //submit: 提交表单事件
    document.querySelector('form').addEventListener('submit', () => {
        alert("表单被提交了...");
    })

    utils.js 代码如下 

    export function printLog(msg){
      console.log(msg);
    }

    三、Vue介绍

    3.1 概述

    是一款用于构建用户界面渐进式的JavaScript框架官方网站:https://cn.vuejs.org)

    1). 构建用户界面

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

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

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

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

    2). 渐进式

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

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

    • 我们学习了声明式渲染,我们就可以使用Vue来构建用户界面了。

    • 我们再学习了组件系统,我们就可以使用Vue中的组件,从而来复用了。

    • 我们再学习了路由VueRouter,就可以使用Vue中的中的路由功能了。

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

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

    • 基于Vue提供的核心包,完成项目局部模块的改造了。

    • 基于Vue提供的核心包、插件进行工程化开发,也就是做整站开发。

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

    3). 框架

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

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

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

    3.2 入门程序

    3.2.1 需求

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

    3.2.2 步骤 

    1). 准备工作:

    • 准备一个html文件,并在其中引入Vue模块 (参考官方文档,复制过来即可)【注意:模块化的js,引入时,需要设置 type="module"

    • 创建Vue程序的应用实例,控制视图的元素

    • 准备元素(div),交给Vue控制

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

    2). 数据驱动视图:

    • 准备数据。 在创建Vue应用实例的时候,传入了一个js对象,在这个js对象中,我们要定义一个data方法,这个data方法的返回值就是Vue中的数据。

    • 通过插值表达式渲染页面。 插值表达式的写法:{{...}}

    3.2.3 实现 

    代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Vue-快速入门</title>
    </head>
    <body>
      
      <div id="app">
        <h1>{{message}}</h1>
        <h1>{{count}}</h1>
      </div>
      
    
      <script type="module">
        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
    
        createApp({
          data() {
            return {
              message: 'Hello Vue',
              count: 100
            }
          }
        }).mount('#app');
      </script>
    </body>
    </html>

    在上述入门程序编写时,需要注意这么几点:

    • Vue中定义数据,必须通过data方法来定义,data方法返回值是一个对象,在这个对象中定义数据。

    • 插值表达式中编写的变量,一定是Vue中定义的数据,如果插值表达式中编写了一个变量,但是在Vue中未定义,将会报错 。

    • Vue应用实例接管的区域是 '#app',超出这个范围,就不受Vue控制了,所以vue的插值表达式,一定写在 <div id="app">...</div> 的里面 。

    四、Vue指令

    4.1 概述

    指令:指的是HTML 标签上带有 v- 前缀的特殊属性,不同指令具有不同含义,可以实现不同的功能 。例如:v-if,v-for…

    形式:

    <p v-xxx="....">.....</p>

     常见指令:

    4.2 案例

    4.2.1 基本实现

    需求:员工列表数据渲染展示 。

    4.2.2 指令详解

    代码如下:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Tlias智能学习辅助系统</title>
        <style>
            /* 导航栏样式 */
            .navbar {
                background-color: #b5b3b3; /* 灰色背景 */
                
                display: flex; /* flex弹性布局 */
                justify-content: space-between; /* 左右对齐 */
    
                padding: 10px; /* 内边距 */
                align-items: center; /* 垂直居中 */
            }
            .navbar h1 {
                margin: 0; /* 移除默认的上下外边距 */
                font-weight: bold; /* 加粗 */
                color: white;
                /* 设置字体为楷体 */
                font-family: "楷体";
            }
            .navbar a {
                color: white; /* 链接颜色为白色 */
                text-decoration: none; /* 移除下划线 */
            }
    
            /* 搜索表单样式 */
            .search-form {
                display: flex;
                flex-wrap: nowrap;
                align-items: center;
                gap: 10px; /* 控件之间的间距 */
                margin: 20px 0;
            }
            .search-form input[type="text"], .search-form select {
                padding: 5px; /* 输入框内边距 */
                width: 260px; /* 宽度 */
            }
            .search-form button {
                padding: 5px 15px; /* 按钮内边距 */
            }
    
            /* 表格样式 */
            table {
                width: 100%;
                border-collapse: collapse;
            }
            th, td {
                border: 1px solid #ddd; /* 边框 */
                padding: 8px; /* 单元格内边距 */
                text-align: center; /* 左对齐 */
            }
            th {
                background-color: #f2f2f2;
                font-weight: bold;
            }
            .avatar {
                width: 30px;
                height: 30px;
            }
    
            /* 页脚样式 */
            .footer {
                background-color: #b5b3b3; /* 灰色背景 */
                color: white; /* 白色文字 */
                text-align: center; /* 居中文本 */
                padding: 10px 0; /* 上下内边距 */
                margin-top: 30px;
            }
    
            #container {
                width: 80%; /* 宽度为80% */
                margin: 0 auto; /* 水平居中 */
            }
        </style>
    </head>
    <body>
        <div id="container">
            <!-- 顶部导航栏 -->
            <div class="navbar">
                <h1>Tlias智能学习辅助系统</h1>
                <a href="#">退出登录</a>
            </div>
            
            <!-- 搜索表单区域 -->
    
            <!-- 就是说在搜索栏输入后,由于v-model的双向绑定,会将输入的值实时更新到searchForm对象的name属性中,
            又因为data方法中的return,也就是可以通过对象调用来得到用户输入的值 -->
    
            <form class="search-form">
                <label for="name">姓名:</label>
                <input type="text" id="name" name="name" v-model="searchForm.name" placeholder="请输入姓名">
    
                <label for="gender">性别:</label>
                <select id="gender" name="gender" v-model="searchForm.gender">
                    <option value=""></option>
                    <option value="1">男</option>
                    <option value="2">女</option>
                </select>
    
                <label for="position">职位:</label>
                <select id="position" name="position" v-model="searchForm.job">
                    <option value=""></option>
                    <option value="1">班主任</option>
                    <option value="2">讲师</option>
                    <option value="3">学工主管</option>
                    <option value="4">教研主管</option>
                    <option value="5">咨询师</option>
                </select>
    
                <button type="button" v-on:click="search">查询</button>
                <button type="button" @click="clear">清空</button>
            </form>
    
    
            <!-- 表格展示区 -->
            <table>
                <!-- 表头 -->
                <thead>
                    <tr>
                        <th>序号</th>
                        <th>姓名</th>
                        <th>性别</th>
                        <th>头像</th>
                        <th>职位</th>
                        <th>入职日期</th>
                        <th>最后操作时间</th>
                        <th>操作</th>
                    </tr>
                </thead>
    
                <!-- 表格主体内容 -->
                <tbody>
                    <tr v-for="(e, index) in empList" :key="e.id">
                        <td>{{index + 1}}</td>
                        <td>{{e.name}}</td>
                        <td>{{e.gender == 1?'男' : '女'}}</td>
    
                        <!-- 插值表达式是不能出现在标签内部 -->
                        <td><img class="avatar"  v-bind:src="e.image" :alt="e.name"></td>
    
                        <!-- v-if: 控制元素的显示与隐藏 -->
                        <td>
                            <span v-if="e.job == 1">班主任</span>
                            <span v-else-if="e.job == 2">讲师</span>
                            <span v-else-if="e.job == 3">学工主管</span>
                            <span v-else-if="e.job == 4">教研主管</span>
                            <span v-else-if="e.job == 5">咨询师</span>
                            <span v-else>其他</span>
                        </td>
    
                        <!-- v-show: 控制元素的显示与隐藏 -->
                        <!-- <td>
                            <span v-show="e.job == 1">班主任</span>
                            <span v-show="e.job == 2">讲师</span>
                            <span v-show="e.job == 3">学工主管</span>
                            <span v-show="e.job == 4">教研主管</span>
                            <span v-show="e.job == 5">咨询师</span>
                        </td> -->
    
                        <td>{{e.entrydate}}</td>
                        <td>{{e.updatetime}}</td>
                        <td class="action-buttons">
                            <button type="button">编辑</button>
                            <button type="button">删除</button>
                        </td>
                    </tr>
                </tbody>
            </table>
    
            <!-- 页脚版权区域 -->
            <footer class="footer">
                <p>橙序研</p>
                <p>版权所有 Copyright </p>
            </footer>
        </div>
        
    
        <script type="module">
          import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
    
          createApp({
            data() {
              return {
                searchForm: { //封装用户输入的查询条件
                    name: '',
                    gender: '',
                    job: ''
                },
                empList: [
                  { "id": 1,
                    "name": "谢逊",
                    "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/4.jpg",
                    "gender": 1,
                    "job": "1",
                    "entrydate": "2023-06-09",
                    "updatetime": "2024-09-30T14:59:38"
                  },
                  {
                    "id": 2,
                    "name": "韦一笑",
                    "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg",
                    "gender": 1,
                    "job": "1",
                    "entrydate": "2020-05-09",
                    "updatetime": "2024-09-01T00:00:00"
                  },
                  {
                    "id": 3,
                    "name": "黛绮丝",
                    "image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/2.jpg",
                    "gender": 2,
                    "job": "2",
                    "entrydate": "2021-06-01",
                    "updatetime": "2024-09-01T00:00:00"
                  }
                ]
              }
            },
            //方法
            methods: {
                search(){
                    //将搜索条件, 输出到控制台
                    console.log(this.searchForm);
                },
                clear(){
                    //清空表单项数据
                    this.searchForm = {name:'', gender:'', job:''}
                }
            },
          }).mount('#container')
        </script>
    
    </body>
    </html>

    4.2.2.1 v-for

    作用:列表渲染,遍历容器的元素或者对象的属性

    语法:<tr v-for="(item,index) in items" :key="item.id">{{item}}</tr>

    参数:

    • items 为遍历的数组

    • item 为遍历出来的元素

    • index 为索引/下标,从0开始 ;可以省略,省略index语法: v-for = "item in items"

    key:

    • 作用:给元素添加的唯一标识,便于vue进行列表项的正确排序复用,提升渲染性能

    • 推荐使用id作为key(唯一),不推荐使用index作为key(会变化,不对应)

    注意:遍历的数组,必须在data中定义; 要想让哪个标签循环展示多次,就在哪个标签上使用 v-for 指令。 

    4.2.2.2 v-bind

    作用:动态为HTML标签绑定属性值,如设置href,src,style样式等。

    语法:v-bind:属性名="属性值" <img v-bind:src="item.image" width="30px">

    简化::属性名="属性值" <img :src="item.image" width="30px">

    注意:v-bind 所绑定的数据,必须在data中定义/或基于data中定义的数据而来。 

    4.2.2.3 v-if & v-show 

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

    • 语法:v-if="表达式",表达式值为 true,显示;false,隐藏

    • 原理:基于条件判断,来控制创建或移除元素节点(条件渲染)

    • 场景:要么显示,要么不显示,不频繁切换的场景

    • 其它:可以配合 v-else-if / v-else 进行链式调用条件判断

    示例代码:

       <!-- 基于v-if/v-else-if/v-else指令来展示职位这一列 -->
      <td>
        <span v-if="emp.job === '1'">班主任</span>
        <span v-else-if="emp.job === '2'">讲师</span>
        <span v-else-if="emp.job === '3'">学工主管</span>
        <span v-else-if="emp.job === '4'">教研主管</span>
        <span v-else-if="emp.job === '5'">咨询师</span>
        <span v-else>其他</span>
      </td>

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

    v-show:

    • 语法:v-show="表达式",表达式值为 true,显示;false,隐藏

    • 原理:基于CSS样式display来控制显示与隐藏

    • 场景:频繁切换显示隐藏的场景

    <!-- 基于v-show指令来展示职位这一列 -->
    <td>
        <span v-show="emp.job === '1'">班主任</span>
        <span v-show="emp.job === '2'">讲师</span>
        <span v-show="emp.job === '3'">学工主管</span>
        <span v-show="emp.job === '4'">教研主管</span>
        <span v-show="emp.job === '5'">咨询师</span>
    </td>
     4.2.2.4 v-model
    • 作用:在表单元素上使用,双向数据绑定。可以方便的 获取设置 表单项数据

    • 语法:v-model="变量名"

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

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

     4.2.2.5 v-on

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

    语法:

    • v-on:事件名="方法名"

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

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

    • <input type="button" value="点我一下试试" @click="handle">

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

    五、Ajax

    5.1 概述

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

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

    • 与服务器进行数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。

    • 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等。

    解释一下Ajax技术的2个作用:

    • 与服务器进行数据交互

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

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

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

    XML:(英语:Extensible Markup Language)可扩展标记语言,本质是一种数据格式,可以用来存储复杂的数据结构。

    5.2 同步异步

    针对于上述Ajax的局部刷新功能是因为Ajax请求是异步的,与之对应的有同步请求。接下来我们介绍一下异步请求和同步请求的区别。 

    • 同步请求发送过程如下图所示:

     浏览器页面在发送请求给服务器,在服务器处理请求的过程中,浏览器页面不能做其他的操作。只能等到服务器响应结束后才能,浏览器页面才能继续做其他的操作。

    • 异步请求发送过程如下图所示:

    浏览器页面发送请求给服务器,在服务器处理请求的过程中,浏览器页面还可以做其他的操作。 

    5.3 Axios 

    使用原生的Ajax请求的代码编写起来还是比较繁琐的,所以接下来我们学习一门更加简单的发送Ajax请求的技术Axios 。Axios是对原生的AJAX进行封装,简化书写。Axios官网是:https://www.axios-http.cn

     

    5.3.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>Ajax-Axios</title>
    </head>
    <body>
        
        <input type="button" value="获取数据GET" id="btnGet">
        <input type="button" value="操作数据POST" id="btnPost">
    
        <script src="js/axios.js"></script>
        <script>
            //发送GET请求
            document.querySelector('#btnGet').addEventListener('click', () => {
                //axios发起异步请求
                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发起异步请求
                axios({
                    url: 'https://mock.apifox.cn/m1/3083103-0-default/emps/update',
                    method: 'POST',
                    data: 'id=1' //POST请求方式 , 请求体
                }).then((result) => { //成功回调函数
                    console.log(result.data);
                }).catch((err) => { //失败回调函数
                    console.log(err);
                })
            })
        </script>
    </body>
    </html>

    5.3.2 请求方法别名

    Axios还针对不同的请求,提供了别名方式的api,具体格式如下:

    axios.请求方式(url [, data [, config]])

    具体如下:

     我们目前只关注get和post请求,所以在上述的入门案例中,我们可以将get请求代码改写成如下:

    axios.get("https://mock.apifox.cn/m1/3083103-0-default/emps/list").then(result => {
        console.log(result.data);
    })

    post请求改写成如下:

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

    总代码如下:

    <!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="js/axios.js"></script>
        <script>
            //发送GET请求
            document.querySelector('#btnGet').addEventListener('click', () => {
                axios.get('https://mock.apifox.cn/m1/3083103-0-default/emps/list').then((result) => {
                    console.log(result.data);
                });
                console.log('==========================');
            })
            
            //发送POST请求
            document.querySelector('#btnPost').addEventListener('click', () => {
                axios.post('https://mock.apifox.cn/m1/3083103-0-default/emps/update', 'id=1').then((result) => {
                    console.log(result.data);
                });
            })
        </script>
    </body>
    </html>

    5.4 案例-异步获取数据

    需求:基于axios动态加载员工列表数据

    具体代码实现如下:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tlias智能学习辅助系统</title>
        <style>
          body {
            margin: 0;
          }
    
          /* 顶栏样式 */
          .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            background-color: #c2c0c0;
            padding: 20px 20px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
          }
          
          /* 加大加粗标题 */
          .header h1 {
            margin: 0;
            font-size: 24px;
            font-weight: bold;
          }
    
          /* 文本链接样式 */
          .header a {
            text-decoration: none;
            color: #333;
            font-size: 16px;
          }
    
          /* 搜索表单区域 */
          .search-form {
            display: flex;
            align-items: center;
            padding: 20px;
            background-color: #f9f9f9;
          }
    
          /* 表单控件样式 */
          .search-form input[type="text"], .search-form select {
            margin-right: 10px;
            padding: 10px 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 26%;
          }
    
          /* 按钮样式 */
          .search-form button {
            padding: 10px 15px;
            margin-left: 10px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
          }
    
          /* 清空按钮样式 */
          .search-form button.clear {
            background-color: #6c757d;
          }
    
          .table {
             min-width: 100%; 
             border-collapse: collapse;
          }
    
          /* 设置表格单元格边框 */
          .table td, .table th { 
            border: 1px solid #ddd; 
            padding: 8px; 
            text-align: center;
          }
          
          .avatar { 
            width: 30px; 
            height: 30px; 
            object-fit: cover; 
            border-radius: 50%; 
          }
    
          /* 页脚版权区域 */
        .footer {
            background-color: #c2c0c0;
            color: white;
            text-align: center;
            padding: 10px 0;
            margin-top: 30px;
        }
    
        .footer .company-name {
            font-size: 1.1em;
            font-weight: bold;
        }
    
        .footer .copyright {
            font-size: 0.9em;
        }
    
        #container {
          width: 80%;
          margin: 0 auto;
        }
        </style>
    </head>
    <body>
        
      <div id="container">
        <!-- 顶栏 -->
        <div class="header">
          <h1>Tlias智能学习辅助系统</h1>
          <a href="#">退出登录</a>
        </div>
        
        <!-- 搜索表单区域 -->
        <form class="search-form">
          <input type="text" name="name" placeholder="姓名" v-model="searchForm.name" />
          <select name="gender" v-model="searchForm.gender">
              <option value="">性别</option>
              <option value="1">男</option>
              <option value="2">女</option>
          </select>
          <select name="job" v-model="searchForm.job">
              <option value="">职位</option>
              <option value="1">班主任</option>
              <option value="2">讲师</option>
              <option value="3">学工主管</option>
              <option value="4">教研主管</option>
              <option value="5">咨询师</option>
          </select>
          <button type="button" @click="search">查询</button>
          <button type="button" @click="clear">清空</button>
        </form>
    
        <table class="table table-striped table-bordered">
          <thead>
              <tr>
                  <th>姓名</th>
                  <th>性别</th>
                  <th>头像</th>
                  <th>职位</th>
                  <th>入职日期</th>
                  <th>最后操作时间</th>
                  <th>操作</th>
              </tr>
          </thead>
          <tbody>
            <tr v-for="(emp, index) in empList" :key="index">
              <td>{{ emp.name }}</td>
              <td>{{ emp.gender === 1 ? '男' : '女' }}</td>
              <td><img :src="emp.image" alt="{{ emp.name }}" class="avatar"></td>
              
               <!-- 基于v-if/v-else-if/v-else指令来展示职位这一列 -->
              <td>
                <span v-if="emp.job == '1'">班主任</span>
                <span v-else-if="emp.job == '2'">讲师</span>
                <span v-else-if="emp.job == '3'">学工主管</span>
                <span v-else-if="emp.job == '4'">教研主管</span>
                <span v-else-if="emp.job == '5'">咨询师</span>
                <span v-else>其他</span>
              </td>
    
              <!-- 基于v-show指令来展示职位这一列 -->
              <!-- <td>
                <span v-show="emp.job === '1'">班主任</span>
                <span v-show="emp.job === '2'">讲师</span>
                <span v-show="emp.job === '3'">学工主管</span>
                <span v-show="emp.job === '4'">教研主管</span>
                <span v-show="emp.job === '5'">咨询师</span>
             </td> -->
    
              <td>{{ emp.entrydate }}</td>
              <td>{{ emp.updatetime }}</td>
              <td class="btn-group">
                <button class="edit">编辑</button>
                <button class="delete">删除</button>
              </td>
            </tr>
          </tbody>
        </table>
    
        <!-- 页脚版权区域 -->
        <footer class="footer">
          <p class="company-name">橙序研</p>
          <p class="copyright">版权所有 Copyright </p>
        </footer>
    
        <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 {
                searchForm: {
                  name: '',
                  gender: '',
                  job: ''
                },
                empList: []
              }
            },
            methods: {
              search() {
                //基于axios发送异步请求,请求https://web-server.itheima.net/emps/list,根据条件查询员工列表
                axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`).then(res => {
                  this.empList = res.data.data
                })
              },
              clear() {
                this.searchForm= {
                  name: '',
                  gender: '',
                  job: ''
                }
              }
            }
          }).mount('#container')
        </script>
    
      </div>
    
    </body>
    </html>

    如果使用axios中提供的.then(function(){....}).catch(function(){....}),这种回调函数的写法,会使得代码的可读性和维护性变差。 而为了解决这个问题,我们可以使用两个关键字,分别是:async、await

    可以通过async、await可以让异步变为同步操作。async就是来声明一个异步方法,await是用来等待异步任务执行。

    代码修改前:

    search() {
        //基于axios发送异步请求,请求https://web-server.itheima.net/emps/list,根据条件查询员工列表
        axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`).then(res => {
          this.empList = res.data.data
        })
      },

    代码修改后:

      async search() {
        //基于axios发送异步请求,请求https://web-server.itheima.net/emps/list,根据条件查询员工列表
        const result = await axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`);
        this.empList = result.data.data;
      },

    修改后,代码就变成同步操作了,一行一行的从前往后执行。 在前端项目开发中,经常使用这两个关键字配合,使得代码的可读性和可维护性变高 

    六、Vue生命周期

    6.1 介绍

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

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

    6.2 案例演示

    代码如下:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Tlias智能学习辅助系统</title>
        <style>
            /* 导航栏样式 */
            .navbar {
                background-color: #b5b3b3; /* 灰色背景 */
                
                display: flex; /* flex弹性布局 */
                justify-content: space-between; /* 左右对齐 */
    
                padding: 10px; /* 内边距 */
                align-items: center; /* 垂直居中 */
            }
            .navbar h1 {
                margin: 0; /* 移除默认的上下外边距 */
                font-weight: bold; /* 加粗 */
                color: white;
                /* 设置字体为楷体 */
                font-family: "楷体";
            }
            .navbar a {
                color: white; /* 链接颜色为白色 */
                text-decoration: none; /* 移除下划线 */
            }
    
            /* 搜索表单样式 */
            .search-form {
                display: flex;
                flex-wrap: nowrap;
                align-items: center;
                gap: 10px; /* 控件之间的间距 */
                margin: 20px 0;
            }
            .search-form input[type="text"], .search-form select {
                padding: 5px; /* 输入框内边距 */
                width: 260px; /* 宽度 */
            }
            .search-form button {
                padding: 5px 15px; /* 按钮内边距 */
            }
    
            /* 表格样式 */
            table {
                width: 100%;
                border-collapse: collapse;
            }
            th, td {
                border: 1px solid #ddd; /* 边框 */
                padding: 8px; /* 单元格内边距 */
                text-align: center; /* 左对齐 */
            }
            th {
                background-color: #f2f2f2;
                font-weight: bold;
            }
            .avatar {
                width: 30px;
                height: 30px;
            }
    
            /* 页脚样式 */
            .footer {
                background-color: #b5b3b3; /* 灰色背景 */
                color: white; /* 白色文字 */
                text-align: center; /* 居中文本 */
                padding: 10px 0; /* 上下内边距 */
                margin-top: 30px;
            }
    
            #container {
                width: 80%; /* 宽度为80% */
                margin: 0 auto; /* 水平居中 */
            }
        </style>
    </head>
    <body>
        <div id="container">
            <!-- 顶部导航栏 -->
            <div class="navbar">
                <h1>Tlias智能学习辅助系统</h1>
                <a href="#">退出登录</a>
            </div>
            
            <!-- 搜索表单区域 -->
            <form class="search-form">
                <label for="name">姓名:</label>
                <input type="text" id="name" name="name" v-model="searchForm.name" placeholder="请输入姓名">
    
                <label for="gender">性别:</label>
                <select id="gender" name="gender" v-model="searchForm.gender">
                    <option value=""></option>
                    <option value="1">男</option>
                    <option value="2">女</option>
                </select>
    
                <label for="position">职位:</label>
                <select id="position" name="position" v-model="searchForm.job">
                    <option value=""></option>
                    <option value="1">班主任</option>
                    <option value="2">讲师</option>
                    <option value="3">学工主管</option>
                    <option value="4">教研主管</option>
                    <option value="5">咨询师</option>
                </select>
    
                <button type="button" v-on:click="search">查询</button>
                <button type="button" @click="clear">清空</button>
            </form>
    
    
            <!-- 表格展示区 -->
            <table>
                <!-- 表头 -->
                <thead>
                    <tr>
                        <th>序号</th>
                        <th>姓名</th>
                        <th>性别</th>
                        <th>头像</th>
                        <th>职位</th>
                        <th>入职日期</th>
                        <th>最后操作时间</th>
                        <th>操作</th>
                    </tr>
                </thead>
    
                <!-- 表格主体内容 -->
                <tbody>
                    <tr v-for="(e, index) in empList" :key="e.id">
                        <td>{{index + 1}}</td>
                        <td>{{e.name}}</td>
                        <td>{{e.gender == 1?'男' : '女'}}</td>
    
                        <!-- 插值表达式是不能出现在标签内部 -->
                        <td><img class="avatar"  v-bind:src="e.image" :alt="e.name"></td>
    
                        <!-- v-if: 控制元素的显示与隐藏 -->
                        <td>
                            <span v-if="e.job == 1">班主任</span>
                            <span v-else-if="e.job == 2">讲师</span>
                            <span v-else-if="e.job == 3">学工主管</span>
                            <span v-else-if="e.job == 4">教研主管</span>
                            <span v-else-if="e.job == 5">咨询师</span>
                            <span v-else>其他</span>
                        </td>
    
                        <!-- v-show: 控制元素的显示与隐藏 -->
                        <!-- <td>
                            <span v-show="e.job == 1">班主任</span>
                            <span v-show="e.job == 2">讲师</span>
                            <span v-show="e.job == 3">学工主管</span>
                            <span v-show="e.job == 4">教研主管</span>
                            <span v-show="e.job == 5">咨询师</span>
                        </td> -->
    
                        <td>{{e.entrydate}}</td>
                        <td>{{e.updatetime}}</td>
                        <td class="action-buttons">
                            <button type="button">编辑</button>
                            <button type="button">删除</button>
                        </td>
                    </tr>
                </tbody>
            </table>
    
            <!-- 页脚版权区域 -->
            <footer class="footer">
                <p>橙序研</p>
                <p>版权所有 Copyright </p>
            </footer>
        </div>
        
        <script src="js/axios.js"></script>
        <script type="module">
          import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
    
          createApp({
            data() {
              return {
                searchForm: { //封装用户输入的查询条件
                    name: '',
                    gender: '',
                    job: ''
                },
                empList: []
              }
            },
            //方法
            methods: {
                async search(){
                    // 发送ajax请求,获取数据
                    // axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`).then((result) => {
                    //     this.empList = result.data.data;
                    // })
                    // console.log('===========================');
    
                    let result = await axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`);
                    this.empList = result.data.data;
                },
                clear(){
                    //清空表单项数据
                    this.searchForm = {name:'', gender:'', job:''}
                    this.search()
                }
            },
            //钩子函数
            mounted(){
                //页面加载完成之后,发送ajax请求,获取数据
                this.search()
            }
          }).mount('#container')
        </script>
    
    </body>
    </html>

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值