DRF+Vue.JS front-end separation project example (below) --- Vue.js front-end implementation code

Please click to read the previous article

1. Requirements description

This article takes the student information query function as an example, adopts a front-end and back-end separation architecture, the back-end provides a RESTFul interface, and the front-end code is implemented with Vue.js + Bottstrap.

1.1 This example requires the following query functions:

List query, single query
Add student information
Change student information
Delete student information

1.2 According to the REST interface guidelines, the RESTFul style API is designed as follows

Before starting, it is recommended to read REST Interface Fundamentals

operate request type resource request url request data
list query GET http://127.0.0.1:8000/student/ none
single query GET http://127.0.0.1:8000/student/1/ none
add record POST http://127.0.0.1:8000/student/2/ {‘name’:‘Jack’, ‘no’:‘A001’,…}
amend record PUT http://127.0.0.1:8000/student/2/ {‘name’:‘Jack’, ‘no’:‘B001’,…}
Delete Record DELETE http://127.0.0.1:8000/student/2/ none

The above interface has been implemented by django-rest-framework.

2. Front-end design

Technology stack:

  • Vue.js dynamic data update
  • Bootstrap5 is responsible for rendering
  • Axios is responsible for interface communication

interface design:

  • Display multiple pieces of data in tabular form;
  • Provide modify and delete buttons for each row of records
  • The page provides an add button
  • The page provides query function
  • All functions are completed on a single page.

Actual page test:
display all records,
insert image description here
query a single piece of data ,
insert image description here
add data,
insert image description here
modify data, click the "Modify" button, a modification bar will pop up, after updating, click the "Submit" button
insert image description here
to delete, just click the delete button
insert image description here

3. Complete code

All code is placed in 1 file, vue_student.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Vue 测试实例 - Vue router(runoob.com)</title>
	<link href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css" rel="stylesheet">
	<script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js"></script>
	<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
	<script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script>
	<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
	<div class="container mt-2">
		<div class="row  my-2 mx-2 ">
		    <div class="col-md-10 p-3">
				<h2 class="text-center">学生信息查询</h2>
				<div id='app'>
					<div class="container mt-3">
						<div class="row">
							<div class="col-md-6"> 
							<input type='number' v-model="sid" placeholder='请输入学生id'>
							<button v-on:click="searchInfo" class="btn btn-primary" >查询</button>
						    </div>
							<div class="col-md-6 d-flex flex-row-reverse">
								<button class="btn btn-info" v-on:click="addReq">添加学生</button>
							</div>
						</div>
					</div>
					<div class="row my-2 border border-1 border-primary shadow-sm py-2 mx-2" v-if="isShowDataDiv">
							
							<div class="form-group row">
								<label for="stdid" class="col-md-1 col-form-label" >ID</label>
								<div class="col-md-2"><input type="text" class="form-control" v-model="studentInfo.id" id="stdid" readonly="true"></div>
							    <label for="stdname" class="col-md-1 col-form-label">姓名</label>
							    <div class="col-md-2"><input type="text" class="form-control" v-model="studentInfo.name" id="stdname"></div>

								<label for="stdno" class="col-md-1 col-form-label">学号</label>
								<div class="col-md-2"><input type="text" class="form-control" v-model="studentInfo.no" id='stdno'  ></div>
								<div class='col-md-3 mt-2'>
								  <span>性别: &nbsp;</span>
								  <input type="radio" id="male" value=0 v-model="studentInfo.gender">
								  <label for="runoob" ></label>
								  <input type="radio" id="female" value=1 v-model="studentInfo.gender">
								  <label for="google"></label>
								</div>
							</div>
							<div class="form-group row">
								<label for="stdage" class="col-md-1 col-form-label">年龄</label>
								<div class="col-md-2"><input type="number" class="form-control" v-model="studentInfo.age" id="stdage"></div>
								<label for="stdclass" class="col-md-1 col-form-label">班级</label>
								<div class="col-md-2"><input type="text" class="form-control" v-model="studentInfo.class_name" id="stdclass"></div>
								<label for="stdscore" class="col-md-1 col-form-label">成绩</label>
								<div class="col-md-2"><input type="number" class="form-control" v-model="studentInfo.score" id="stdscore"></div>
								<div class="col-md-3 d-flex flex-row-reverse" v-if="isShowUpgradeBtn"><button class="btn btn-outline-primary" v-on:click="upgradeConfirm">更新提交</button></div>
								<div class="col-md-3 d-flex flex-row-reverse" v-if="isShowAddBtn"><button class="btn btn-outline-primary" v-on:click="addConfirm">添加提交</button></div>
							</div>
						
					</div>
					
					<table class="table table-striped">
						<thead>
							<tr>
								<td>ID</td>
								<td>姓名</td>
								<td>学号</td>
								<td>性别</td>
								<td>年龄</td>
								<td>班级</td>
								<td>成绩</td>
								<td>操作</td>
							</tr>
						</thead>
						<tbody>
							<tr v-for="(student,index) in studentArray">
								<td v-text="student.id"></td>
								<td v-text="student.name"></td>
								<td v-text="student.no"></td>
								<td v-text="student.gender"></td>
								<td v-text="student.age"></td>
								<td v-text="student.class_name"></td>
								<td v-text="student.score"></td>
								<td> <button class='btn btn-primary btn-sm' v-on:click="upgradeReq(student.id,index)">修改</button>  <button class='btn btn-danger btn-sm' v-on:click="deleteStudent(student.id,index)">删除</button></td>
							</tr>
						</tbody>
					</table>
				</div>
				
			</div>
		</div>		
	</div>
	
	<script>
	const url = "http://127.0.0.1:8000/student/v1/";
	var array_index; 
	var vm = new Vue({
      
      
		el: '#app',
		data: {
      
      
			studentInfo: {
      
      
				id: 1,
				name:'王小乙',
				no: 'B0001',
				gender: 0,
				age: 14,
				class_name: '初2',
				score: 80
			},
			studentArray: [],
			sid: 1,
			isShowDataDiv: false,
			isShowAddBtn: false,
			isShowUpgradeBtn: true
		},
		methods: {
      
      
			searchInfo: function(){
      
      
				that = this; 
				let url_req = url
				if(that.sid > 0){
      
      
					url_req = url+String(that.sid)+'/';
				} 
				
				axios.get(url_req)
					.then( function(response){
      
      
						console.log(response.data); 
						that.studentArray=[]
						if (response.data instanceof Array){
      
      							
							for (var n in response.data){
      
      
								that.studentArray.push(response.data[n]);
							}
						}
						else if (response.data instanceof Object ){
      
      
							that.studentArray.push(response.data);
						}						
					})
					.catch(function (error) {
      
       // 请求失败处理
						console.log(error);
					})
			},
			addData: function(){
      
      
				this.studentArray.push(this.studentInfo);
				
			},
			deleteStudent: function(pk,index){
      
      
				that = this;
				url_req = url+pk+'/';
				axios.delete(url_req)
					.then(function(response){
      
       
						console.log(response.status);
						that.studentArray.splice(index,1)
						})
					.catch(function(err){
      
       console.log(err)})
			},
			addStudent: function(){
      
      
				window.open("vue_student_add.html");
			},
			addReq: function(){
      
      
				that=this;
				that.studentInfo = {
      
      
				id: 0,
				name:'',
				no: '',
				gender: 0,
				age: 0,
				class_name: '2',
				score: 0
				}
				that.isShowDataDiv=true;
				that.isShowUpgradeBtn=false;
				that.isShowAddBtn=true;
			},
			addConfirm: function(){
      
      
				that=this; 
				if (that.studentInfo.name !='' && that.studentInfo.no!='' ) {
      
      
					axios.post(url,that.studentInfo)
						.then(function(response){
      
      
							console.log(response);
							alert("添加成功")
							that.isShowDataDiv=false;
							that.isShowUpgradeBtn=true;
							that.isShowAddBtn=false;
							that.studentArray.push(that.studentInfo)							
						})
						.catch(function(err){
      
      
							console.log(err);
						})
				}
				else {
      
      
					alert("姓名,学号不能为空")
				}
				
			},
			upgradeReq: function(pk,index){
      
      
				that = this;
				that.studentInfo = that.studentArray[index];
				array_index = index; 
				that.isShowDataDiv=true;
				that.isShowUpgradeBtn=true;
				that.isShowAddBtn=false;
				// alert("update data " + pk)
			},
			upgradeConfirm: function(){
      
      
				that = this; 
				url_req = url+that.studentInfo.id+'/';
				axios.put(url_req,that.studentInfo)
					.then(response=>{
      
      
						console.log(response.status);
						that.studentArray[array_index]=that.studentInfo; 
						alert("更新成功")
						that.isShowDataDiv=false;
						
					})
					.catch(function(err){
      
       console.log(err)})				
			}
		}
	});
	vm.addData()
	</script>
</body>
</html>

Running in a test environment usually encounters CORS cross-domain problems, causing requests sent by Axios to be blocked. For solutions, please refer to my other blog post Django Solve CORS cross-domain problems .

Summarize

Advantages and disadvantages of DRF+Vue.js or DRF+React front-end and back-end separation architecture

The advantage of adopting DRF+Vue.js or DRF+React front-end and back-end separation architecture is that it can develop front-end pages with better user experience, but the premise is that front-end engineers must join the project, or you can learn and master Javascript + Vue technology yourself . Of course, mastering these two tools will also improve your ability. In addition, separating the front-end and back-end projects will generally increase the amount of code and testing workload for some projects.

How to determine whether the project is suitable for adopting the DRF+Vue front-end and back-end separation architecture?

If users have high requirements for the interface, or need to use front-end component libraries such as drawing and data visualization (such as JointJS, echarts, etc.), it is recommended to adopt a front-end and back-end separation architecture. If the main function of the project is mainly CRUD operations or data analysis, use django and templates to improve development efficiency.

Guess you like

Origin blog.csdn.net/captain5339/article/details/131605845