Ajax&Vue

1、Ajax

1.1、概述

  • AJAX(Asynchronous JavaScript And XML):异步的JavaScript和XML
  • 作用
    • 1.与服务器进行数据交换:通过ajax可以给服务器发送请求,服务器将数据直接响应回给浏览器。
      • 如图是没使用Ajax的时候,各个请求之间的流程
        • Servlet调用完业务逻辑层后将数据存储到域对象中,然后跳转到指定的JSP页面,在页面上使用EL表达式和JSTL标签库进行数据的展示
      • 在学习Ajax后,就可以使用Ajax和服务器进行通信,以达到使用HTML+Ajax来替代JSP页面
        • 在上图中,浏览器发送请求给Servlet,Servlet调用完业务逻辑层后将数据直接响应回给浏览器页面,页面使用HTML来进行数据展示
    • 2.进行异步交互:可以在不重新加载整个页面的情况下(局部刷新),与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用校验,等等

1.2、同步和异步的概念

  • 同步发送请求的过程如下所示
    • 浏览器页面发送请求给服务器,在服务器处理请求的过程中,浏览器页面不能做其他操作。只能等到服务器响应结束之后,浏览器页面才能继续其他操作
  • 异步发送请求的过程如下所示
    • 浏览器页面发送请求给服务器,在服务器处理请求的过程中,浏览器页面还可以做其他的操作

1.3、Ajax入门

1.3.1、客户端代码

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <input><br>
        <input type="button" value="点我,我在睡觉" onclick="sendAjax()">
    </body>
    <script>
        function sendAjax() {
            //1.创建核心对象
            xmlhttp=null;
            if (window.XMLHttpRequest)
            {// code for IE7, Firefox, Opera, etc.
                xmlhttp=new XMLHttpRequest();
            }
            else if (window.ActiveXObject)
            {// code for IE6, IE5
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
                //2.明确发送的请求方式和请求路径
          xmlhttp.open("get","/day28/ajaxServlet?username=tom")
    
          //3.发送请求
          xmlhttp.send()
    
          //4.处理响应
          xmlhttp.onreadystatechange=function () {
              //当响应完成的时候且响应正常完成的时候
              if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                  alert(xmlhttp.responseText);
              }
          }
      }
        </script>
    
      </html>
    
    

1.3.2、服务端代码

  • package com.itheima.web.servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet(value = "/ajaxServlet")
    public class AjaxServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //获取发送过来的参数
            String username = request.getParameter("username");
            System.out.println(username);
    
            //生成响应
            response.getWriter().print("ok~~~");
        }
    }
    

1.3.3、实现效果

  • 不难发现,点击按钮后,整个页面并没有发生跳转,只是进行了局部的刷新

1.4、校验用户名是否存在案例(仅测试,不做过多的逻辑判断)

1.4.1、需求

  • 在完成用户注册的时候,当用户名输入框失去焦点时,校验用户名是否在数据库中存在

1.4.2、分析

  • 前端完成的逻辑
    • 1.给用户名输入框绑定光标失去焦点事件onblur
    • 2.发送ajax请求,携带username参数
    • 3.处理响应:是否显示提示信息
  • 后端完成的逻辑
    • 1.接收用户名
    • 2.调用service查询User
    • 3.返回标记

1.4.3、整体流程图

1.4.4、前端实现

  • Step1:给用户名输入框绑定光标失去焦点事件

    • //1. 给用户名输入框绑定 失去焦点事件
      document.getElementById("username").onblur = function () {
          
      }
      
  • Step2:发送ajax请求,携带username参数

    • //2. 发送ajax请求
      //2.1. 创建核心对象
      var xhttp;
      if (window.XMLHttpRequest) {
          xhttp = new XMLHttpRequest();
      } else {
          // code for IE6, IE5
          xhttp = new ActiveXObject("Microsoft.XMLHTTP");
      }
      //2.2. 发送请求
      xhttp.open("GET", "http://localhost:8080/ajax-demo/selectUserServlet);
      xhttp.send();
      
      //2.3. 获取响应
      xhttp.onreadystatechange = function() {
          if (this.readyState == 4 && this.status == 200) {
              //处理响应的结果
          }
      };
      
    • 由于我们发送的是 GET 请求,所以需要在 URL 后拼接从输入框获取的用户名数据。而我们在 第一步 绑定的匿名函数中通过以下代码可以获取用户名数据

    • // 获取用户名的值
      var username = this.value;  //this : 给谁绑定的事件,this就代表谁
      
    • 而携带数据需要将 URL 修改为:

    • xhttp.open("GET", "http://localhost:8080/ajax-demo/selectUserServlet?username="+username);
      
  • Step3:处理响应,根据响应判断是否显示提示信息

    • this.readyState == 4 && this.status == 200 条件满足时,说明已经成功响应数据了

    • 此时需要判断响应的数据是否是 “true” 字符串,如果是说明用户名已经占用给出错误提示;如果不是说明用户名未被占用清除错误提示。代码如下

      • //判断
        if(this.responseText == "true"){
            //用户名存在,显示提示信息
            document.getElementById("username_err").style.display = '';
        }else {
            //用户名不存在 ,清楚提示信息
            document.getElementById("username_err").style.display = 'none';
        }
        
  • 完整JS代码

    • //1. 给用户名输入框绑定 失去焦点事件
      document.getElementById("username").onblur = function () {
          //2. 发送ajax请求
          // 获取用户名的值
          var username = this.value;
      
          //2.1. 创建核心对象
          var xhttp;
          if (window.XMLHttpRequest) {
              xhttp = new XMLHttpRequest();
          } else {
              // code for IE6, IE5
              xhttp = new ActiveXObject("Microsoft.XMLHTTP");
          }
          //2.2. 发送请求
          xhttp.open("GET", "http://localhost:8080/ajax-demo/selectUserServlet?username="+username);
          xhttp.send();
      
          //2.3. 获取响应
          xhttp.onreadystatechange = function() {
              if (this.readyState == 4 && this.status == 200) {
                  //alert(this.responseText);
                  //判断
                  if(this.responseText == "true"){
                      //用户名存在,显示提示信息
                      document.getElementById("username_err").style.display = '';
                  }else {
                      //用户名不存在 ,清楚提示信息
                      document.getElementById("username_err").style.display = 'none';
                  }
              }
          };
      }
      

1.4.5、后端实现

  • @WebServlet("/selectUserServlet")
    public class SelectUserServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //1. 接收用户名
            String username = request.getParameter("username");
            //2. 调用service查询User对象,此处不进行业务逻辑处理,直接给 flag 赋值为 true,表明用户名占用
            boolean flag = true;
            //3. 响应标记
            response.getWriter().write("" + flag);
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
    

1.4.6、实现效果

2、Axios

  • 概念
    • Axios是对原生的Ajax进行封装,简化书写

2.1、基本使用

  • 1.引入axios的js文件

    • <script src="js/axios-0.18.0.js"></script>
      
  • 2.使用axios发送ajax请求

    • 发送get请求

      • axios({
            method:"get",
            url:"http://localhost:8080/ajax-demo1/aJAXDemo1?username=zhangsan"
        }).then(function (resp){
            alert(resp.data);
        });
        
    • 发送post请求

      • axios({
            method:"post",
            url:"http://localhost:8080/ajax-demo1/aJAXDemo1",
            data:"username=zhangsan"
        }).then(function (resp){
            alert(resp.data);
        });
        
  • 说明

    • axios()是用来发送异步请求的,小括号中使用js对象传递相关的参数
      • method属性:用来设置请求方式的。取值为get或者post
      • url属性:用来书写请求的资源路径。如果是get请求,需要将请求参数拼接到路径的后面,格式为:url?参数名1=参数值1&参数名2=参数值2
      • data属性:作为请求体被发送的数据。也就是说如果是post请求的话。数据需要作为data属性的值
    • then()需要传递一个匿名函数。then()中传递的匿名函数称为回调函数,意思是该匿名函数在发送请求的时候不会被调用,而是在成功响应后调用的函数。
      • resp属性是对响应的数据进行封装的对象,通过resp.data可以获取到响应的数据

2.2、基本使用

2.2.1、后端实现

  • @WebServlet("/axiosServlet")
    public class AxiosServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("get...");
            //1. 接收请求参数
            String username = request.getParameter("username");
            System.out.println(username);
            //2. 响应数据
            response.getWriter().write("hello Axios~");
        }
    
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("post...");
            this.doGet(request, response);
        }
    }
    

2.2.2、前端实现

  • 1.引入js文件

    • <script src="js/axios-0.18.0.js"></script>
      
  • 2.发送ajax请求

    • get请求

      • axios({
            method:"get",
            url:"http://localhost:8080/ajax-demo/axiosServlet?username=zhangsan"
        }).then(function (resp) {
            alert(resp.data);
        })
        
    • post请求

      • axios({
            method:"post",
            url:"http://localhost:8080/ajax-demo/axiosServlet",
            data:"username=zhangsan"
        }).then(function (resp) {
            alert(resp.data);
        })
        
  • 完整代码

    • <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>axios-demo</title>
      </head>
      <body>
          <input type="button" value="发送get请求" id="btn1">
          <input type="button" value="发送post请求" id="btn2">
      </body>
      <!--导入axios.js-->
      <script src="./js/axios-0.18.0.js"></script>
      <!--编写axios的代码-->
      <script>
          document.getElementById("btn1").onclick = function () {
            // axios({
            //     method: "get",
            //     url: "axiosServlet?username=tom"
            // }).then(function (response) {
            //     // console.log(response);
            //     // console.log(response.data);
            //     window.alert(response);
            //     window.alert(response.data);
            // });
      
            // axios更简化的写法
            axios.get("axiosServlet?username=tom").then(response => {
              console.log(response.data);
            });
          }
      
          document.getElementById("btn2").onclick = function () {
            // axios({
            //   method: "post",
            //   url: "axiosServlet",
            //   data: "username=tom"
            // }).then(function (response) {
            //   // console.log(response);
            //   // console.log(response.data);
            //     window.alert(response);
            //     window.alert(response.data);
            // });
      
            // axios更简化的写法
            axios.post("axiosServlet", "username=tom").then(response => {
              console.log(response.data);
            });
          }
      </script>
      </html>
      

2.2.3、实现效果

2.3、Axios请求方法别名

  • get 请求 : axios.get(url[,config])
  • delete 请求 : axios.delete(url[,config])
  • head 请求 : axios.head(url[,config])
  • options 请求 : axios.option(url[,config])
  • post 请求:axios.post(url[,data[,config])
  • put 请求:axios.put(url[,data[,config])
  • patch 请求:axios.patch(url[,data[,config])

PS:

  • axios会自动对JSON串进行转换
  • 发送异步请求时,如果请求参数是JSON格式,那请求方式必须是POST。因为JSON串需要放在请求体中

2.4、使用Axios和JSON完成学生列表数据查询

虽然实现的效果差不多,但是实际上免去了JSTL中复杂的编写格式

2.4.1、前端实现

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>学生信息</title>
    </head>
    <body>
    <hr>
    <table id="studentTable" border="1" cellspacing="0" width="800" align="center">
    
    </table>
    <script src="./js/axios-0.18.0.js"></script>
    <!--<script>window.alert("等待页面加载.....");</script>-->
    <script>
        // 在页面加载完成的时候,展示数据
        console.log("等待页面加载.....");
        window.alert("等待页面加载.....");
    
        window.onload = function () {
            window.alert("页面加载成功,正在发送ajax请求!");
            // 发送ajax的get请求,获取所有学生的信息
            axios.get("selectAllStudentsServlet").then(response => {
                // console.log(response.data);
                // 定义表格中的首行信息
                let startTr = "<tr>\n" +
                    "        <th>序号</th>\n" +
                    "        <th>学号</th>\n" +
                    "        <th>姓名</th>\n" +
                    "        <th>年龄</th>\n" +
                    "        <th>性别</th>\n" +
                    "        <th>语文成绩</th>\n" +
                    "        <th>数学成绩</th>\n" +
                    "        <th>英语成绩</th>\n" +
                    "        <th>操作</th>\n" +
                    "    </tr>";
    
                // 定义表格中的末尾信息
                let endTr = "<tr align=\"center\">\n" +
                    "        <td></td>\n" +
                    "        <td></td>\n" +
                    "        <td></td>\n" +
                    "        <td></td>\n" +
                    "        <td></td>\n" +
                    "        <td></td>\n" +
                    "        <td></td>\n" +
                    "        <td></td>\n" +
                    "        <td><input type=\"button\" value=\"新增学生信息\" onclick=\"location.href=('#')\"></td>\n" +
                    "    </tr>";
    
                let middleTr = "";
                // 遍历json数组,获取每个学生对象
                // 获取返回的json数组
                let arr = response.data;
                for (let i = 0; i < arr.length; i++) {
                    // 将每个品牌封装成tr标签
                    middleTr += "<tr align=\"center\">\n" +
                        "        <td>" + (i + 1) + "</td>\n" +
                        "        <td>" + (arr[i].stuNumber) + "</td>\n" +
                        "        <td>" + (arr[i].name) + "</td>\n" +
                        "        <td>" + (arr[i].age) + "</td>\n" +
                        "        <td>" + (arr[i].sex) + "</td>\n" +
                        "        <td>" + (arr[i].chineseScore) + "</td>\n" +
                        "        <td>" + (arr[i].mathScore) + "</td>\n" +
                        "        <td>" + (arr[i].englishScore) + "</td>\n" +
                        "        <td>\n" +
                        "            <input type=\"button\" src=\"#\" value=\"修改\">\n" +
                        "            <input type=\"button\" src=\"#\" value=\"删除\">\n" +
                        "        </td>\n" +
                        "    </tr>";
                }
    
                // 将所有的tr标签放入table标签终
                document.getElementById("studentTable").innerHTML = startTr + middleTr + endTr;
                window.alert(document.getElementById("studentTable").innerHTML);
            });
        }
    </script>
    </body>
    </html>
    

2.4.2、后端实现

  • package com.coolman.web.servlet;
    
    import com.alibaba.fastjson.JSON;
    import com.coolman.pojo.Student;
    import com.coolman.service.StudentService;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.List;
    
    @WebServlet("/selectAllStudentsServlet")
    public class SelectAllStudentsServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 在这里处理请求
    
            // 调用服务,查询所有学生信息
            List<Student> students = new StudentService().selectAllStudent();
    
            // 将List对象转换成JSON格式的字符串
            String str = JSON.toJSONString(students);
    
            // 处理中文乱码问题
            // 方案1
    //        response.setContentType("text/html;charset=utf-8");
            // 方案2
            response.setContentType("application/json;charset=utf-8");
    
            // 返回字符串
            response.getWriter().print(str);
    
        }
    }
    

2.5、使用Axios和JSON完成新增学生信息

2.5.1、前端实现

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>添加学生信息</title>
    </head>
    <body>
    <h3 align="center" style="color: red">添加学生信息</h3>
    <form>
        <div align="center">
            <span>学号:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <input name="stuNumber" id="stuNumber">
                <br/>
                <span style="color: red" id="stuNumber_err_msg"></span>
                <br/>
            </span>
            <span>姓名:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <input name="name" id="name">
                <br>
                <span style="color: red" id="name_err_msg"></span>
                <br>
            </span>
            <span>年龄:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <input name="age" id="age">
                <br>
                <span style="color: red" id="age_err_msg"></span>
                <br>
            </span>
            <span>性别:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <input name="sex" id="sex">
                <br>
                <span style="color: red" id="sex_err_msg"></span>
                <br>
            </span>
            <span>语文成绩:
                <input name="chineseScore" id="chineseScore">
                <br>
                <span style="color: red" id="chineseScore_err_msg"></span>
                <br>
            </span>
            <span>数学成绩:
                <input name="mathScore" id="mathScore">
                <br>
                <span style="color: red" id="mathScore_err_msg"></span>
                <br>
            </span>
            <span>英语成绩:
                <input name="englishScore" id="englishScore">
                <br>
                <span style="color: red" id="englishScore_err_msg"></span>
                <br>
            </span>
    
            <input id="commit" type="button" value="提交">
        </div>
    </form>
    <script src="./js/axios-0.18.0.js"></script>
    <script>
        // 定义一个对象,接收输入框中的信息
        let studentFormData = {
            stuNumber: "",
            name: "",
            age: "",
            sex: "",
            chineseScore: "",
            mathScore: "",
            englishScore: "",
        }
        // 判断输入框是否为空
        document.getElementById("stuNumber").onblur = function () {
            let stuNumber = this.value;
            if (stuNumber != "") {
                studentFormData.stuNumber = stuNumber;
            } else {
                document.getElementById("stuNumber_err_msg").innerText = "学号不能为空";
            }
        };
        document.getElementById("name").onblur = function () {
            let name = this.value;
            if (name != "") {
                studentFormData.name = name;
            } else {
                document.getElementById("name_err_msg").innerText = "姓名不能为空";
            }
        };
        document.getElementById("age").onblur = function () {
            let age = this.value;
            if (age != "") {
                studentFormData.age = age;
            } else {
                document.getElementById("age_err_msg").innerText = "年龄不能为空";
            }
        };
        document.getElementById("sex").onblur = function () {
            let sex = this.value;
            if (sex != "") {
                studentFormData.sex = sex;
            } else {
                document.getElementById("sex_err_msg").innerText = "性别不能为空";
            }
        };
        document.getElementById("chineseScore").onblur = function () {
            let chineseScore = this.value;
            if (chineseScore != "") {
                studentFormData.chineseScore = chineseScore;
            } else {
                document.getElementById("chineseScore_err_msg").innerText = "语文成绩不能为空";
            }
        };
        document.getElementById("mathScore").onblur = function () {
            let mathScore = this.value;
            if (mathScore != "") {
                studentFormData.mathScore = mathScore;
            } else {
                document.getElementById("mathScore_err_msg").innerText = "数学成绩不能为空";
            }
        };
        document.getElementById("englishScore").onblur = function () {
            let englishScore = this.value;
            if (englishScore != "") {
                studentFormData.englishScore = englishScore;
            } else {
                document.getElementById("englishScore_err_msg").innerText = "英语成绩不能为空";
            }
        };
    
        // 绑定提交事件
        document.getElementById("commit").onclick = function () {
            // 判断对象是否存在数据
            // 不存在则不发送添加学生信息的请求
            if (studentFormData.name != "" && studentFormData.age != "" && studentFormData.sex != "" && studentFormData.stuNumber != ""
                && studentFormData.chineseScore != "" && studentFormData.mathScore != "" && studentFormData.englishScore != ""
            ) {
                // 发送ajax请求,添加学生数据
                axios.post("addStudentServlet", studentFormData).then(response => {
                    if (response.data == "ok") {
                        location.href = "studentList.html";
                    }
                });
            } else {
                window.alert("请补全信息!");
            }
        }
    </script>
    </body>
    </html>
    

2.5.2、后端实现

  • package com.coolman.web.servlet;
    
    import com.alibaba.fastjson.JSON;
    import com.coolman.pojo.Student;
    import com.coolman.service.StudentService;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletInputStream;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet("/addStudentServlet")
    public class AddStudentServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 在这里处理请求
    
            //1.获取请求体中的流
            ServletInputStream is = request.getInputStream();
    
            //2.把流转成java对象
            Student student = JSON.parseObject(is, Student.class);
    
            //3.调用service中保存方法
            new StudentService().addStudent(student);
    
            //4.通知前端保存成功
            response.getWriter().print("ok");
        }
    }
    

3、Vue

3.1、概念

  • Vue是一套前端框架,免除原生JavaScript中的DOM操作,简化书写。其基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定,将编程的关注点放在数据上。
  • MVC思想图解
    • MVC:只能实现模型到视图的单向展示,无法实现双向绑定。
    • 双向绑定的概念
      • 指的是当数据模型的数据发生变化的时候,页面展示也会随之发生变化,而如果表单数据发生变化,绑定的模型数据也随之发生变化。
  • MVVM思想图解
    • 图中的Model就是我们的数据,View是视图,也就是页面标签,用户可以通过浏览器看到的内容
    • Model和View是通过ViewModel对象进行双向绑定的,而ViewModel对象是Vue提供的
  • MVVM简单示例
    • 输入框绑定username模型数据,页面上使用{{}}绑定username模型数据
    • 通过浏览器打开该页面可以看到如下页面
    • 当我们在输入框中输入内容的同时,输入框后面也随之实时的展示我们输入的内容,这就是双向绑定的效果

3.2、Vue入门

  • Vue使用起来比较简单,可以分为如下三步

    • 1.新建HTML页面,引入Vue.js文件

      • <script src="js/vue.js"></script>
        
    • 2.在js代码区域,创建Vue核心对象,进行数据绑定

      • new Vue({
            el: "#app",
            data() {
                return {
                    username: ""
                }
            }
        });
        
      • 创建Vue对象的时候,需要传递一个js对象,而该对象中需要如下属性:

        • el:用来指定哪些标签受Vue管理,该属性取值#app中的app需要的是受管理的标签的id属性值
        • data:用来定义数据模型
        • methods:用来定义函数
    • 3.编写视图

      • <div id="app">
            <input name="username" v-model="username" >
            {{username}}
        </div>
        
      • {{}}是Vue中定义的插值表达式,在里面写数据模型,到时候会将该模型的数据值展示在这个位置

  • 整体代码如下

    • <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
      <div id="app">
          <input v-model="username">
          <!--插值表达式-->
          {{username}}
      </div>
      <script src="js/vue.js"></script>
      <script>
          //1. 创建Vue核心对象
          new Vue({
              el:"#app",
              data(){  // data() 是 ECMAScript 6 版本的新的写法
                  return {
                      username:""
                  }
              }
      
              /*data: function () {
                  return {
                      username:""
                  }
              }*/
          });
      
      </script>
      </body>
      </html>
      

3.3、Vue指令

  • 指令:HTML标签上带有v-前缀的特殊属性,不同指令具有不同含义。例如:v-if,v-for….

  • 常用的指令如下所示

    • 指令 作用
      v-bind 为HTML标签绑定属性值,如设置href,css样式等等
      v-model 在表单元素上创建双向数据绑定
      v-on 为HTML标签绑定事件
      v-if 条件性的渲染某元素,判定为true的时候渲染,否则不渲染
      v-else 同if-else
      v-else-if 同if-else if-else
      v-show 根据条件展示某元素,区别在于切换的是display属性的值
      v-for 列表渲染,遍历容器的元素或者对象的属性

3.3.1、v-bind示例

  • <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v-bind="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <!--
                v-bind  该指令可以给标签原有属性绑定模型数据
                v-bind  可以简化写成 :
             -->
            <a v-bind:href="url">点我一下</a><br/>
            <a :href="url">点我一下</a><br/>
        </div>
    </body>
    <!--导入vue.js-->
    <script src="../js/vue.js"></script>
    <!--定义vue对象-->
    <script>
        new Vue({
            el: "#app",
            data: {
                url: "https://www.baidu.com"
            }
        })
    </script>
    </html>
    
    • 通过浏览器打开该页面,可以发现,链接标签就绑定了data中的url数据模型

3.3.2、v-model示例

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <a :href="url">点我一下</a><br/>
            <!--
                 v-model 指令可以给表单项标签绑定模型数据,这样就能实现双向绑定效果
            -->
            <input v-model="url"/>
        </div>
    </body>
    <!--导入vue.js-->
    <script src="../js/vue.js"></script>
    
    <!--定义vue对象-->
    <script>
        new Vue({
            el:"#app",
            data:{
                url:"https://www.bing.com"
            }
        });
    </script>
    </html>
    
    • 通过浏览器打开该页面,发现a标签的href属性会随着输入框输入的路径变化而变化,这是因为超链接和输入框绑定的是同一个数据模型

3.3.3、v-on示例

  • <!DOCTYPE html>
    <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <!--
                 v-on 指令用于绑定事件,具体方法逻辑需要在vue的methods属性中体现
                 v-on 可以简写为 @
            -->
            <input type="button" value="点我44" v-on:click="show1()"/>
            <input type="button" value="点我44" v-on:click="show2"/>
            <input type="button" value="点我44" @click="show3()"/>
        </div>
    </body>
    <!--导入vue.js-->
    <script src="../js/vue.js"></script>
    
    <!--定义vue对象-->
    <script>
        new Vue({
            el:"#app",
            data:{
            },
            methods: {
                show1() {
                    alert("我被点了,嘤嘤嘤");
                },
                show2() {
                    alert("我又被点了,嘤嘤嘤");
                },
                show3() {
                    alert("我又又被点了,嘤嘤嘤");
                }
            }
        });
    </script>
    </html>
    
    • v-on:后面的事件名称是之前原生事件属性名去掉on
    • 例如
      • 单击事件:事件属性名是onclick,而在vue中使用的是:v-on:onclick
      • 失去焦点事件:事件属性名是onblur,而在vue中使用的是:v-on:blur

3.3.4、v-if示例

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <!--
            语法:
                 v-if="布尔表达式"  v-else-if="布尔表达式"   v-else
            注意:
                当得到结果为true时,所在的元素才会被渲染
                v-else-if或v-else元素必须跟在v-if的元素的后面,否则它将不会被识别
            -->
            <!--从文本框输入成绩, 然后判断成绩是否及格  >=60:及格  <60:不及格  其他数字:超出范围 非数字:数据非法-->
            <h3>考试成绩练习</h3>
            请输入成绩:<input type="text" v-model="score"><br>
            你本次考试成绩:
            <div v-if="score == ''"></div>
            <div v-else-if="score > 100 || score < 0">超出范围</div>
            <div v-else-if="score >= 60">及格</div>
            <div v-else-if="score < 60">不及格</div>
            <div v-else>数据非法</div>
    
            <hr>
            <div v-show="score==100">满分</div>
        </div>
    </body>
    <!--导入vue.js-->
    <script src="../js/vue.js"></script>
    
    <!--定义vue对象-->
    <script>
        new Vue({
            el:"#app",
            data:{
                score:"",
            },
        });
    </script>
    </html>
    

3.3.5、v-for示例

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <!--
            语法:
                <标签 v-for="(变量名,索引) in 集合模型数据">
                    {{变量名}}
                </标签>
            注意:
                遍历那个标签就把v-for写在那个标签中
                不需要索引时可以不写,这时候小括号也可以省略
            -->
            <ul>
                <li v-for="city in cities">{{city}}</li>
            </ul>
            <hr/>
            <ul>
                <li v-for="(city, index) in cities">
                    {{index + 1}}   :   {{city}}
                </li>
            </ul>
        </div>
    </body>
    <!--导入vue.js-->
    <script src="../js/vue.js"></script>
    
    <!--定义vue对象-->
    <script>
        new Vue({
            el:"#app",
            data:{
                cities:["北京", "上海", "广州", "深圳"]
            }
        });
    </script>
    </html>
    

3.3.6、生命周期

  • 声明周期的八个阶段,每触发一个生命周期事件,会自动执行一个生命周期方法,这些生命周期方法也被称为钩子方法

    • 状态 阶段周期
      beforeCreate 创建前
      created 创建后
      beforeMount 载入前
      mounted 挂载完成
      beforeUpdate 更新前
      updated 更新后
      beforeDestory 销毁前
      destoryed 销毁后
  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <div id="app">
            <!--
            -->
        </div>
    </body>
    <!--导入vue.js-->
    <script src="../js/vue.js"></script>
    
    <!--定义vue对象-->
    <script>
        new Vue({
            el:"#app",
            mounted() {
                console.log("I am mounted method");
            },
            created() {
                console.log("I am create method");
            }
        });
    </script>
    </html>
    

3.4、使用Vue简化基于ajax做的查询所有和添加功能

3.4.1、学生列表信息页面

  • 前端实现

    • <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>学生信息</title>
      </head>
      <body>
      <hr>
      <table id="studentTable" border="1" cellspacing="0" width="800" align="center">
          <tr>
              <th>序号</th>
              <th>学号</th>
              <th>姓名</th>
              <th>年龄</th>
              <th>性别</th>
              <th>语文成绩</th>
              <th>数学成绩</th>
              <th>英语成绩</th>
              <th>操作</th>
          </tr>
      
          <tr align="center" v-for="(student, index) in students">
              <td>{{index + 1}}</td>
              <td>{{student.stuNumber}}</td>
              <td>{{student.name}}</td>
              <td>{{student.age}}</td>
              <td>{{student.sex}}</td>
              <td>{{student.chineseScore}}</td>
              <td>{{student.mathScore}}</td>
              <td>{{student.englishScore}}</td>
              <td><a href="#">修改</a> <a href="#">删除</a></td>
          </tr>
      
          <tr align="center">
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td><input type="button" value="新增学生信息" onclick="location.href=('addStudent.html')"></td>
          </tr>
      </table>
      <script src="./js/axios-0.18.0.js"></script>
      <!--导入vue.js-->
      <script src="./js/vue.js"></script>
      <script>
          new Vue({
              el: "#studentTable",
              data: {
                  students: []
              },
              created(){
                  axios.get("selectAllStudentsServlet").then(response => {
                      this.students = response.data;
                  })
              }
          });
      </script>
      </body>
      </html>
      
  • 后端实现

    • package com.coolman.web.servlet;
      
      import com.alibaba.fastjson.JSON;
      import com.coolman.pojo.Student;
      import com.coolman.service.StudentService;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.util.List;
      
      @WebServlet("/selectAllStudentsServlet")
      public class SelectAllStudentsServlet extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              doGet(request, response);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 在这里处理请求
      
              // 调用服务,查询所有学生信息
              List<Student> students = new StudentService().selectAllStudent();
      
              // 将List对象转换成JSON格式的字符串
              String str = JSON.toJSONString(students);
      
              // 处理中文乱码问题
              // 方案1
      //        response.setContentType("text/html;charset=utf-8");
              // 方案2
              response.setContentType("application/json;charset=utf-8");
      
              // 返回字符串
              response.getWriter().print(str);
      
          }
      }
      
      

3.4.2、添加学生信息

  • 前端实现

    • <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>添加学生信息</title>
      </head>
      <body>
      <h3 align="center" style="color: red">添加学生信息</h3>
      <form>
          <div align="center" id="addStudent">
              <span>学号:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  <input name="stuNumber" id="stuNumber" v-model="student.stuNumber">
                  <br/>
                  <span style="color: red" id="stuNumber_err_msg"></span>
                  <br/>
              </span>
              <span>姓名:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  <input name="name" id="name" v-model="student.name">
                  <br>
                  <span style="color: red" id="name_err_msg"></span>
                  <br>
              </span>
              <span>年龄:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  <input name="age" id="age" v-model="student.age">
                  <br>
                  <span style="color: red" id="age_err_msg"></span>
                  <br>
              </span>
              <span>性别:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  <input name="sex" id="sex" v-model="student.sex">
                  <br>
                  <span style="color: red" id="sex_err_msg"></span>
                  <br>
              </span>
              <span>语文成绩:
                  <input name="chineseScore" id="chineseScore" v-model="student.chineseScore">
                  <br>
                  <span style="color: red" id="chineseScore_err_msg"></span>
                  <br>
              </span>
              <span>数学成绩:
                  <input name="mathScore" id="mathScore" v-model="student.mathScore">
                  <br>
                  <span style="color: red" id="mathScore_err_msg"></span>
                  <br>
              </span>
              <span>英语成绩:
                  <input name="englishScore" id="englishScore" v-model="student.englishScore">
                  <br>
                  <span style="color: red" id="englishScore_err_msg"></span>
                  <br>
              </span>
      
              <input id="commit" type="button" value="提交" v-on:click="add()">
          </div>
      </form>
      <script src="./js/axios-0.18.0.js"></script>
      <script src="./js/vue.js"></script>
      <script>
          new Vue({
              el: "#addStudent",
              data: {
                  student: {
                      stuNumber: "",
                      name: "",
                      age: "",
                      sex: "",
                      chineseScore: "",
                      mathScore: "",
                      englishScore: "",
                  }
              },
              methods: {
                  add() {
                      axios.post("addStudentServlet", this.student).then(response =>{
                          if (response.data == "ok") {
                              window.location.href = "studentList.html";
                          }
                      })
                  }
              }
          })
      </script>
      </body>
      </html>
      
  • 后端实现

    • package com.coolman.web.servlet;
      
      import com.alibaba.fastjson.JSON;
      import com.coolman.pojo.Student;
      import com.coolman.service.StudentService;
      
      import javax.servlet.ServletException;
      import javax.servlet.ServletInputStream;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      @WebServlet("/addStudentServlet")
      public class AddStudentServlet extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              doGet(request, response);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              // 在这里处理请求
      
              //1.获取请求体中的流
              ServletInputStream is = request.getInputStream();
      
              //2.把流转成java对象
              Student student = JSON.parseObject(is, Student.class);
      
              //3.调用service中保存方法
              new StudentService().addStudent(student);
      
              //4.通知前端保存成功
              response.getWriter().print("ok");
          }
      }
      

4、总结

导入axios的js文件

axios.get(“url?key=value”).then(r=>{ r.data });

axios.post(“url”,”key=value”).then(r=>{ r.data });

导入vue的js文件

在script标签中定义vue变量

new Vue({
	el:"#id值",//指定渲染的标签
	data:{},//声明数据
	methods:{},//声明vue绑定的事件方法
	created(){},//页面加载成功
	mounted(){}//也可以认为是页面加载成功
});

指令:

  • v-bind
  • v-model
  • v-on
  • v-if v-else-if v-else
  • v-show
  • v-for

vue生命周期函数

  • created或者mounted均可替代页面加载成功