Vue.js、ElementUI在spring boot上实现增删查改

版权声明:本文为博主原创文章,未经允许不得转载,https://blog.csdn.net/lean_He/article/details/82904931

1、最近我在研究比较火的框架、Vue.js 与ElementUI,坑的路是一大堆,以此记录一下,方便以后学习。

2、页面效果图如下:

Vue.js、ElementUI在spring boot上实现增删查改

3、首先说查询、本项目访问index.html进行异步查询数据,二话不说上代码(由于时间问题,此处并没有实现分页操作)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!--此处引入Element Ui的css样式,也可以官网在线引用  -->
<link rel="stylesheet" type="text/css" href="/element/current/lib/theme-chalk/index.css" />
</head>
<body>

<!--主页面  -->
<div id="app">
<template>
  <el-row>
  	<el-button type="primary" @click="handleAdd()">添加</el-button>
  	<el-button type="danger" @click="removeBatch()">
  	 批量删除
  	</el-button>
  </el-row>
  
  <el-table :data="tableData" style="width: 100%" @selection-change="selsChange">
 
    <el-table-column type="selection" width="65"></el-table-column>
   
    <el-table-column label="编号" width="180" prop="id">
    </el-table-column>
    
    <el-table-column label="姓名" width="200" prop="username">    
    </el-table-column>
    
    <el-table-column label="昵称" width="180" prop="nickname">   
    </el-table-column>
    
    <el-table-column label="状态" width="180" prop="status">   
    </el-table-column>
    
    <el-table-column label="操作">
      <template slot-scope="scope">
        <el-button size="mini" @click="handleEdit(scope.$index, scope.row,tableData)">编辑</el-button>
        <el-button size="mini" type="danger" @click="handleDelete(scope.$index,scope.row,tableData)">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  
  <!--此处是分页,可以暂时不管 -->
  <el-col class="toolbar" style="padding:10px;">
      <el-pagination @current-change="findAll" :current-page="currentPage" :page-size="10" 
                     layout="total, prev, pager, next, jumper" :total="50" style="float:right">
      </el-pagination>
  </el-col>

</template>
</div>

<!--添加与编辑、弹出层页面-->
<div id="app2">
	
		<el-dialog title="用户信息" :visible.sync="dialogFormVisible">
		  <el-form :model="form">
		    <el-form-item label="姓名" :label-width="formLabelWidth">
		      <el-input v-model="form.username" autocomplete="off"></el-input>
		    </el-form-item>
		    <el-form-item label="昵称" :label-width="formLabelWidth">
		      <el-input v-model="form.nickname" autocomplete="off"></el-input>
		    </el-form-item>
		     <el-form-item label="状态" :label-width="formLabelWidth">
		      <el-input v-model="form.status" autocomplete="off"></el-input>
		    </el-form-item>
		  </el-form>
		  <div slot="footer" class="dialog-footer">
		    <el-button @click="dialogFormVisible = false" >取 消</el-button>
		    <el-button type="primary" @click="doSubmit">确 定</el-button>
		  </div>
		</el-dialog>
	</div>

</body>
<script src="/vue/vue.min.js"></script>
<script src="/vue/vue-resource.min.js"></script>
<script src="/element/current/lib/index.js"></script>
<script>
	/*主页面  */
	var Main =new Vue ({
		el:'#app',
	    data:{     
	        tableData: [],         
	      	currentPage:1,
	      	total:10,
	      	sels:[] //存放多选的数据
	    
	    },
	    
	    //mounted在模板html加载后,就调用,此处调用异步查询方法findAll
	    mounted: function () {
            this.findAll();
        },
	    methods: {     
		//查询所有用户信息	      
	   	findAll:function(){

             //分页的参数,可以暂时不管,还没实现分页
    	     var _params ={
    		     pageNum:this.currentPage,
    		     pageSize:10	    	
    		 };

    	   //采取vue.resource.js里面的异步查询方法
    	   this.$http.get("/user",{params:_params},{emulateJSON:true})	     	
    	   .then(function(res){	 
    		    //每次查询都需要将表格数据先清空,否则重复
	     		this.tableData=[];
	     		//根据查询的结果userList去将表格渲染,注意表格的字段必须与实体类字段一致
	     		for(var key in res.data.userList){
	     			this.$set(this.tableData,key,res.data.userList[key]);
	     		} 
	     	})

    		//失败调用
	     	.catch(function (res){
	     		console.log(res.data);
	     	})   	   
	       },
	       
     	   //删除用户信息
	       handleDelete(index,row,tableData) {		 
		        var id = tableData[index].id;
		        this.$http.get("/deleteUser/"+id)
		     	.then(function(res){		
		     		this.findAll();
		     	})		     	
		     	.catch(function (res){
		     		console.log(res.data);
		     	}) 			        
		      },
		      
		     //编辑用户信息,通过vue的表单数据直接给弹出层传递数据,无需再查库
		     handleEdit(index,row,tableData){
		    	 console.log(tableData[index].id);
		    	 AddOrEdit.form.username=tableData[index].username;
		    	 AddOrEdit.form.nickname=tableData[index].nickname;
		    	 AddOrEdit.form.status=tableData[index].status;
		    	 AddOrEdit.form.id=tableData[index].id;
		    	 AddOrEdit.form.flag=0;
		    	 AddOrEdit.dialogFormVisible=true;	    	
		    	},
		    
		    //添加用户
       		handleAdd(){
		    	AddOrEdit.form.flag=1;
		    	AddOrEdit.form.username='';
		    	AddOrEdit.form.nickname='';
		    	AddOrEdit.form.status='';
		        AddOrEdit.form.id='';
        		AddOrEdit.dialogFormVisible=true;
        	},
        	
        	//全选时,获取复选框中的勾选的所有数据
        	selsChange(sels) {
                this.sels = sels
            },
            
            //批量删除
            removeBatch(){    
            	var arr =new Array();
            	for(var i=0;i<this.sels.length;i++){           		           		
            		var object = new Object();
            		object.id=this.sels[i].id;
            		arr[i]=object;
            	} 
            	
            	//异步提交删除
            	this.$http.post("/deleteBatchUser",{params:JSON.stringify(arr)},
                                {emulateJSON:true})
            	.then(function(res){
            		console.log("批量删除成功");
            		this.findAll();
            	})
            	.catch(function (res){
            		console.log(res.data);
            	})
            		
            }
 	
	    },            
 	});

 /*添加与编辑页面 */
 var AddOrEdit = new Vue({
	 	el:'#app2',
	    data() {
	      return {
	        dialogFormVisible: false,
	        form: {
	          id:'',
	          username: '',
	          nickname:'',
	          status:'',
	          region: '',
	          date1: '',
	          delivery: false,
	          type: [],
	          resource: '',
	          flag:''
	        },
	        formLabelWidth: '120px'
	      };
	    },
	    
	    methods:{
	    	//更新用户信息
	    	doSubmit:function(){
                //更新表单的参数
	    		var _params={
	    			username:AddOrEdit.form.username,
	    			nickname:AddOrEdit.form.nickname,
	    			status:AddOrEdit.form.status,
	    			id:AddOrEdit.form.id
	    		};
	    		console.log(_params);
	    		if(this.form.flag==0){
	    			//异步更新用户信息,传参是原本想用{params:_params}传过去,然后Spring自动封装对象,奈何不知道为何,一直无法封装成对象,换成一下格式,结果能封装成对象传递过去,我初步估计可能是外面还嵌套了一层{}
		    		this.$http.post("/updateUser",{username:AddOrEdit.form.username,nickname:AddOrEdit.form.nickname,id:AddOrEdit.form.id,status:AddOrEdit.form.status},{emulateJSON:true})	     	
		      	     .then(function(res){	     		
		  	     		console.log('更新成功');	  	     		
		  	     		Main.findAll();
		  	     	})		      	
		  	     	.catch(function (res){
		  	     		console.log(res.data);
		  	     	})
		    		
	    			
	    		}
	    		else{	    		
	    			//添加用户信息
		    		this.$http.post("/addUser",{username:AddOrEdit.form.username,nickname:AddOrEdit.form.nickname,id:AddOrEdit.form.id,status:AddOrEdit.form.status},{emulateJSON:true})	     	
		      	   .then(function(res){	     		
		  	     		console.log('添加成功');		  	 
		  	     		Main.findAll();
		  	     	})
		      	
		  	     	.catch(function (res){
		  	     		console.log(res.data);
		  	     	})
	    		
	    		}   		
	    		this.dialogFormVisible=false; 
	    		
	    	}
	    	
	    }
	    
	  }); 

</script> 
</html>

4、后台Controller代码UserController

package com.helian.cloud.web.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.helian.cloud.api.model.User;
import com.helian.cloud.api.service.UserService;

/**
 * 用户控制层
 * @author helian
 * @date 2018/9/26 下午5:40
 */

@Controller
public class UserController {

    @Autowired
    private UserService userService;
    
    /**
     *. 查询用户
     * @return
     */
    @GetMapping("/user")
    public @ResponseBody Map<String,Object> userList() {
        List<User> userList = userService.listUsers();
        Map<String,Object> tableData = new HashMap<>();
        tableData.put("userList",userList);
        return tableData;    
    }
    
    /**
     *. 删除单个用户
     * @param id
     */
    @GetMapping("/deleteUser/{id}")
    @ResponseBody
    public void deleteUser(@PathVariable(value="id") String id) {
        try {
        	 if(id!=null) {
        		 userService.deleteUserById(id);
        	 }
        }
        catch (Exception e) {
        	e.printStackTrace();
        }    
    }
    
    /**
     *. 批量删除用户
     * @param idArr[]
     */
    @PostMapping("/deleteBatchUser")
    @ResponseBody
    public void deleteBatchUser(@RequestParam("params") String params) { 	
    	   try {
            /**进行批量删除的时候,vue.resource传递id数组过来的时候,需要JSON.stringify转换成json字符串,再到后台转换成JSONArray去遍历,原本想直接通过Spring封装成String数组,由于vue的异步有些不一样,需要这么转换才行。*/
			JSONArray jsonArray= new JSONArray(params);
			for(int i=0;i<jsonArray.length();i++) {
				userService.deleteUserById(String.valueOf(jsonArray.getJSONObject(i).get("id")));
				System.out.println(jsonArray.getJSONObject(i).get("id"));
	    	}
		  } catch (JSONException e) {
			 e.printStackTrace();
		 }
    	
    }
    
    
    
    
    /**
     *. 更新用户信息
     * @param user
     */
    @PostMapping("/updateUser")
    @ResponseBody
    public void updateUser(User user) {
    	if(user!=null) {
    		System.out.println("---------");
    		System.out.println("状态"+user.getStatus());
    		userService.updateUser(user);
    	}
    }
    
    /**
     * .添加用户信息
     * @param user
     */
    @PostMapping("/addUser")
    @ResponseBody
    public void addUser(User user) {
    	userService.insertUser(user);
    }
 


}

5、在采用vue.resource中的$.http进行异步操作时无法获取数据,因为vue的异步跟Jquery中Ajax不太一样,原因是默认传递数据格式不一样,这个需要注意设置一下emulateJSON:true。 vue.resource中post方法时,默认传递格式是request payload,传递数据例如:{a:"123",b:"321"} ,如果设置emulateJSON:true以后,post传递数据格式是form data(默认的的Content-Type用的是application/x-www-form-urlencoded),传递数据例如:a:123 , b:321

6.在进行通过异步传递数组时,需要在前台html使用JSON.stringify(数组),转换成字符串,否则后台可能解析出原有的JSON字符串或者参数为空。

7.在刚使用Spring boot时,发现跳转Controller层无法返回页面问题时,需要注意@RestController与@Controller的区别,@RestController结合了@Controller与@ResponseBody的使用,大家也知道@ResponseBody用来解析例如JSON或者其他数据格式,不知道为何它会忽略自身配置的视图解析器,导致无法返回视图,将@RestController改成@Controller,需要返回页面可以采取返回String 或者ModelAndView 或者Model去返回视图页面,需要解析JSON等格式数据,在方法体前加@ResponseBody即可。

总结:以上都是个人尝试的成果与思考,如有不足之处,请指出,或提出解决方案,感谢大家。