DRF+Vue.JS前后端分离项目实例(下) --- Vue.js 前端实现代码

本文上篇请 点击阅读

1. 需求说明

本文以学生信息查询功能为例,采用前后端分离架构,后端提供RESTFul 接口,前端代码用Vue.js + Bottstrap实现。

1.1 本例要求提供如下查询功能:

列表查询、单条查询
添加学生信息
更改学生信息
删除学生信息

1.2 按REST接口指导原则, RESTFul 风格API 设计如下

在开始之前,推荐阅读 REST接口基本原理

操作请求类型资源请求url请求数据
列表查询GEThttp://127.0.0.1:8000/student/
单条查询GEThttp://127.0.0.1:8000/student/1/
添加记录POSThttp://127.0.0.1:8000/student/2/{‘name’:‘Jack’, ‘no’:‘A001’,…}
更改记录PUThttp://127.0.0.1:8000/student/2/{‘name’:‘Jack’, ‘no’:‘B001’,…}
删除记录DELETEhttp://127.0.0.1:8000/student/2/

上述接口已通过django-rest-framework 实现.

2. 前端设计

技术栈:

  • Vue.js 动态数据更新
  • Bootstrap5 负责渲染
  • Axios 负责接口通讯

界面设计:

  • 以表格方式显示多条数据;
  • 每行记录提供修改、删除按钮
  • 页面提供添加按钮
  • 页面提供查询功能
  • 各功能在单页面完成。

实际页面测试:
显示所有记录
在这里插入图片描述
查询单条数据
在这里插入图片描述
添加数据
在这里插入图片描述
修改数据,单击”修改“按钮后,弹出修改栏,更新后单击 ”提交“按钮
在这里插入图片描述
删除,直接点击删除按钮即可
在这里插入图片描述

3. 完整代码

所有代码均放在1个文件中, 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 = urlif(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>

在测试环境下运行,通常会遇到CORS跨域问题,造成Axios发送的请求被阻止,解决办法请参考本人另一篇博文 Django 解决CORS跨域问题的方法.

总结

DRF+Vue.js 或 DRF+React 前后端分离架构的优点与缺点

采用 DRF+Vue.js 或 DRF+React 前后端分离架构的好处是,能够开发出用户体验更佳的前端页面,不过前提是,项目要有前端工程师加入,或者你自己学习掌握Javascript + Vue 技术,当然掌握了这两门工具,也会提升你的能力。另外,前后端分离项目,总体上会增加一些项目的代码量以及测试工作量。

如何确定项目是否适合采用DRF+Vue前后端分离架构呢?

如果用户对界面有较高要求,或者需要使用绘图、数据可视化等前端组件库(如 JointJS, echarts等),建议采用前后端分离架构。 如果项目的主要功能是以CRUD操作为主,或者数据分析为主,则使用django与模板方式,开发效率更高,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/13798.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JDK,JRE,JVM的区别

1.JVM JVM&#xff0c;也叫java虚拟机&#xff0c;用来运行字节码文件&#xff0c;可将字节码翻译为机器码&#xff0c;JVM是实现java跨平台的关键&#xff0c;可以让相同的java代码在不同的操作系统上运行出相同的结果。 2.JRE JRE&#xff0c;也叫java运行时环境&#xff…

基于Spring Boot的社区适龄青年征兵系统设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的社区适龄青年征兵系统设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 后端&#xff1a;Java springboot框架 …

在工作与生活中保持情绪稳定的艺术

强烈的情绪波动&#xff1a;工作中的挑战 在我的职业生涯中&#xff0c;我经历过许多情绪波动的时刻。其中一个最具挑战性的时刻是在我负责一个重要项目的时候。我需要在短时间内完成大量的工作&#xff0c;同时还要管理一个由不同背景和技能的人组成的团队。这个项目的压力让…

flutter聊天界面-聊天列表 下拉加载更多历史消息

flutter聊天界面-聊天列表 下拉加载更多历史消息 在之前实现了flutter聊天界面的富文本展示内容、自定义表情键盘实现、加号【➕】更多展开相机、相册等操作Panel、消息气泡展示实现Flexible。这里把实现的聊天界面的滑动列表及下拉加载更多历史消息记录一下 聊天界面的列表使…

python与深度学习——基础环境搭建

一、安装jupyter notebook Jupyter Notebook是一个开源的交互式笔记本环境&#xff0c;可以用于编写和执行代码、创建可视化效果、展示数据分析结果等。我们在这里用它实现代码运行和观察运行结果。安装jupyter notebook实质上是安装Anaconda,后续还要在Anaconda Prompt中使用c…

QTday2

第一个界面头部的代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> #include<QLabel> #include<QIcon> #include<QLineEdit> #include<QDebug> class Widget : public QWidget {Q_OBJECTsignals:void j…

Unity:sentinel key not found (h0007)

SSD换电脑&#xff0c;unity 编辑器无法打开&#xff1b; 具体步骤&#xff1a; 删除这个路径下的文件 C:\ProgramData\SafeNet 下 Sentinel LDK 打开Windows 的Cmd 命令行&#xff0c;输入编辑器版本下Unity.exe的路径&#xff0c; CD E:\Dev_Env\Unity\Hub\Editor\2020.3.3…

Java Excel 打开文件报发现“xx.xlsx”中的部分内容有问题。是否让我们尽量尝试恢复问题解决

问题描述&#xff1a; 发现“文件.xlsx”中的部分内容有问题。是否让我们尽量尝试恢复&#xff1f; 问题分析&#xff1a; 1、后端的导出接口写的不对&#xff0c;又返回流数据&#xff0c;又返回响应体数据&#xff0c;导致前端将流数据和响应体数据都下载到了excel文件中。…

leetcode 106. 从中序与后序遍历序列构造二叉树

2023.7.8 让我很难受的一道题&#xff0c;个人感觉难度不止中等。 首先要知道的是知道了前序/后序 中序 之后&#xff0c;是可以构造出相应且唯一的二叉树的。 本道题的思路通过递归的方式根据中序遍历数组和后序遍历数组构建二叉树&#xff0c;并返回根节点。递归的结束条…

项目中期检查会议和进度对接

1.召开中期项目检查会议&#xff0c;与团队成员和博士王锟对接进度。对整体项目表示满意接受&#xff0c;指出重点需要修改提升和进一步开发完善的部分&#xff0c;以增强系统的完整度、功能亮点和界面数量点。具体为 ①注重“highlight”&#xff0c;即布局凸显主题功能&…

ubuntu常用软件安装、异常处理

1.ubuntu更换源 打开以下文件&#xff1a; sudo gedit /etc/apt/sources.list 在文件中添加如下内容 #中科大源 deb https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main re…

大学英语六级相当于雅思考试多少分

雅思考试的难度&#xff0c;可以和大学英语六级进行对应&#xff0c;大家可以通过分数来基本确认雅思考试的难度系数。跟着小编来一起看看大学英语六级相当于雅思考试多少分&#xff1f; 英语六级相当于雅思多少分 大学英语六级和雅思没有直接的分数对应关系&#xff0c;一般大…