一、VueJS概述与快速入门
1.1 介绍
一个构建数据驱动的web界面的渐进式其框架,Vue.js的目标提供尽可能简单的API就可以满足我们的日常开发,官网:https://cn.vuejs.org/。学习此框架需要有HTML、CSS和JavaScript的一些基础。
1.2 MVVM模式
MVVM是Modle-View-ViewModel的简写,是MVC的改进版。MVVM就是将其中View的状态和行为抽象化,让我们将视图(html和dom元素)和业务逻辑分开,分开后我们直接曹组模型数据就等同于html的dom元素。
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model)。
Vue.js是一个提供了MVVM风格的双向数据绑定的JavaScript库,专注于View层。它的核心是MVVM中的VM,也就是ViewModle。ViewModel负责连接View和Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。
1.3 VueJS快速入门
首先需要在官网上下载一个vuejs的文件,这个自己操作一下,接着创建一个html文件
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>vue入门</title>
6 <script src = "js/vuejs-2.5.16.js"></script>
7 </head>
8 <body>
9 <div id="app">
10 {{message}}
11 </div>
12 <script>
13 new Vue({
14 el:'#app', //表示当前vue对象接管了div区域
15 data:{
16 message:'hello vue' //注意不要写分号结尾
17 }
18 });
19 </script>
在浏览器中打开

1.4 插值表达式
数据绑定最常见的形式就是使用"Mustache"语法(双大括号)的文本插值,Mustache标签会被替代为对应数据对象上的属性的值。当绑定对象上属性发生变化是,插值处的内容都会更新。
Vue.js都提供了完全的对JavaScript表达式的支持。
{{ number + 1}}
{{ true ? 'YES' : 'NO'}}
这些表达式会在所属Vue实例的数据作用域下作为JavaScript被解析。有个限制是每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
1 <!-- 这是语句,不是表达式 -->
2 {{ var a = 1}}
3 <!-- 流控制也不会生效,请使用三元表达式 -->
4 {{ if (ok) { return message } }}
示例:
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8"/>
5 <title>vue插值表达式</title>
6 <script src="js/vuejs-2.5.16.js"></script>
7 </head>
8 <body>
9 <div id="app">
10 <!--Vue的插值表达式,把data中定义的数据显示到此处-->
11 {{message}}<br>
12 <!-- 三元运算符 -->
13 {{ true ? "OK" : "No" }}<br>
14 <!-- 数学运算-->
15 {{number*3.14}}<br>
16 </div>
17 </body>
18 <script>
19 // 创建Vue对象
20 new Vue({
21 el: "#app",// 由vue接管id为app区域
22 data: {
23 message: "Hello Vue!",//注意:此处不要加分号
24 number: 100
25 }
26 });
27 </script>
28 </html>

二、VueJS常用系统指令
2.1 v-on
使用v-on指令监听DOM时间,并在触发时运行一些JavaScript代码
1. v-on:click
1 <!DOCTYPE html>
2 <html xmlns:v-on="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta charset="utf-8" />
5 <title>v-on:click</title>
6 <script src="js/vuejs-2.5.16.js"></script>
7 </head>
8 <body>
9 <div id="app">
10 {{message}}
11 <button v-on:click="fun1('Vue v-on')">vue的onclick</button>
12 </div>
13 </body>
14 <script>
15 new Vue({
16 el:"#app",
17 data:{
18 message:"Hello Vue!"
19 },
20 methods:{
21 fun1:function(msg){
22 alert("Hello");
23 this.message = msg;
24 }
25 }
26 });
27 </script>
28 </html>



2.v-on:keydown
1 <!DOCTYPE html>
2 <html xmlns:v-on="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta charset="utf-8"/>
5 <title>v-on:keydown</title>
6 <script src="js/vuejs-2.5.16.js"></script>
7 </head>
8
9 <body>
10 <div id="app">
11 Vue:<input type="text" v-on:keydown="fun($event)">
12 <hr/>
13 传统JS:<input type="text" onkeydown="showKeyCode()"/>
14 </div>
15 </body>
16 <script>
17 new Vue({
18 el: "#app",
19 methods: {
20 /* $event 它是vue中的事件对象 和我们传统js的event对象是一样的 */
21 fun: function (event) {
22 var keyCode = event.keyCode;
23 if (keyCode < 48 || keyCode > 57) {// 48是字符0对应的ASCII值,57是字符9对应的ASCII值
24 // 不让键盘的按键起作用
25 event.preventDefault();
26 }
27 }
28 }
29 });
30
31 // 传统js的键盘按下事件
32 function showKeyCode() {
33 // event对象和我们的document对象以及window对象是一样的,可以不用定义直接使用
34 var keyCode = event.keyCode;
35 if (keyCode < 48 || keyCode > 57) {
36 //不让键盘的按键起作用
37 event.preventDefault();
38 }
39 }
40 </script>
41 </html>

发现一个小问题,当我们使用中文输入法的时候文本框内是可以填充进我们输入的汉字或英文字符,但是在英文输入法的情况下则不会,有人补充的话可以留言。
3.v-on:mouseover
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <title>v-on:mouseover</title>
6 <style>
7 #div {
8 background-color: green;
9 width:300px;
10 height:64px;
11 }
12 </style>
13 <script src="js/vuejs-2.5.16.js"></script>
14 </head>
15
16 <body>
17 <div id="app">
18 <div @mouseover="fun1" id="div">
19 <textarea @mouseover="fun2($event)">这是一个文本域</textarea>
20 </div>
21 </div>
22 </body>
23 <script>
24 /**
25 * @事件名称 就是 v-on:事件名称的简写方式
26 * @mouseover它就等同于v-on:mouseover
27 */
28 new Vue({
29 el:"#app",
30 methods:{
31 fun1:function(){
32 alert("鼠标悬停在div上了");
33 },
34 fun2:function(event){
35 alert("鼠标悬停在textarea上了");
36 event.stopPropagation();
37 }
38 }
39 });
40 //传统的js方式
41 function divmouseover(){
42 alert("鼠标移动到了div上了");
43 }
44 function textareamouseover(){
45 alert("鼠标移动到了textarea上了");
46 event.stopPropagation();
47 }
48 </script>
49
50 </html>
4.事件修饰符
Vue.js为v-on提供了时间修饰符来处理DOM事件细节,如event。preventDefault()或event.stopPropagation().
Vue.js通过有点(.)表示指令后缀来调用修饰符。
- .stop
- .prevent
- capture
- .self
- .once
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>v-on:事件修饰符</title>
<script src="js/vuejs-2.5.16.js"></script>
</head>
<body>
<div id="app">
<form @submit.prevent action="https://www.cnblogs.com" method="post">
<input type="submit" value="提交">
</form>
</div>
</body>
</html>
5.按键修饰符
Vue允许为v-on在监听键盘事件时添加按键修饰符
全部的按键别名:
- .enter
- .tab
- .delete(捕获“删除”和“退格”键)
- .esc
- .space
- .up
- .down
- .left
- .right
- .ctrl
- .alt
- .shift
- .meta
1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="utf-8" />
6 <title>v-on:按键修饰符</title>
7
8 <script src="js/vuejs-2.5.16.js"></script>
9 </head>
10
11 <body>
12 <div id="app">
13 Vue:<input type="text" @keydown.enter="fun1">
14 </div>
15 </body>
16 <script>
17 //view model
18 new Vue({
19 el:"#app",
20 methods:{
21 fun1:function(){
22 alert("按下的是回车");
23 }
24 }
25 });
26 </script>
27
28 </html>
v-on简写方式
1 <!-- 完整与法 --> 2 <a v-on:click = "doSomething">...</a> 3 <!-- 简写 --> 4 <a @click = "doSomething">...</a>
2.2 v-text与v-html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <title>v-text与v-html</title>
6 <script src="js/vuejs-2.5.16.js"></script>
7 </head>
8 <body>
9 <div id="app">
10 <div v-text="message"></div>
11 <div v-html="message"></div>
12 </div>
13 </body>
14 <script>
15 new Vue({
16 el:"#app",
17 data:{
18 message:"<h1>Hello Vue</h1>"
19 }
20 });
21 // 传统js的innerText和innerHTML
22 window.onload = function(){
23 document.getElementById("div1").innerHTML="<h1>Hello</h1>";
24 document.getElementById("div2").innerText="<h1>Hello</h1>";
25 }
26 </script>
27 </html>
2.3 v-bind
插值语法不能作用在HTML特性上,遇到这种情况需要使用到v-bind指令
1 <!DOCTYPE html>
2 <html xmlns:v-bind="http://www.w3.org/1999/xhtml">
3
4 <head>
5 <meta charset="utf-8" />
6 <title>v-bind的使用</title>
7 <script src="js/vuejs-2.5.16.js"></script>
8 </head>
9
10 <body>
11 <div id="app">
12 <font size="5" v-bind:color="ys1">不为</font><br>
13 <font size="5" :color="ys2">不为</font>
14 </div>
15 </body>
16 <script>
17 // 插值表达式不能用于html标签的属性取值
18 // 要想给html标签的属性设置变量的值,需要使用v-bind
19 // v-bind也可以简化写法,直接使用:
20 new Vue({
21 el:"#app",
22 data:{
23 ys1:"red",
24 ys2:"green"
25 }
26 })
27 </script>
28
29 </html>
v-bind的两种写法
1 <!-- 完整写法 --> 2 <a v-bind:href = "url">这是一个超链接</a> 3 <!-- 简写 --> 4 <a :href = "url">这也是一个超链接</a>
2.4 v-model
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <title>v-model</title>
6 <script src="js/vuejs-2.5.16.js"></script>
7 </head>
8 <body>
9 <div id="app">
10 <form action="" method="post">
11 用户名:<input type="text" name="username" v-model="user.username"><br/>
12 密码:<input type="text" name="password" v-model="user.password"><br/>
13 </form>
14 </div>
15 </body>
16 <script>
17 new Vue({
18 el:"#app",
19 data:{
20 user:{
21 username:"buwei",
22 password:"1234"
23 }
24 }
25 })
26 </script>
27 </html>
2.5 v-for
- 操作array
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <title>v-for遍历数组</title>
6 <script src="js/vuejs-2.5.16.js"></script>
7 </head>
8 <body>
9 <div id="app">
10 <ul>
11 <li v-for="(item,index) in arr ">{{item}}={{index}} </li>
12 </ul>
13 </div>
14 </body>
15 <script>
16 new Vue({
17 el:"#app",
18 data:{
19 arr:[1,2,3,4,5]
20 }
21 })
22 </script>
23 </html>
- 操作对象
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <title>v-for遍历对象</title>
6 <script src="js/vuejs-2.5.16.js"></script>
7 </head>
8 <body>
9 <div id="app">
10 <ul>
11 <li v-for="(key,value) in product ">{{value}}:{{key}}</li>
12 </ul>
13 </div>
14 </body>
15 <script>
16 new Vue({
17 el:"#app",
18 data:{
19 product:{
20 id:1,
21 name:"笔记本电脑",
22 price:5000
23 }
24 }
25 })
26 </script>
27 </html>
- 操作对象数组
1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="utf-8" />
6 <title>v-for遍历对象</title>
7 <script src="js/vuejs-2.5.16.js"></script>
8 </head>
9
10 <body>
11 <div id="app">
12 <table border="1">
13 <tr>
14 <td>序号</td>
15 <td>id</td>
16 <td>名称</td>
17 <td>价格</td>
18 </tr>
19 <tr v-for="(product,index) in products ">
20 <td>{{index}}</td>
21 <td>{{product.id}}</td>
22 <td>{{product.name}}</td>
23 <td>{{product.price}}</td>
24 </tr>
25 </table>
26 </div>
27 </body>
28 <script>
29 new Vue({
30 el:"#app",
31 data:{
32 products:[
33 { id:1,name:"笔记本",price:5000 },
34 { id:2,name:"手机",price:3000 },
35 { id:3,name:"电视",price:4000 }
36 ]
37 }
38 })
39 </script>
40 </html>
2.6 v-if与v-show
v-if是根据表达式的值来决定是否渲染元素
v-show是根据表达式的值来切换元素的display css属性
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <title>v-if与v-show</title>
6 <script src="js/vuejs-2.5.16.js"></script>
7 </head>
8 <body>
9 <div id="app">
10 <span v-if="flag">你看不到我</span><br>
11 <span v-show="flag">you can't see me</span><br>
12 <button @click="toggle">切换</button>
13 </div>
14 </body>
15 <script>
16 //view model
17 new Vue({
18 el:"#app",
19 data:{
20 flag:true
21 },
22 methods:{
23 toggle:function(){
24 this.flag = !this.flag;
25 }
26 }
27 })
28 </script>
29 </html>
三、VueJS的生命周期
每个Vue实例在被创建之前都要经过一系列的初始化过程。

vue在生命周期中有以下八种状态:
beforCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。Vue在实例化的过程中,会调用这些生命周期的钩子,给我们提供执行自定义逻辑的机会。通过下面的例子,我们可以看下vue实例执行了哪些操作。
1 <!DOCTYPE html>
2 <html>
3
4 <head>
5 <meta charset="utf-8" />
6 <title>vuejs生命周期</title>
7 <script src="js/vuejs-2.5.16.js"></script>
8 </head>
9
10 <body>
11 <div id="app">
12 {{message}}
13 </div>
14 </body>
15 <script>
16 var vm = new Vue({
17 el: "#app",
18 data: {
19 message: 'hello world'
20 },
21 beforeCreate: function() {
22 console.log(this);
23 showData('创建vue实例前', this);
24 },
25 created: function() {
26 showData('创建vue实例后', this);
27 },
28 beforeMount: function() {
29 showData('挂载到dom前', this);
30 },
31 mounted: function() {
32 showData('挂载到dom后', this);
33 },
34 beforeUpdate: function() {
35 showData('数据变化更新前', this);
36 },
37 updated: function() {
38 showData('数据变化更新后', this);
39 },
40 beforeDestroy: function() {
41 vm.test = "3333";
42 showData('vue实例销毁前', this);
43 },
44 destroyed: function() {
45 showData('vue实例销毁后', this);
46 }
47 });
48
49 function realDom() {
50 console.log('真实dom结构:' + document.getElementById('app').innerHTML);
51 }
52
53 function showData(process, obj) {
54 console.log(process);
55 console.log('data 数据:' + obj.message)
56 console.log('挂载的对象:')
57 console.log(obj.$el)
58 realDom();
59 console.log('------------------')
60 console.log('------------------')
61 }
62 // vm.message = "hello cnblog";
63 // vm.$destroy();
64 </script>
65
66 </html>
vue对象在初始化过程中,会执行到beforeCreate、created、beforeMount、mounted 等几个状态。 -- 需要在浏览器的console控制台中查看,代码62,63行后面步骤中解开继续查看。
- beforeCreate:数据还没有监听,没有绑定到Vue实例对象,同时也没有挂载对象
- created:数据已经绑定到了对象实例,但是还没有挂载对象
- 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的绑定,即数据驱动。
四、VueJS ajax
4.1 vue-resource
vue-resource是Vue.js的插件提供了使用XMLHttpRequest或JSONP进行Web请求和处理响应的服务。当vue更新到了2.0之后,vue-resource停止更新,使用axios,所以这里仅做了解。
vue-resource的github:https://github.com/pagekit/vue-resource
4.2 axios
Axios是一个基于promise的Http库,可以用在浏览器和node.js中
axios的github:https://github.com/axios/axios,上面有我们使用时需要的请求格式
1.引入axios
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
2.get请求
1 //通过给定的ID来发送请求
2 axios.get('/user?ID=12345')
3 .then(function (response) {
4 console.log(response);
5 })
6 .catch(function (err) {
7 console.log(err);
8 });
9 //以上请求也可以通过这种方式来发送
10 axios.get('/user', {
11 params: {
12 ID: 12345
13 }
14 })
15 .then(function (response) {
16 console.log(response);
17 })
18 .catch(function (err) {
19 console.log(err);
20 });
3.post请求
1 axios.post('/user', {
2 firstName: 'Fred',
3 lastName: 'Flintstone'
4 })
5 .then(function (res) {
6 console.log(res);
7 })
8 .catch(function (err) {
9 console.log(err);
10 });
为方便起见,为所有支持的请求方法提供了别名
1 axios.request(配置) 2 axios.get(url [,config]) 3 axios.delete(url [,config]) 4 axios.head(url [,config]) 5 axios.options(url [,config]) 6 axios.post(url [,data [,config]]) 7 axios.put(url [,data [,config]]) 8 axios.patch(url [,data [,config]]) 9 使用别名方法时url,不需要在config中指定method和data属性。
以上均摘自官网,大家可以自行上官网查看。。。。
五、综合案例
5.1 案例需求
使用SpringBoot结合vuejs完成信息的查询与修改操作
5.2 数据库的设计与表结构
1 CREATE DATABASE vuejsdemo; 2 USE vuejsdemo; 3 CREATE TABLE USER( 4 id INT PRIMARY KEY AUTO_INCREMENT, 5 age INT, 6 username VARCHAR(20), 7 PASSWORD VARCHAR(50), 8 email VARCHAR(50), 9 sex VARCHAR(20) 10 )
这里手动填充一些数据到表里面

5.3 使用idea快速生成一个SpringBoot框架的工程
自动生成SpringBootVue.js类
1 @SpringBootApplication
2 public class SpringBootVuejsApplication {
3
4 public static void main(String[] args) {
5 SpringApplication.run(SpringbootVuejsApplication.class, args);
6 }
7 }
创建User类,对应数据库中的表字段
1 public class User {
2
3 private Integer id;
4
5 private String username;
6
7 private String password;
8
9 private String sex;
10
11 private int age;
12
13 private String email;
14
15 // 省略getter/setter
16 }
持久层使用mybatis,pom.xml中引入mybatis与数据库连接依赖坐标
1 <!--mybatis起步依赖--> 2 <dependency> 3 <groupId>org.mybatis.spring.boot</groupId> 4 <artifactId>mybatis-spring-boot-starter</artifactId> 5 <version>1.1.1</version> 6 </dependency> 7 8 <!-- MySQL连接驱动 --> 9 <dependency> 10 <groupId>mysql</groupId> 11 <artifactId>mysql-connector-java</artifactId> 12 </dependency>
application.properties配置文件
1 #DB Configuration: 2 spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver 3 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/vuejsdemo?serverTimezone=UTC 4 useUnicode=true&characterEncoding=utf8 5 spring.datasource.username=root 6 spring.datasource.password=root 7 8 #spring集成Mybatis环境 9 #pojo别名扫描包 10 mybatis.type-aliases-package=com.buwei.entity 11 #加载Mybatis映射文件 12 mybatis.mapper-locations=classpath:com/buwei/mapper/*Mapper.xml
UserMapper接口
1 @Mapper
2 public interface UserMapper {
3 /**
4 * 查询所有
5 * @return
6 */
7 public List<User> findAll();
8
9 /**
10 * 根据id查询一个
11 * @return
12 * @param i
13 */
14 public User findById(Integer userId);
15
16 /**
17 * 修改信息
18 */
19 public void updateUserInfo(User user);
20 }
userMapper.xml文件
1 <?xml version="1.0" encoding="utf-8" ?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
4 <mapper namespace="com.buwei.mapper.UserMapper">
5 <select id="findAll" resultType="user">
6 select * from user
7 </select>
8 <select id="findById" parameterType="int" resultType="user">
9 select * from user where id = #{id}
10 </select>
11 <update id="updateUserInfo" parameterType="user">
12 update user set username=#{username},password=#{password},
13 sex=#{sex},age=#{age},email=#{email} where id=#{id}
14 </update>
15 </mapper>
--------------------------------------------------此部分完成后记得测试一下--------------------------------------------------
- 测试类可以使用idea快速生成将光标定位到写的UserMapper接口中
- 然后点击导航栏navigate——>test——>create new test——>填写测试类的一些信息
- 然后就神奇的发生了,我们在接口中定义的方法对应的测试方法已经生成,大家稍微补充一下就可以了
UserService接口
1 public interface UserService {
2 /**
3 * 查询所有
4 * @return
5 */
6 public List<User> findAll();
7
8 /**
9 * 根据id查询一个
10 * @return
11 * @param userId
12 */
13 public User findById(Integer userId);
14
15 /**
16 * 修改信息
17 */
18 public void updateUserInfo(User user);
19 }
实现类userServiceImpl
1 @Service
2 public class UserServiceImpl implements UserService {
3
4 @Autowired
5 private UserMapper userMapper;
6 @Override
7 public List<User> findAll() {
8 return userMapper.findAll();
9 }
10
11 @Override
12 public User findById(Integer userId) {
13 return userMapper.findById(userId);
14 }
15
16 @Override
17 public void updateUserInfo(User user) {
18 userMapper.updateUserInfo(user);
19 }
20 }
UserController
1 @RestController
2 @RequestMapping("/user")
3 public class UserController {
4
5 @Autowired
6 private UserService userService;
7
8 /**
9 * 查询所有用户信息
10 * @return
11 */
12 @RequestMapping("/findAll")
13 public List<User> findAll() {
14 return userService.findAll();
15 }
16
17 /**
18 * 查询一个用户信息
19 * @param id
20 * @return
21 */
22 @RequestMapping("/findById")
23 public User findById(Integer id) {
24 User user = userService.findById(id);
25 System.out.println(user.getUsername());
26 return userService.findById(id);
27 }
28
29 /**
30 * 修改用户信息
31 * @param user
32 */
33 @RequestMapping("/updateUserInfo")
34 public void updateUserInfo(@RequestBody User user) {
35 userService.updateUserInfo(user);
36 }
37
38 }
静态页面user.html -- 其中的模态窗口使用的是Bootstrap 模态框(Modal)插件完成的
除了上面的BootStrap模态框插件,同时需引入vuejs-2.5.16.js和axios-0.18.0.js以及后面定义的user.js文件
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>VueJS测试案例</title>
6 <!-- 模态框插件 -->
7 <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
8 <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
9 <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
10 <!-- 模态框插件结束 -->
11 </head>
12 <body>
13 <div id="app">
14 <table id="dataList">
15 <thead>
16 <tr>
17 <th>ID</th>
18 <th>用户名</th>
19 <th>密码</th>
20 <th>性别</th>
21 <th>年龄</th>
22 <th>邮箱</th>
23 <th>操作</th>
24 </tr>
25 </thead>
26 <tbody>
27 <tr v-for="u in userList">
28 <td>{{u.id}}</td>
29 <td>{{u.username}}</td>
30 <td>{{u.password}}</td>
31 <td>{{u.sex}}</td>
32 <td>{{u.age}}</td>
33 <td>{{u.email}}</td>
34 <td>
35 <button data-toggle="modal" data-target="#myModal"
36 @click="findById(u.id)">编辑
37 </button>
38 </td>
39 </tr>
40 </tbody>
41
42 <!-- 模态窗口 -->
43 <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
44 aria-hidden="true">
45 <div class="modal-dialog">
46 <div class="modal-content">
47 <div class="modal-header">
48 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
49 ×
50 </button>
51 <h4 class="modal-title" id="myModalLabel">用户信息</h4>
52 </div>
53 <div class="modal-body">
54 <label>用户名:</label>
55 <div>
56 <input type="text" v-model="user.username">
57 </div>
58 </div>
59 <div class="modal-body">
60 <label>密码:</label>
61 <div>
62 <input type="text" v-model="user.password">
63 </div>
64 </div>
65 <div class="modal-body">
66 <label>性别:</label>
67 <div>
68 <input type="text" v-model="user.sex">
69 </div>
70 </div>
71 <div class="modal-body">
72 <label>年龄:</label>
73 <div>
74 <input type="text" v-model="user.age">
75 </div>
76 </div>
77 <div class="modal-body">
78 <label>邮箱:</label>
79 <div>
80 <input type="text" v-model="user.email">
81 </div>
82 </div>
83 <div class="modal-footer">
84 <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
85 <button type="button" class="btn btn-primary" data-dismiss="modal" @click="update">修改</button>
86 </div>
87 </div><!-- /.modal-content -->
88 </div><!-- /.modal -->
89 </div>
90 <!-- 模态窗口结束 -->
91 </table>
92 </div>
93 <script src="js/vuejs-2.5.16.js"></script>
94 <script src="js/axios-0.18.0.js"></script>
95 <script src="js/user.js"></script>
96 </body>
97
98 </html>
js文件user.js
1 new Vue({
2 el:"#app",
3 data:{
4 user:{
5 id:"",
6 username:"",
7 password:"",
8 email:"",
9 age:"",
10 sex:""
11 },
12 userList:[],
13 isShow:false
14
15 },
16 methods:{
17 /**
18 * 查询所有
19 */
20 findAll:function(){
21 //在当前方法中定义一个变量,表明是vue对象
22 var _this = this;
23 axios.get('/user/findAll')
24 .then(function (response) {
25 _this.userList = response.data;// 响应数据给userList赋值
26 console.log(response);
27 })
28 .catch(function (error) {
29 console.log(error);
30 })
31 },
32 /**
33 * 根据id查询
34 * @param userid
35 */
36 findById:function (userid) {
37 //在当前方法中定义一个变量,表明是vue对象
38 var _this = this;
39 axios.get('/user/findById',{params:{id:userid}})
40 .then(function (response) {
41 _this.user = response.data;// 响应数据给userList赋值
42 // $("#myModal").modal("show");
43 _this.isShow = !_this.isShow;
44 })
45 .catch(function (error) {
46 console.log(error);
47 })
48 },
49 /**
50 * 更新
51 */
52 update:function () {//post请求
53 //在当前方法中定义一个变量,表明是vue对象
54 var _this = this;
55 axios.post('/user/updateUserInfo', _this.user)
56 .then(function (response) {
57 _this.findAll();
58 _this.isShow = !_this.isShow;
59 })
60 .catch(function (error) {
61 console.log(error);
62 });
63 },
64 notShow:function () {
65 this.isShow = !this.isShow
66 }
67 },
68 created:function() {//当我们页面加载的时候触发请求,查询所有
69 this.findAll();
70 }
71 });
- 执行SpringBootVueJSApplication的main方法
- 访问http://localhost:8080/user.html

这里我就不一一演示了,有兴趣可以拷贝以上代码查看一下,发现问题:
- 使用火狐浏览器的时候编辑用户信息的时候页面信息会刷新
- 但是使用Chrome浏览器则不会,数据库中的信息有改变,执行更新操作之后也有执行查询所有的方法,并且执行成功
- 火狐浏览器下方会有一个报错
1 XML 解析错误:找不到根元素 2 <html> 3 <body> 4 <h1>Whitelabel Error Page</h1> 5 <p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p> 6 <div id='created'>Fri Nov 23 14:19:00 CST 2018</div> 7 <div>There was an unexpected error (type=Bad Request, status=400).</div> 8 <div>Required request body is missing: public void com.buwei.controller.UserController.updateUserInfo(com.buwei.entity.User) 9 </div> 10 </body> 11 </html>
此一次遇到这个问题,暂时还没想到解决的方法
根据提示在UserController中的updateUserInfo方法中的请求参数中@RequestBody(required=false)依旧是没有解决问题。:(
------------------------------------------------------分割线------------------------------------------------------
查询了一下,参考https://www.cnblogs.com/net064/p/7735832.html解决了问题,controller中的updateUserInfo没有返回值报这个错误,先用上
发现谷歌执行不刷新数据的问题与浏览器有关,我使用的是版本 69.0.3497.100(正式版本)(64 位),换了版本 70.0.3538.102(正式版本) (64 位)就没问题了
来源:https://www.cnblogs.com/buwei/p/9999604.html