Ajax异步请求
Asynchronous JavaScript + XML(异步JavaScript和XML), 其本身不是一种新技术,而是一个在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法,包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的 XMLHttpRequest。当使用结合了这些技术的AJAX模型以后, 网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面。这使得程序能够更快地回应用户的操作。
AJax是可以做异步的请求 ,可以在页面上发起请求(异步),实现局部刷新一种客户端技术
JS的Ajax
服务器接收和响应数据
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { System.out.println("UserServlet...doGet..."); //0. 设置中文编码 req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); //1. 获取参数 String username = req.getParameter("username"); //2. 交代service UserService userService = new UserService(); //返回这个用户名在数据库表中的数量,有多少个。 int total = userService.checkUsername(username); //3. 响应 if(total > 0 ){ //表明什么?数据库有这样的用户名 resp.getWriter().write("<font color='red'>用户名已被占用!</font>"); }else{//表明什么? 数据库还没有这个用户名 resp.getWriter().write("<font color='green'>用户名可以使用!</font>"); } } catch (SQLException throwables) { throwables.printStackTrace(); } } public int checkUsername(String username) throws SQLException { //调用dao UserDao userDao = new UserDao(); return userDao.findUser(username); } public int findUser(String username) throws SQLException { QueryRunner runner = new QueryRunner(C3P0Utils.getDataSource()); //我们对这个叫这个用户名的用户的信息不感兴趣,我们只想知道数据库有没有这个用户名。 //所以这里使用select count(*) 而不是使用select * String sql = "select count(*) from user where username = ?"; long total = (long) runner.query(sql , new ScalarHandler(), username); return (int) total; }
GET请求方式
<input type="button" value="使用Ajax发起GET请求" onclick="sendGET()"/> <br/> <script> //使用ajax发起get请求 function sendGET() { //1. 创建xmlhttprequest对象 //var http =new XMLHttpRequest(); // 现在可以直接使用该方式,下面的方式是之前版本需要根据浏览器类型来创建异步请求对象 var xmlHttp = null; if (window.XMLHttpRequest) {// all modern browsers xmlHttp = new XMLHttpRequest(); } else if (window.ActiveXObject) {// for IE5, IE6 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } //2. 打开连接 //参数一: 请求方式, //参数二: 请求地址 //xmlHttp.open("GET", "../ajax"); //发请求,带数据 xmlHttp.open("GET", "../ajax?username=admin&password=123456"); //3. 发送请求 xmlHttp.send(); //4. 获得响应。 设置一个状态的监听 xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ var result = xmlHttp.responseText; console.log("result=" + result); } } } </script>
POST请求方式
<input type="button" value="使用Ajax发起POST请求" onclick="sendPOST()"/> <br/> <script> //使用ajax发起post请求 function sendPOST(){ //1. 创建xmlhttprequest对象 //var http =new XMLHttpRequest(); var xmlHttp = null; if (window.XMLHttpRequest) {// all modern browsers xmlHttp = new XMLHttpRequest(); } else if (window.ActiveXObject) {// for IE5, IE6 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } //2. 打开连接 参数一: 发起的请求方式, 参数二:请求地址 xmlHttp.open("POST" , "../ajax") //2.1 如果使用post请求来发送数据,那么需要设置数据的内容类型,设置一个头。 xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded") //3. 发送请求 xmlHttp.send("username=zhangsan&password=123456"); //4. 获得响应 xmlHttp.onreadystatechange=function(){ if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ //获取结果 var result = xmlHttp.responseText; console.log("result=" + result); } } } </script>
XMLHttpRequest对象
不同的浏览器对该对象的创建的方式不一样,MSIE浏览器,比较早的浏览器,创建这个对象的时候将这个对象封装到ActiveXObject的插件中。像火狐或者谷歌浏览器则直接new出来。
function createXmlHttp(){ var xmlHttp; try{ // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); }catch (e){ try{// Internet Explorer xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){ try{ xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e){} } } return xmlHttp; }
方法
open() :打开连接。传递三个参数。第一个是请求方式(GET/POST),第二个是请求路径,第三个是否是异步的(默认就是异步,不需要这个参数)
send([post请求的参数]): 发送请求。
setRequestHeader():解决POST请求参数的问题。 key和值 content-type
属性
onreadystatechange:监听该对象的状态的改变,需要一个函数响应它
readyState:该属性就记录这个对象的状态
值 说明 0(未初始化) 对象已建立,但是尚未初始化(尚未调用open方法) 1(初始化) 对象已建立,尚未调用send方法 2(发送数据) send方法已调用,但是当前的状态及http头未知 3(数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误 4(完成) 数据接收完毕,此时可以通过responseBody和responseText获取完整的回应数据 status:状态码 。 200
responseText:获得字符串形式的响应数据(响应体)。
responseXML :获得 XML 形式的响应数据(响应体)
JQ的AJAX
JQuery的Ajax的API
请求方式 | 语法 |
---|---|
GET请求 | $.get(url, [data], [callback], [type]) |
POST请求 | $.post(url, [data], [callback], [type]) |
AJAX请求 | $.ajax([settings]) |
GET请求(3.0新特性) | $.get([settings]) |
POST请求(3.0新特性) | $.post([settings]) |
参数名称 | 解释 |
---|---|
url | 请求的服务器端url地址 |
data | 发送给服务器端的请求参数,格式可以是key=value,也可以是js对象 |
callback | 当请求成功后的回调函数,可以在函数体中编写我们的逻辑代码 |
type | 预期的返回数据的类型,取值可以是 xml, html, script, json, text, _defaul等,一般可以不写它,由浏览器自行去判定回来的数据是什么类型。 |
其中,settings是一个js字面量形式的对象,格式是{name:value,name:value... ...},常用的name属性名如下
属性名称 | 解释 |
---|---|
url | 请求的服务器端url地址 |
async | (默认: true) 默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false |
data | 发送到服务器的数据,可以是键值对形式,也可以是js对象形式 |
type | (默认: "GET") 请求方式 ("POST" 或 "GET"), 默认为 "GET" |
dataType | 预期的返回数据的类型,取值可以是 xml, html, script, json, text, _defaul等 |
success | 请求成功后的回调函数 |
error | 请求失败时调用此函数 |
get()
get方式, 语法
$.get(url, [data], [callback], [type]);
<input type="button" value="使用Jquery的Ajax发起get请求" onclick="sendGet()"/><br/> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../js/jquery-1.11.0.min.js"></script> <script> //发起get请求。 function sendGET() { //1. 发请求,不带数据,不求响应 //$.get("../ajax") //2. 发请求,带数据,不求响应 //$.get("../ajax?username=admin&password=123456") //2.1 发请求,带数据,不求响应 //$.get("../ajax", {username:'admin6' , password:'6666'}); //3. 发请求,带数据,求响应 /* $.get :发起get请求 参数一: 请求的地址路径 参数二: {username:'admin6' , password:'6666'} 这是提交的数据,它是一个json格式的数据 参数三:回调函数,也就是当请求成功了之后,会调用这个函数。这个函数里面可有一个参数data, 这个参数data就是服务器返回回来的数据。 */ $.get("../ajax" , {username:'admin6' , password:'6666'} , function(data){ console.log("回来结果了~"); console.log(data); }); } </script> </head> <body> <!--使用JQuery发起Ajax请求(GET请求和POST请求)--> <input type="button" value="使用JQuery发起GET请求" onclick="sendGET()"/> </body> </html>
post()
post方式, 语法
$.post(url, [data], [callback], [type])
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../js/jquery-1.11.0.min.js"></script> <script> //使用jquery发起post请求 function sendPOST() { //1. 发请求,不带参数,不求响应 //$.post("../ajax"); //2. 发请求,带参数,不求响应 //$.post("../ajax" ,{username:"zhangsan",password:"12345678"} ); //3. 发请求,带参数,求响应 /* $.post : 发起post请求 参数一: 请求地址 参数二:请求的参数,这是一个json格式的数据 参数三: 回调函数,请求成功之后调用的函数,里面可以有一个参数data, (这个参数的名字随意,) 这个参数data就是服务器返回回来的数据 */ $.post("../ajax" ,{username:"zhangsan",password:"12345678"} ,function (data) { console.log("服务器返回:" + data); }) } </script> </head> <body> <!--使用JQuery发起Ajax请求(GET请求和POST请求)--> <input type="button" value="使用JQuery发起POST请求" onclick="sendPOST()"/><br/> </body> </html>
ajax()
语法
$.ajax([settings])
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../js/jquery-1.11.0.min.js"></script> <script> //使用JQuery的ajax发起get请求 function sendAjax() { //发请求。 $.ajax({ url:"../ajax", // 请求的地址 type:"GET", // 请求的方式 data:{username:"zhangsanfeng",password:66666}, //请求的参数 success:function(data){ //请求成功之后调用的函数 console.log("成功了:data=" + data); }, error:function(e){ //请求失败之后调用的函数。 console.log("失败了:e=" + e); console.log(e); } }); } </script> </head> <body> <!--使用JQuery发起Ajax请求(GET请求和POST请求)--> <input type="button" value="使用JQuery的ajax发请求" onclick="sendAjax()"/><br/> </body> </html>
JSON
JSON就是一个容易生成和解析的数据格式
常用作客户端(前端,IOS,安卓)和服务器(JavaEE)之间的数据交换 ,数据传输的载体。
定义方式:
对象形式:
{key:value,key:value...}
key是字符串
value是任意的合法数据类型
多个元素(key-value)之间使用 , 隔开,最后一个,不写
key和value之间使用 : 连接
数组形式:
[element1, element2, ...]
里面装的是json对象混合(嵌套)形式:以上两种类型任意混合
json对象的value,可以是任意类型,当然也可以是数组
数组里的element,可以是任意类型,当然也可以是json对象
解析语法:
获取json对象里的value值:
json对象.key
获取数组里指定索引的元素:
数组[索引]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!--解析对象形态的json--> <script> //1. 创建json对象 var jsonObject = {name:"张三",age:18 , address:"深圳湾1号对面的小房子",marry:false}; //2. 解析数据 解析json对象,语法: json对象.属性|key console.log("姓名=" + jsonObject.name); console.log("age=" + jsonObject.age); console.log("地址=" + jsonObject.address); console.log("婚否=" + jsonObject.marry); </script> <script> //1. 定义数组 var jsonArray = [ {name:"张三",age:18 , address:"灵芝公园对面的1号房子"}, {name:"李四",age:28 , address:"灵芝公园对面的2号房子"}, {name:"王五",age:38 , address:"灵芝公园对面的3号房子"} ]; //2. 解析数据 把李四的数据取出来打印 //2.1 根据下标取出来对应的数据,jsonarray里面存的是jsonobject var jsonObject = jsonArray[1]; //2.2 在对象身上取值即可 ,如果没有这个属性,那么返回的是undefined. console.log("姓名:" + jsonObject.name); console.log("年龄:" + jsonObject.age); console.log("地址:" + jsonObject.address); </script> <script> //1. 定义混合形式的json数据 var stu = { name:"张三", age:13, className:"三年二班", girlfriends:[ {name:'小红',age:8 , className:"一年一班"}, {name:'小花',age:9 , className:"二年一班"}, {name:'小翠',age:10 , className:"三年一班"} ] } //2. 取值: //张三的数据取出来 console.log("姓名:" + stu.name); console.log("年龄:" + stu.age); console.log("班级:" + stu.className); console.log("最后一个女朋友的数据:") var jsonObject = stu.girlfriends[2]; console.log("姓名:" + jsonObject.name); console.log("年龄:" + jsonObject.age); console.log("班级:" + jsonObject.className); </script> </body> </html>
常见JSON转换工具类
常见的转换工具有:
Jackson:SpringMVC内置的转换工具
jsonlib:Java提供的转换工具
gson:google提供的转换工具
fastjson:Alibaba提供的转换工具
Jackson转换工具
Jackson提供了转换的核心类:
ObjectMapper
ObjectMapper
的构造方法:无参构造
ObjectMapper
的常用方法:
方法 说明 writeValueAsString(Object obj)
把obj对象里的数据转换成json格式 readValue(String json, Class type)
把json字符串,还原成type类型的Java对象 User readValue(String json, 2reference)
把json字符串,还原成带泛型的复杂Java对象 List<User> 其中
TypeReference
,com.fasterxml.jackson.core.type.TypeReference
是一个抽象类,用于配置完整的泛型映射信息,避免泛型丢失的问题。用法示例:
// List<Integer> 类型的映射信息 TypeReference ref1 = new TypeReference<List<Integer>>() {}; // List<User> 类型的映射信息 TypeReference ref2 = new TypeReference<List<User>>() {}; // Map<String,User> 类型的映射信息 TypeReference ref3 = new TypeReference<Map<String,User>>(){};
Jackson使用示例
导入jar包 jackson-annotations-2.2.3.jar 和 jackson-core-2.2.3.jar 还有 jackson-databind-2.2.3.jar
public class TestJackson { // java对象 <--> json字符串 @Test public void testJava2Json() throws IOException { //1. 创建javaBean对象 User user = new User(1, "admin","123456","深圳"); //2. 创建ObjectMapper对象 ObjectMapper objectMapper = new ObjectMapper(); //3. 把对象转化成json字符串 String json = objectMapper.writeValueAsString(user); System.out.println("json=" + json); //========================================== //4. 把json字符串转化成java对象 User newUser = objectMapper.readValue(json, User.class); System.out.println("newUser=" + newUser); } // Map集合 <---> json字符串 @Test public void testMap2Json() throws Exception{ //1. 创建一个map集合 Map<String , Object> map = new HashMap<>(); map.put("name","张三"); map.put("age",18); map.put("user",new User(1,"admin","123456","深圳")); //2. 把map集合 ----> json字符串 ObjectMapper objectMapper = new ObjectMapper(); //把map集合转化成json字符串 String json = objectMapper.writeValueAsString(map); System.out.println("json=" + json); //============================================= //3. 把json字符串转化成map集合 Map newMap = objectMapper.readValue(json, Map.class); System.out.println("newMap=" + newMap); System.out.println(newMap.get("name")); System.out.println(newMap.get("age")); System.out.println(newMap.get("user")); //=================================================== //4. 使用typereferenct来转化json字符串到Map集合,顺便带上泛型 //4.1. 构建map的泛型类型 TypeReference<Map<String , Object>> tr = new TypeReference<Map<String , Object>>(){}; //4.2 把json转化成map集合 Map<String , Object> newMap2 = objectMapper.readValue(json, tr); System.out.println("newMap2=" + newMap2); } // List集合 <---> json字符串 @Test public void testList2Json() throws Exception{ //1. 创建一个List集合 List<User> list = new ArrayList<>(); list.add(new User(1, "zhangsan1","1231","深圳")); list.add(new User(2, "zhangsan2","1232","深圳")); list.add(new User(3, "zhangsan3","1233","深圳")); //2. 把list集合转化成json字符串 ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(list); System.out.println("json=" + json); //============================================================= //3. 把json字符串转化成list集合 //从后面的参数来看,我们仅仅是告诉了ObjectMapper ,把json字符串转化之后,丢到List集合里面去。 //跟本没有告诉它,转化出来的每一个元素|对象,用什么类型来装,所以ObjectMapper默认采用LinkedHashmap来装了 List newList = objectMapper.readValue(json , List.class); System.out.println("newList=" + newList); //假设在没有泛型的情况下,我们取值该怎么取? //User user = (User) newList.get(0); //这里会报错! //System.out.println(user.getId() + "= " + user.getUsername() + " = " + user.getPassword()); //4. 使用typereference来转化json字符串到list集合 TypeReference<List<User>> tr = new TypeReference<List<User>>(){}; //使用tr这种方式来转化,那么objectMapper就能够知道,转化的json字符串要装到List集合里面 //并且每一个元素都使用User来封装。 List<User> newList2 = objectMapper.readValue(json , tr); System.out.println("newList2=" + newList2); User user = newList2.get(0); System.out.println(user.getId() + "=" + user.getUsername() + "=" + user.getPassword()); } }
fastjson转换工具
fastjson提供了核心类:
JSON
JSON
提供了一些常用的==静态==方法:
方法 说明 toJSONString(Object obj)
把obj对象里的数据转换成json格式 parseObject(String json, Class type)
把json字符串,还原成type类型的Java对象 parseObject(String json, TypeReference reference)
把json字符串,还原成带泛型的复杂Java对象 其中
TypeReference
:com.alibaba.fastjson.TypeReference
是一个抽象类,用于配置完整的泛型映射信息,避免泛型丢失的问题。用法示例:
fastjson的使用示例
导入jar包:fastjson-1.2.39.jar
public class TestFastjson { //1. javabean <---> json @Test public void testJava2Json(){ //1. 创建一个对象 User user = new User(1, "张三","123456","北京"); //2. 把对象转化成json字符串 String json = JSON.toJSONString(user); System.out.println("json=" + json); //3. 把json字符串转化成javaBean User newUser = JSON.parseObject(json , User.class); System.out.println("newUser=" + newUser); } //2. Map <---> json @Test public void testMap2Json(){ //1. 创建map集合 Map<String , String> map = new HashMap<>(); map.put("a","aaa"); map.put("b","bbb"); map.put("c","ccc"); //2. map 转化成json字符串 String json = JSON.toJSONString(map); System.out.println("json=" + json); //3. json字符串转化成map集合 Map newMap = JSON.parseObject(json, Map.class); System.out.println("newMap=" + newMap); String value = (String) newMap.get("a"); System.out.println("value=" + value); //4. 也可以使用TypeReference来处理泛型。 TypeReference<Map<String,String>> tr = new TypeReference<Map<String,String>>(){}; Map<String,String> newMap2 = JSON.parseObject(json, tr); String valueC = newMap2.get("c"); System.out.println("valueC=" + valueC); } //3. List <---> json @Test public void testList2Json(){ //1. 创建List集合 List<User> list = new ArrayList<>(); list.add(new User(1, "admin1","123","北京")); list.add(new User(2, "admin2","456","上海")); list.add(new User(3, "admin3","789","深圳")); //2. 把list集合转化成json字符串 String json = JSON.toJSONString(list); System.out.println("json=" + json); //3. 把json字符串转化成list<User> List newList = JSON.parseObject(json , List.class); System.out.println("newList=" + newList); //没有泛型的基础上,取第0个元素的用户名 // 有错! com.alibaba.fastjson.JSONObject cannot be cast to com.itheima.bean.User //User user = (User) newList.get(0); //System.out.println("userName="+user.getUsername()); //4. 使用typereference来转化json字符串到list<User> TypeReference<List<User>> tr = new TypeReference<List<User>>(){}; List<User> newList2 = JSON.parseObject(json , tr); User user = newList2.get(0); System.out.println("username=" + user.getUsername()); } }
Vue
Vue.js是一个渐进式JavaScript 框架。Vue.js 的目标是通过尽可能简单的 API 实现数据和视图的绑定(数据发生改变,视图(页面)也发生改变 。 视图发生改变,数据也发生改变。)。它不仅易于上手,还便于与第三方库或既有项目整合。
MVVM模式 MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。
MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图UI 和业务逻辑分开. MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model)Vue.js 是一个提供了 MVVM 风格的==双向数据绑定==的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷.
使用示例
页面引入vuejs-2.5.16.js文件
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值表达式,Mustache 标签将会被替代为对应数据对象上属性的值。无论何时,绑定的数据对象上属性发生了改变,插值处的内容都会更新.
Vue.js 都提供了完全的 JavaScript 表达式支持。
{{ number + 1 }} {{flag?'true':'false'}}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../js/vuejs-2.5.16.js"></script> </head> <body> <!-- 使用插值表达式来显示vue对象里面的数据 {{数据的属性}}--> <div id="myDiv"> <span>{{username}}</span> <!--事件名称就是事件使用@取代掉on,也可以使用v-on:click=""的形式来写 方法后面的括号可以省略--> <input type="button" value="点我一下~" @click="clickBtn()"/> <!--当键盘按下的时候,执行handleKeyDown, $event 即表示捕获事件的对象,然后传递给方法--> <input type="text" id="myInput" @keydown="handleKeyDown($event)"/> </div> <!-- 需求: 使用vue来管理上面的span,然后让里面显示的内容,来自于vue对象。 1. 给span定义一个id 2. 创建vue对象,然后让它管理span标签 3. 定义一份数据 message 4. 在span标签里面使用这份数据 message --> <script> //1. 创建vue对象 vue对象里面的构造参数,要求的是json的格式。 v = new Vue({ el:"#myDiv", // 2. el,全称就是element,表示管理哪个标签 data:{ //data是这个vue对象里面的数据,随意定义。 username:"张三", password:"123456", age:18 }, methods:{ // vue对象里面可以定义很多方法。 methods 这是固定的语法。 clickBtn:function(){ //4. 定义一个方法,clickBtn是方法名(这个随意设置) ,右边就是方法的方法体。 this.name="李四"; }, handleKeyDown:function(e){ //e 就是事件的对象,全称 event console.log("键盘弹起了~~" + e.keyCode); if(e.keyCode < 48 || e.keyCode > 57){ // 48 - 57 正好表示的就是键盘的 0-9 console.log("进入了if..."); e.preventDefault(); //阻止事件的发生。 } } } }); </script> </body> </html>
v-text与v-html
v-text:输出文本内容,不会解析html元素, 会认为是纯文本
v-html:输出文本内容,会解析html元素 , 如果内容里面有HTML标签,那么会解析他们。
这两个东西把它当成标签的属性来用就可以了。它们两个不是写在标签的中间。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../js/vuejs-2.5.16.js"></script> </head> <body> <!-- 需求: 有3个div, 第一个div使用插值表达式来显示vue里面的message数据 第二个div使用v-text来显示vue里面的message数据 第三个div使用v-html来显示vue里面的mesage数据 message : <font color="red">黑马程序员111</font> vue能控制3个div吗?id不行! 尽可能的向上提升。在更大的一层标签上写id值。 --> <div id="myDiv"> <!--使用插值表达式取值 ,插值表达式不会解析里面的内容,原来是什么文字就显示什么文字--> <div>{{message}}</div> <!--使用v-text取值,要在标签里面写成属性的样子 , 只会当成纯文本来看待 v-xxx里面不需要写 {{}} ,否则会报错: invalid expression: Unexpected token '{' --> <div v-text="{{message}}"></div> <!--使用v-html取值,要在标签里面写成属性的样子 , 会解析内容,识别html标签--> <div v-html="message"></div> </div> <script> // 1. 创建vue对象 new Vue({ el: "#myDiv", //2. 管理最大的那个div data:{ //3. 定义数据 message:"<font color='red'>zml111</font>" } }); </script> </body> </html>
v-bind和v-model
插值语法不能作用在HTML 属性上,遇到这种情况应该使用 v-bind/v-model指令
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../js/vuejs-2.5.16.js"></script> </head> <body> <!-- 需求: 有一个font文字,它的颜色我们想使用vue来动态的控制 1. 不能直接在标签的属性里面取到vue里面的数据 2. 使用插值表达式不行,直接写数据的属性名字也不行! 3. 只有一种办法: 使用v-bind:标签属性="vue里面的数据属性" v-bind:color="myColor" 可以省略写为:color:="myColor" v-bind只能做单向绑定,也就是数据发生了改变,视图(标签|页面)也跟着改变 但是视图发生了改变,(vue里面的)数据可不会发生改变。 --> <div id="myDiv"> <font :color="myColor">zml111</font> <br/> <input type="text" v-bind:value="username"/> </div> <script> //1. 创建vue对象 v = new Vue({ el: "#myDiv", //2. 管理div data:{ //3. 定义数据 myColor:"red", username:"张三" } }); </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../js/vuejs-2.5.16.js"></script> </head> <body> <!-- 需求: 有一个form表单,里面有两个输入框: 用户名和密码,还有一个按钮。 1. 用户名和密码,显示的内容来自于vue里面的数据 2. 点击按钮了之后,去修改vue里面的数据,看一下输入框的内容是否发生了改变。 --> <form id="myForm"> {{user.username}} , {{user.password}} <br/> <!--用户名: <input type="text" v-bind:value="user.username"/><br/>--> <!--v-model主要是用来赋值和取值的,所以它针对的其实就是value属性,那么可以简写成v-model="xxx"--> 用户名: <input type="text" v-model="user.username"/><br/> 密 码: <input type="text" v-model:value="user.password"/><br/> <input type="button" value="点我改变内容" @click="changeData"/> </form> <script> //1. 创建vue对象 v = new Vue({ el:"#myForm" , //2. 让vue管理form表单 data:{ //3. 给vue定义一些数据 a:"aa", b:"bb", user:{ //标签里面要想使用用户名和密码,需要使用user.username | user.password username:"admin", password:"123456" } }, methods:{ changeData:function(){ //定义一个修改数据的方法,点击按钮的时候调用 //修改user的username 和 user的password //这里要注意: 一定要加上 this 或者 v对象。否则这个user就会被认为是这个function里面的一个局部变量。 //this 和 v是对等的。 this.user.username="王五"; v.user.password="66666"; } } }); </script> </body> </html>
v-for,v-if,v-show
v-for
用于操作array/集合,遍历
语法:
v-for="(元素,index) in 数组/集合"
,它的出现只会出现在属性上,也就是开始标签的里面。v-for 只能写在开始标签上,写在哪一个标签上,就表示遍历出来多个这样的标签
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../../js/vuejs-2.5.16.js"></script> </head> <body> <!-- 需求: 有一个无序列表,用于遍历显示我的爱好 v-for: 1. 要写在标签上。 2. 写在那个标签上,哪个 标签就会循环出现。 3. 语法: 3.1 v-for="(元素,索引) in 集合" 3.2 取值的时候,需要使用插值表达式 {{元素}} 3.3 如果对索引下标不感兴趣,那么可以有一种简写的方式 v-for="元素 in 集合" --> <ul id="myUL"> <!-- <li v-for="(e, i) in hobbys">{{i+1}} ===== {{e}}</li>--> <li v-for="a in hobbys">{{a}}</li> </ul> <script> //1. 创建vue对象 new Vue({ el :"#myUL", data:{ hobbys:["唱","跳","rap","敲代码"] } }); </script> </body> </html>
v-if与v-show
-
v-if 是根据表达式的值来决定是否渲染元素(标签都没有了)
-
v-show 是根据表达式的值来(决定是否显示)切换元素的display css属性(标签还在)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../../js/vuejs-2.5.16.js"></script>
</head>
<body>
<!--
需求:
有两个div , 下面使用两个按钮来控制着两个div的显示和隐藏
分别使用v-if和v-show 来控制着两个div的显示和隐藏。
v-show和v-if:
1. 它们两个指令要的值都是一个boolean值
2. 如果是true,那么标签能够显示出来
3. 如果是false,那么标签就不能够显示出来。
4. 它们两个的区别就是:
v-if : 直接不渲染这个标签,连源码都没有。
v-show: 渲染这个标签,只是通过设置了display:none 来控制它的隐藏。
-->
<div id="myDiv">
<div v-if="flag">这是第一个div</div>
<div v-show="flag">这是第二个div</div>
<input type="button" value="点我显示div" @click="show"/><br/>
<input type="button" value="点我隐藏div" @click="hide"/><br/>
</div>
<script>
//1. 创建vue对象
new Vue({
el:"#myDiv",//2. 管理mydiv
data:{ //3. 定义数据
flag:true
},
methods:{
show:function () {
//让flag值是true,那么页面就显示两个div‘
this.flag = true;
},
hide:function () {
//让flag值是false,那么页面就不显示两个div
this.flag = false;
}
}
});
</script>
</body>
</html>
VueJS生命周期
每个 Vue 实例在被创建到销毁都要经过一系列的初始化过程 的函数,这给了用户在不同阶段添加自己的代码的机会。 (钩子函数。创建对象的时候,就会执行类的构造函数...)
一般情况下 我们可以在==created或者mounted进行初始化(请求服务器获得数据绑定)==
beforeCreate :数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象
==created== :数据已经绑定到了对象实例,但是还没有挂载对象(使用ajax可在此方法中查询数据,调用函数)
beforeMount: 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的
el属性,el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创 建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点
==mounted==:将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们 就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并 进行各种操作当我们的data发生改变时,会调用beforeUpdate和updated方法
beforeUpdate :数据更新到dom之前,我们可以看到$el对象已经修改,但是我们页面上dom的数据还 没有发生改变
updated: dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到 dom上面,完成更新
beforeDestroy,destroyed :实例的销毁,vue实例还是存在的,只是解绑了事件的监听、还有watcher对象数据 与view的绑定,即数据驱动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>01_vue入门</title> <script src="js/vuejs-2.5.16.js"></script> </head> <body> <div id="app"> {{message}} </div> <script> /** * - beforeCreate :数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象 - created :数据已经绑定到了对象实例,但是还没有挂载对象(使用ajax可在此方法中查询数据,调用函数) - beforeMount: 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的 el属性,el属性是一个HTMLElement对象,也就是这个阶段,vue实例通过原生的createElement等方法来创 建这个html片段,准备注入到我们vue实例指明的el属性所对应的挂载点 - mounted:将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们 就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并 进行各种操作当我们的data发生改变时,会调用beforeUpdate和updated方法 - beforeUpdate :数据更新到dom之前,我们可以看到$el对象已经修改,但是我们页面上dom的数据还 没有发生改变 - updated: dom结构会通过虚拟dom的原则,找到需要更新页面dom结构的最小路径,将改变更新到 dom上面,完成更新 - beforeDestroy,destroed :实例的销毁,vue实例还是存在的,只是解绑了事件的监听、还有watcher对象数据 与view的绑定,即数据驱动 */ var vue = new Vue({ //表示当前vue对象接管了div区域 el: '#app', //定义数据 data: { message: 'hello word', }, //beforeCreate: 数据还没有监听,没有绑定到vue对象实例,同时也没有挂载对象 beforeCreate: function () { showMsg('---beforeCreate---', this); }, //created :数据已经绑定到了对象实例,但是还没有挂载对象 created: function () { showMsg('---created---', this); }, //beforeMount: 模板已经编译好了,根据数据和模板已经生成了对应的元素对象,将数据对象关联到了对象的 beforeMount: function () { showMsg('---beforeMount---', this); }, //mounted:将el的内容挂载到了el,相当于我们在jquery执行了(el).html(el),生成页面上真正的dom,上面我们就会发现dom的元素和我们el的元素是一致的。在此之后,我们能够用方法来获取到el元素下的dom对象,并进行各种操作当我们的data发生改变时,会调用beforeUpdate和updated方法 mounted: function () { showMsg('---mounted---', this); }, //beforeDestroy,destroed :实例的销毁,vue实例还是存在的,只是解绑了事件的监听、还有watcher对象数据与view的绑定,即数据驱动 beforeDestroy: function () { showMsg('---beforeDestroy---', this); } }); function showMsg(msg, obj) { console.log(msg); console.log("data:" + obj.message); console.log("el元素:" + obj.$el); console.log("元素的内容:" + document.getElementById("app").innerHTML); } //vue的销毁 vue.$destroy(); </script> </body> </html>
VueJS ajax
vue-resource
vue-resource是Vue.js的插件提供了使用XMLHttpRequest或JSONP (跨域)进行Web请求和处理响应的服务。 当vue更新到2.0之后,作者就宣告不再对vue-resource更新,而是推荐的axios,在这里大家了解一下vue-resource就可以。
vue-resource的github: [GitHub - pagekit/vue-resource: The HTTP client for Vue.js](
Axios
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中
注: Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。
axios的github:GitHub - axios/axios: Promise based HTTP client for the browser and node.js
中文说明: 使用说明 · Axios 中文说明 · 看云
使用前提:页面引入axios-0.18.0.js文件
get请求
// 为给定 ID 的 user 创建请求 axios.get('/user?ID=12345').then(function (response) { console.log(response); }).catch(function (error) { console.log(error); }); // 可选地,上面的请求可以这样做 axios.get('/user', { params: { //params是固定名字,不能改。 ID: 12345 } }).then(function (response) { console.log(response); }).catch(function (error) { console.log(error); });
- post请求
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }).then(function (response) { console.log(response); }).catch(function (error) { console.log(error); });
使用示例
// 创建实体对象 public class User { private String username; private String password; //.... } // 服务端代码 @WebServlet("/demo") public class DemoServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("DemoServlet...doGet..."); //1. 接数据 String username = req.getParameter("username"); String password = req.getParameter("password"); System.out.println(username + "=" + password); //2. 响应 resp.getWriter().write("success~!~"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("DemoServlet...doPost..."); //由于前端使用axios提交了数据,导致后台使用普通的getParameter方法取不到数据,要想取数据,就需要自己手动转化 /* //=================把页面提交过来的数据封装成一个Map集合========================== //1. 先获取输入流,因为post请求写过来数据是采用流的方式写过来的。 InputStream is = req.getInputStream(); //2. 把这个输入流转化成一个Map集合。 Map map = JSON.parseObject(is , Map.class); String username = (String) map.get("username"); String password = (String) map.get("password"); //3. 打印map System.out.println("map=" + map); System.out.println(username+"=" + password);*/ //=================把页面提交过来的数据封装成一个Bean============================ //1. 先获取输入流 InputStream is = req.getInputStream(); //2. 把输入流转化成一个Bean User user = JSON.parseObject(is , User.class); //3. 打印user System.out.println("user=" + user); //响应: resp.getWriter().write("post...success~!~"); } }
get请求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../js/vuejs-2.5.16.js"></script> <script src="../js/axios-0.18.0.js"></script> <!-- 一般把axios放在vue的后面--> </head> <body> <div id="myDiv"> <input type="button" value="点我发起GET请求" @click="sendGET"/> </div> <!-- 需求: 点击按钮,发请求给DemoServlet --> <script> //1. 创建vue对象 new Vue({ el:"#myDiv", //2. 管理div methods:{ sendGET:function () { //1. 发请求,不带数据,不求响应 // axios.get("../demo"); //2. 发请求,带数据,不求响应 //axios.get("../demo?username=admin&password=123456") //3. 发请求,带数据,不求响应 也可以使用一个单独的位置来传递数据 params这是固定的格式,不能改。 /*axios.get("../demo" , { params:{username:"admin",password:"666"} //params必须收一个json对象 } );*/ //4. 发请求,带数据,求响应 //4.1 响应回来的resposne : {data: "success~!~", status: 200, statusText: "", headers: {…}, config: {…}, …} //真正写出来的数据是 data这个属性。 //4.2 then : 请求成功之后执行的代码 //4.3 catch :请求失败之后执行的代码。 axios.get("../d234emo?username=zhangsan&password=123").then(function (response) { console.log("请求成功~~~"+response); console.log(response.data); }).catch(function (e) { //e : Error: Request failed with status code 404 console.log("请求失败~~"+e); }); } } }); </script> </body> </html>
post请求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../js/vuejs-2.5.16.js"></script> <script src="../js/axios-0.18.0.js"></script> <!-- 一般把axios放在vue的后面--> </head> <body> <div id="myDiv"> <input type="button" value="点我发起POST请求" @click="sendPOST"/> </div> <!-- 需求: 点击按钮,发请求给DemoServlet --> <script> //1. 创建vue对象 new Vue({ el:"#myDiv", //2. 管理div methods:{ sendPOST:function () { //1. 发请求,不带数据,不求响应 // axios.post("../demo") //2. 发请求,带数据,不求响应 //axios.post("../demo" ,{username:"admin" , password:"123456"}); //3. 发请求,带数据,求响应 axios.post("../demo",{username:"zhangsan",password:"66666"}).then(function (response) { //response代表一个对象,包含的东西很多,如果想看服务器返回的结果,就看response里面的data属性 console.log("请求成功:" + response.data); }).catch(function () { console.log("请求失败~"); }) } } }); </script> </body> </html>
综合案例
显示所有联系人案例显示所有联系人案例
// 创建实体类对象 public class LinkMan implements Serializable{ private int id; private String name; private String sex; //... } // 前端响应实体封装对象 public class Result implements Serializable{ private boolean flag; private String message; private Object result; //... } //查询所有联系人 private void findAll(HttpServletRequest req, HttpServletResponse resp){ try { //1. 直接调用service LinkManService service = new LinkManService(); List<LinkMan> list = service.findAll(); System.out.println("list=" + list); Result result; if(list !=null ){ //成功了 result = new Result(true , "查询成功" , list); }else{ result = new Result(false , "查询失败"); } resp.getWriter().write(JSON.toJSONString(result)); /* //2. 把list集合变成json数据 String json = JSON.toJSONString(list); //3. 直接把数据写出去就行。 resp.getWriter().write(json);*/ } catch (Exception throwables) { throwables.printStackTrace(); } } //添加联系人,需要传递req和resp对象过来。 public void add(HttpServletRequest req, HttpServletResponse resp){ try { //1. 获取所有参数 InputStream is = req.getInputStream(); LinkMan linkMan = JSON.parseObject(is , LinkMan.class); //2. 交代service干活 LinkManService service = new LinkManService(); int row = service.add(linkMan); //3. 响应 ,判定结果 if(row > 0 ){ //添加成功 //要告诉前端结果是怎样的。 resp.getWriter().write("success"); } } catch (Exception e) { e.printStackTrace(); } } //根据id查询 public void findByUid(HttpServletRequest request, HttpServletResponse response) throws IOException { ObjectMapper objectMapper = new ObjectMapper(); String data=null; ResultInfo resultInfo = null; try { //1.调用业务 获得List<linkMan> int uid = Integer.parseInt(request.getParameter("uid")); LinkMan linkMan = linkManService.findByUid(uid); //2.转成json resultInfo = new ResultInfo(true,linkMan,"查询成功"); } catch (Exception e) { e.printStackTrace(); resultInfo = new ResultInfo(false,"查询失败"); }finally { data = objectMapper.writeValueAsString(resultInfo); response.getWriter().print(data); } } //更新联系人 private void update(HttpServletRequest request, HttpServletResponse response) throws IOException { try { //1.获得请求参数,封装成LinkMan对象 LinkMan linkMan = JsonUtils.parseJSON2Object(request, LinkMan.class); //2.调用业务, 进行新增 linkManService.add(linkMan); //3.封装Result, 响应 Result result = new Result(true, "更新成功"); JsonUtils.printResult(response,result); } catch (Exception e) { e.printStackTrace(); //3.封装Result, 响应 Result result = new Result(false, "更新失败"); JsonUtils.printResult(response,result); } }
前端页面
<tr v-for="(linkMan , i) in linkMans"> <td>{{i+1}}</td> <td>{{linkMan.name}}</td> <td>{{linkMan.sex}}</td> <td>{{linkMan.age}}</td> <td>{{linkMan.address}}</td> <td>{{linkMan.qq}}</td> <td>{{linkMan.email}}</td> <td><a class="btn btn-default btn-sm" href="修改联系人.html">修改</a> <a class="btn btn-default btn-sm" href="#" @click="deleteLinkMan(linkMan.id)">删除</a></td> </tr> <script> new Vue({ el:"#myDiv", data:{ linkMans:[] }, created:function(){ //3. 当vue对象创建完毕之后,发请求 //4. 发请求 /**/ axios.get("linkMan?method=findAll").then(function (response) { //5. 把服务器响应回来的数据,直接赋值给linkMans v.linkMans = response.data; //在axios里面的请求回调函数里面,this不代表vue对象,因为这个方法是回调函数, //谁调用了这个方法,那么这里的this就是谁。它是window对象。 //this.linkMans = response.data; console.log("==="); console.log(this) console.log("==="); }); // 使用下面这种方式的话this对象就是vue对象了 /* axios.get("linkMan?method=findAll").then(response =>{ this.linkMans = response.data; console.log("==="); console.log(this) console.log("==="); }); */ }); </script>
添加联系人
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!-- HTML5文档--> <!DOCTYPE html> <!-- 网页使用的语言 --> <html lang="zh-CN"> <head> <!-- 指定字符集 --> <meta charset="utf-8"> <!-- 使用Edge最新的浏览器的渲染方式 --> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。 width: 默认宽度与设备的宽度相同 initial-scale: 初始的缩放比,为1:1 --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>添加用户</title> <!-- 1. 导入CSS的全局样式 --> <link href="css/bootstrap.min.css" rel="stylesheet"> <!-- 2. jQuery导入,建议使用1.9以上的版本 --> <script src="js/jquery-2.1.0.min.js"></script> <!-- 3. 导入bootstrap的js文件 --> <%--导入vue和axios的js库--%> <script src="js/vuejs-2.5.16.js"></script> <script src="js/axios-0.18.0.js"></script> <script src="js/bootstrap.min.js"></script> </head> <body> <div class="container" id="myDiv"> <center><h3>添加联系人页面</h3></center> <form action="linkMan?method=add" method="post"> <div class="form-group"> <label for="name">姓名:</label> <input type="text" v-model:value="linkman.name" class="form-control" id="name" name="name" placeholder="请输入姓名"> </div> <div class="form-group"> <label>性别:</label> <input type="radio" name="sex" v-model:value="linkman.sex" value="男" checked="checked"/>男 <input type="radio" name="sex" v-model:value="linkman.sex" value="女"/>女 </div> <div class="form-group"> <label for="age">年龄:</label> <input type="text" v-model:value="linkman.age" class="form-control" id="age" name="age" placeholder="请输入年龄"> </div> <div class="form-group" style="text-align: center"> <input class="btn btn-primary" type="button" value="提交" @click="sendData"/> <input class="btn btn-default" type="reset" value="重置" /> <input class="btn btn-default" type="button" value="返回" /> </div> </form> </div> <script> //1. 创建vue对象 new Vue({ el:"#myDiv" , // 2. 表示管理div标签 data:{ linkman:{sex:'男'} // 页面中设置的checked属性无效,如果需要设定默认值的话,直接给属性赋值 }, methods:{ sendData:function () { //3. 在这里面发请求。 //参数一: 提交的地址, //参数二: 提交的数据。{username:"admin",password:"123456"} //如何获得页面上的表单标签的数据呢? 需要一个data属性与他们进行双向绑定。 axios.post("linkMan?method=add", this.linkman).then(function (response) { //4. 判断回来的结果: if(response.data == "success"){ //跳转到list.jsp location.href="list.jsp"; } }).catch(function () { alert("添加失败!"); }) } } }); </script> </body> </html>
更新联系人
<script> var uid = getParameter("uid"); //创建vue实例 var vue = new Vue({ el: "#app", data: { linkMan: {} }, methods: { // 点击修改按钮发送请求的方法 update:function () { axios.post('linkMan?method=update', this.linkMan).then(response=>{ if (response.data.flag){ location.href = "list.html"; }else{ alert(response.data.message) } }); } }, // 当vue对象创建完毕发送请求 created:function () { axios.get('linkMan?method=findByUid&uid='+uid).then(response=>{ if(response.data.flag){ this.linkMan = response.data.result; }else{ alert(response.data.message); } }) } }); </script>