目录

一、新建项目并初始化

二、安装依赖 axios、elementUI

三、Vue代码

四、进行接口联调

五、后端接口优化

六、web页面功能测试

七、总结

八、展望

九、附录(截止发文时的代码)


先来看看效果,再步入正题

主页

增加

查询

详情

修改

删除

先打一下地基

环境搭建博文:

VUE 3.0项目环境搭建+VS code安装(图文教程)_软件测试李同学的博客-CSDN博客

Flask+mysql接口增删改查博文:Flask+mysql实现增删改查接口开发+测试(图文教程附源码)_软件测试李同学的博客-CSDN博客

注意:本篇文章接着上面的图书项目book增删改查实现

一、新建项目并初始化

vue 创建新项目 :vue create book

初始化 :vue init webpack book

中间要是提示要安装脚手架:npm i -g @vue/cli-init

,按照提示执行命令即可

安装:npm i -g @vue/cli-init

新建项目成功后,目录结构如下:

二、安装依赖 axios、elementUI

axios说白了就是调接口用的

安装axios npm 
npm install axios --save
安装element-ui 
npm install element-ui --save (yarn add element-ui)

elementUI说白了就是一个组件库,很流行,实战的时候肯定是CV多,有轮子就不用重复写轮子

elementUI的引入

在src下面的main.js下新增如下内容
import Element from 'element-ui'
import "element-ui/lib/theme-chalk/index.css"
Vue.use(Element)

axios的引入
在src下面的main.js下新增如下内容
import axios from 'axios'
Vue.prototype.$axios=axios
组件中,我们就可以通过this.$axios.get()来发起我们的请求了哈

通过命令 npm run dev  启动

三、Vue代码

以下代码也是轮子,轮子有了,先看看效果

向src->components->HelloWorld.vue文件中加入以下代码,然后保存

<!--
Element-ui框架实现对数据库的增删改查
这里利用Vue进行简单的增删改查操作,可以与后台进行结合,进行增删改查的过程,只需要将接口改一下名字。
其中element-ui组件库经常与vue进行结合使用-->
<template><div class="back"><h1>{{ msg }}</h1><el-button :span="8" type="primary" @click="adduser" class="add-btn" plain>添加信息</el-button><el-input :span="8" placeholder="请输入内容" v-model="bookname" class="add-btn"clearable></el-input><el-button :span="8" slot="append" icon="el-icon-search" @click="check"class="button"></el-button><el-table :data="bookInfo" style="width: 100%"><el-table-column prop="id" label="编号" width="180"></el-table-column><el-table-column prop="name" label="书名" width="180"></el-table-column><el-table-column prop="writer" label="作者" width="180"></el-table-column><el-table-column prop="publish" label="出版社" width="180"></el-table-column><el-table-column align="right"><!-- <template> --><el-input placeholder="请输⼊书名搜索" v-model="bookname" clearable></el-input><el-button slot="append" icon="el-icon-search" @click="check" class="button"></el-button><!-- </template> --><template slot-scope="scope"><el-button size="mini" @click="edit(scope.row,scope.row.id)">编辑</el-button><el-button size="mini" type="danger" @click.native.prevent="deleteRow(scope.row.id)">删除</el-button></template></el-table-column></el-table><!--增加框--><el-dialog title="增加书籍信息" :visible.sync="dialogVisible1" width="30%" :before-close="handleClose1"><div><el-form ref="form" :model="editObj1" label-width="80px"><el-form-item label="书名"><el-input v-model="editObj1.name"></el-input></el-form-item><el-form-item label="作者"><el-input v-model="editObj1.writer"></el-input></el-form-item><el-form-item label="出版社"><el-input v-model="editObj1.publish"></el-input></el-form-item></el-form></div><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible1 = false">取消</el-button><el-button type="primary" @click="confirm1">确定</el-button></span></el-dialog><!--编辑框 --><el-dialog title="编辑书籍信息" :visible.sync="dialogVisible" width="30%" :before-close="handleClose"><div><el-form ref="form" :model="editObj" label-width="80px"><el-input type="hidden" v-model="editObj.id"></el-input><el-form-item label="书名"><el-input v-model="editObj.name"></el-input></el-form-item><el-form-item label="作者"><el-input v-model="editObj.writer"></el-input></el-form-item><el-form-item label="出版社"><el-input v-model="editObj.publish"></el-input></el-form-item></el-form></div><span slot="footer" class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="confirm">确定</el-button></span></el-dialog></div>
</template>
<script>export default {data() {return {msg: "欢迎访问图书管理系统",dialogVisible: false,dialogVisible1: false,bookname: '',bookInfo: [{id: '',name: '',writer: '',publish: ''}],editObj: {id: '',name: '',writer: '',publish: ''},editObj1: {name: '',writer: '',publish: ''},userIndex: 0,}},mounted() {this.getnetwork();},methods: {getnetwork() {// console.log(this.bookinfo.id);var that = this this.$axios.post("http://localhost:8081/springboot/getuser").then(function(res) {console.log(res.data) that.bookInfo = res.data// console.log(this.bookInfo)}).catch(function(err) {console.log(err)})},//确定查询按钮check() {// console.log(this.bookname)var that = this//网络请求获取数据axiosthis.$axios.post("http://localhost:8081/springboot/checkbyname", {name: this.bookname,}).then(function(res) { //请求成功,方法回调//回调方法不能用thisconsole.log(res.data) console.log(res.data.data) that.bookInfo = res.data.data// console.log(this.data.id)}).catch(function(err) { //请求失败console.log(err)})},adduser() {this.dialogVisible1 = true;},edit(item, id) {this.userIndex = id;console.log(id)// console.log(item.id)// console.log(item.id)this.editObj = {id: item.id,name: item.name,writer: item.writer,publish: item.publish,};this.dialogVisible = true;},deleteRow(bookid) {console.log(bookid) if (confirm('确定要删除吗') == true) {var that = this//网络请求获取数据axiosthis.$axios.post("http://localhost:8081/springboot/deletebyid", {id: bookid}).then(res =>{ //请求成功,方法回调   //回调方法不能thisthis.getnetwork()// getnetwork();console.log(res.data) that.newsList = res.data// console.log(this.newsList);}).catch(function(err) { //请求失败console.log("失败了" + err)})}// window.location.href = 'http://127.0.0.1:8848/HelloVue/book.html'},// ×按钮handleClose() {this.dialogVisible = false;},handleClose1() {this.dialogVisible1 = false;},confirm() { //确认修改console.log(this.editObj.id) console.log(this.editObj.name) console.log(this.editObj.publish) console.log(this.editObj.writer) var that = this//网络请求获取数据axiosthis.$axios.post("http://localhost:8081/springboot/updateuser", {id: this.editObj.id,name: this.editObj.name,publish: this.editObj.publish,writer: this.editObj.writer}).then(function(res) { //请求成功,方法回调//回调⽅方不能thisthat.getnetwork() console.log(res.data) that.newsList = res.data}).catch(function(err) { //请求失败console.log(err)}) this.dialogVisible = false;// Vue.set(this.tableData, this.userIndex, this.editObj);},// 确定增加按钮confirm1() {var that = this//网络请求获取数据axiosthis.$axios.post("http://localhost:8081/springboot/adduser", {name: this.editObj1.name,publish: this.editObj1.publish,writer: this.editObj1.writer}).then(function(res) { //请求成功,方法回调//回调方法不能用thisthat.getnetwork() console.log(res.data) that.newsList = res.data}).catch(function(err) { //请求失败console.log(err)}) this.dialogVisible1 = false;// Vue.set(this.tableData, this.userIndex, this.editObj);}},}
</script>
<style>.add-btn{ width:450px } .input{ width: 220px; height: 70px; } .button{}#app{ width: 1024px; margin: 0 auto; } #back{ height: 200px; }
</style>

运行看看效果

 页面画好了,下一步和后端接口联调

四、进行接口联调

继续联调,发现vue文件还有很多需要改的地方

理智分析一波

1、先是先将对应的模板<template>写好,包括输入框(查找操作),增加按钮(增加操作),删除按钮(删除操作),修改按钮(修改操作),表格(显示数据)

模板代码如下:

<template><div class="back"><h1>{{ msg }}</h1><el-button :span="8" type="primary" @click="addbook" class="add-btn" plain>添加图书</el-button><el-input :span="8" placeholder="请输入编号搜索" v-model="id" class="add-btn"clearable></el-input><el-button :span="8" slot="append" icon="el-icon-search" @click="check"class="button"></el-button><el-table :data="bookInfo" style="width: 100%"><el-table-column prop="id" label="编号" width="180"></el-table-column><el-table-column prop="title" label="书名" width="180"><template slot='header'><span class ="star">*</span><span >书名</span></template></el-table-column><el-table-column prop="author" label="作者" width="180"><template slot='header'><span class ="star">*</span><span >作者</span></template></el-table-column><!-- 表头提示在这里用 --><el-table-column prop="read_status" label="阅读状态" width="180" :render-header="renderHeader"><!-- 这里红星星没生效还需要找原因 --><template slot='header'><span class ="star">*</span><span >阅读状态</span></template></el-table-column><el-table-column align="right"><template slot-scope="scope"><!-- plain改变按钮显示方式,element 称为朴素按钮--><el-button size="mini" type="info" @click="detail(scope.row,scope.row.id)" >详情</el-button><el-button size="mini" type="success" @click="edit(scope.row,scope.row.id)">编辑</el-button><el-button size="mini" type="danger" @click.native.prevent="deleteRow(scope.row.id)">删除</el-button></template></el-table-column></el-table><!-- 数据分页页面,还没做好--><div class="block" ><!--换行用br标签--><br><br/><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage4":page-sizes="[20, 30, 50, 100]":page-size="100"layout="total, sizes, prev, pager, next, jumper":total="400"></el-pagination></div><!--增加对话框--><el-dialog title="增加图书信息" :visible.sync="addbook_dialogVisible" width="30%" :before-close="handleClose1"><div><el-form ref="form" :model="editObj1" label-width="80px"><el-form-item label="书名" required="true"><el-input v-model="editObj1.title" placeholder="请输入书名"></el-input></el-form-item><el-form-item label="作者" required="true"><el-input v-model="editObj1.author" placeholder="请输入作者"></el-input></el-form-item><!--鼠标在此标签区域显示提示--><el-form-item label="阅读状态" required="true" title="阅读状态只能输入0或者1;0代表未读,1代表已读"><el-input v-model="editObj1.read_status" placeholder="请输入阅读状态"></el-input></el-form-item></el-form></div><span slot="footer" class="dialog-footer"><el-button @click="addbook_dialogVisible = false">取消</el-button><el-button type="primary" @click="confirm_add">确定</el-button></span></el-dialog><!--编辑对话框 --><el-dialog title="编辑图书信息" :visible.sync="edit_dialogVisible" width="30%" :before-close="handleClose"><div><el-form ref="form" :model="editObj" label-width="80px"><el-input type="hidden" v-model="editObj.id"></el-input><!--required显示红星表示必填项,placeholder为输入框注释 --><el-form-item label="书名" required="true" ><el-input v-model="editObj.title" placeholder="请输入书名"></el-input></el-form-item><el-form-item label="作者" required="true" ><el-input v-model="editObj.author" placeholder="请输入作者"></el-input></el-form-item><el-form-item label="阅读状态" required="true" title="阅读状态只能输入0或者1;0代表未读,1代表已读"><el-input v-model="editObj.read_status" placeholder="请输入阅读状态"></el-input></el-form-item></el-form></div><span slot="footer" class="dialog-footer"><el-button @click="edit_dialogVisible = false">取消</el-button><el-button type="primary" @click="confirm">确定</el-button></span></el-dialog><!--详情对话框,新建一个对话框把编辑的代码复制过来,然后逻辑复制编辑额逻辑,再把确定和取消按钮去掉即可 --><el-dialog title="图书详情信息" :visible.sync="detail_dialogVisible" width="30%" :before-close="detail_handleClose"><div><el-form ref="form" :model="editObj" label-width="80px"><el-input type="hidden" v-model="editObj.id"></el-input><el-form-item label="书名" required="true"><el-input v-model="editObj.title" :disabled="true"></el-input></el-form-item><el-form-item label="作者" required="true"><el-input v-model="editObj.author" :disabled="true"></el-input></el-form-item><el-form-item label="阅读状态" required="true" title="阅读状态只能输入0或者1;0代表未读,1代表已读"><el-input v-model="editObj.read_status" :disabled="true"></el-input></el-form-item></el-form></div><!--详情对话框的确定和取消按钮去掉 <span slot="footer" class="dialog-footer"><el-button @click="edit_dialogVisible = false">取消</el-button><el-button type="primary" @click="confirm">确定</el-button></span>--></el-dialog></div>
</template>

2、制作好模板之后,就得编写下各个方法,包括显示数据方法(getnetwork)增加方法(confirm_add),删除方法(deleteRow),查询方法(check),修改方法(confirm)

显示方法代码如下:

         getnetwork() {// console.log(this.bookinfo.id);var that = this this.$axios.post("http://127.0.0.1:5001/query",{id: "",  //这里不传id查所有}).then(function(res) {console.log(res.data) that.bookInfo = res.data.datathat.bookInfo = that.bookInfo.map(item=>{item.read_status = String(item.read_status)return item})// console.log(this.bookInfo)}).catch(function(err) {console.log(err)})}

增加方法(confirm_add)如下:

         //5、 增加方法confirm_add() {// 确定增加按钮if (this.editObj1.title === '') {this.$message({message: '书名不能为空!',type: 'warning'});return}if (this.editObj1.author === '') {this.$message({message: '作者不能为空!',type: 'warning'});return}if (this.editObj1.read_status === '') {this.$message({message: '阅读状态不能为空!',type: 'warning'});return}var that = this//网络请求获取数据axiosthis.$axios.post("http://127.0.0.1:5001/add", {title: this.editObj1.title,author: this.editObj1.author,read_status: this.editObj1.read_status}).then(function(res) { //请求成功,方法回调//    this.$message.success('图书添加成功!');//回调方法不能用thisthat.getnetwork() // if (this.editObj1.read_status == success)console.log(res.data)//that.newsList = res.data}).catch(function(err) { //请求失败console.log(err)}) this.addbook_dialogVisible = false;// Vue.set(this.tableData, this.userIndex, this.editObj);},// 给表头增加提示renderHeader(h,{column}){const serviceContent= [h('div',{slot:"content",},"提示:true代表已读,false代表未读")]return h("div",[h("span",column.label),h("el-tooltip",{props:{placement:"top"}},[serviceContent,h("i",{class:"el-icon-warning-outline",style:"color:blue;margin-left:5px;"})])]);},},}

删除方法(deleteRow)如下:

         //3、删除方法deleteRow(id) {console.log(id) if (confirm('确定要删除吗') == true) {var that = this//网络请求获取数据axiosthis.$axios.post("http://127.0.0.1:5001/delete", {id:id}).then(res =>{ //请求成功,方法回调   //回调方法不能thisthis.getnetwork()// getnetwork();console.log(res.data) }).catch(function(err) { //请求失败console.log("失败了" + err)})}},// 对话框右上角的×按钮handleClose() {//编辑this.edit_dialogVisible = false;},handleClose1() {//增加this.addbook_dialogVisible = false;},detail_handleClose() {//详情this.detail_dialogVisible = false;}

查询方法(check)如下:

         //2、查询方法check() {//确定查询按钮// console.log(this.bookname)var that = this//网络请求获取数据axiosthis.$axios.post("http://127.0.0.1:5001/query", {id: this.id,}).then(function(res) { //请求成功,方法回调//回调方法不能用thisconsole.log(res.data) console.log(res.data.data) that.bookInfo = res.data.datathat.bookInfo = that.bookInfo.map(item=>{//布尔类型转字符串item.read_status = String(item.read_status)return item})// console.log(this.data.id)}).catch(function(err) { //请求失败console.log(err)})},

修改方法(confirm) 如下:

         //4、修改方法confirm() { //确认修改if (this.editObj.title === '') {this.$message({message: '书名不能为空!',type: 'warning'});return}if (this.editObj.author === '') {this.$message({message: '作者不能为空!',type: 'warning'});return}if (this.editObj.read_status === '') {this.$message({message: '阅读状态不能为空!',type: 'warning'});return}var that = this//网络请求获取数据axiosthis.$axios.post("http://127.0.0.1:5001/update", {id: this.editObj.id,title: this.editObj.title,author: this.editObj.author,read_status: this.editObj.read_status}).then(function(res) { //请求成功,方法回调//回调方法不能this    that.getnetwork()console.log(res.data) }).catch(function(err) { //请求失败console.log(err)}) this.edit_dialogVisible = false;// Vue.set(this.tableData, this.userIndex, this.editObj);},

五、后端接口优化

1、传单个id的时候返回的单个数据没在数组里,这里要处理一下

2、删除的方法由DELETE改为POST

3、。。。。还有很多别的,具体看代码

六、web页面功能测试

准备测试,看看增删改查效果

增加

删除

修改

查询

查询所有

通过编号查询

其他的测试场景和细节体验这里就不测试了

代码的注释已经写得很清楚了

七、总结

上一篇博文的代码有一些bug,不知道大家找出来没。这一次做的增删改查前端加入了很多小细节,基本是就是工作中需要测试的细节,如果是自己实现的话,这个会给大家带来很深的印象。

还有对阅读状态这个布尔型字段的处理,有点费功夫的,坑也多

八、期望

很多校验还没做好,还有很多bug,前期设计不太合理,后续需要优化。

1、更改为书名查询,模糊查询

2、修复增加和修改后页面自动按照id查询的bug。。。等bug

3、增加输入框长度校验、提示校验,目前做的还不够

4、增加操作成功和失败后的提示

5、删除确认框的处理

6、做好分页功能

7、做好封装,接口、方法等

8、。。。。。。

完成以上工作,一个健壮的增删改查就有了,已经满足工作的要求了

九、附录(截止发文时的代码)

1、后端app.py全部代码

# -*- coding: utf-8 -*-
# @Author  : Liqiju
# @Time    : 2022/5/1 2:45
# @File    : app.py
# @Software: PyCharm
import pymysql
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask import make_response,request
from flask_cors import CORS
pymysql.install_as_MySQLdb()app = Flask(__name__)
# ------------------database----------------------------
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:root@localhost:3306/books'
# 指定数据库文件
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True# 允许修改跟踪数据库
db = SQLAlchemy(app)class Books(db.Model):id = db.Column(db.Integer, primary_key=True, comment='自动递增id,唯一键')title = db.Column(db.String(80), nullable=False, comment='书名')author = db.Column(db.String(120), nullable=False, comment='作者')read_status = db.Column(db.Boolean, comment='阅读状态,0未读,1已读') # bool的True和False是数值1和0# 增加数据
def insert_data(title, author, read_status):book = Books(title=title, author=author, read_status=read_status)db.session.add_all([book])db.session.commit()# 查询所有
def select_data_all():book_list = []books = Books.query.all()# 类似于 select * from Booksfor s in books:dic = {}dic['id'] = s.iddic['title'] = s.titledic['author'] = s.authordic['read_status'] = s.read_statusbook_list.append(dic)return book_list# 通过id查询
def select_data_by_id(id):book_list = []book = Books.query.get(id)if not book:return Falsedic = {}dic['id'] = book.iddic['title'] = book.titledic['author'] = book.authordic['read_status'] = book.read_statusbook_list.append(dic)return book_list# 通过id删除数据
def delete_data(id):# 类似于 select * from Books where id = iddelete_id = Books.query.get(id)if not delete_id:return Falsedb.session.delete(delete_id)db.session.commit()# 提交操作到数据库# 修改数据
def update_data(id, title='', author='', read_status=''):book = Books.query.get(id)if not title == '':book.title = titleif not author == '':book.author = authorif not read_status == '':book.read_status = read_statusdb.session.commit()# 解决浏览器浏览器访问输出乱码问题
app.config['JSON_AS_ASCII'] = False@app.after_request
def after(resp):resp = make_response(resp)resp.headers['Access-Control-Allow-Origin'] = '*'  # 允许跨域地址resp.headers['Access-Control-Allow-Methods'] = '*'  # 请求 ‘*’ 就是全部resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'  # 头部resp.headers['Access-Control-Allow-Credentials'] = 'True'return respCORS(app, resources=r'/*', supports_credentials=True)# 前端通过传参title、author、read_status增加书籍
@app.route('/add', methods=['POST'])
def add():response_object = {'status': 'success'}if request.method == 'POST':post_data = request.get_json()print('调用add方传过来的参数是', post_data)book_list = select_data_all()for i in range(len(book_list)):title_list = book_list[i]['title']if post_data.get('title') in title_list:response_object['message'] = '书名(title)重复!'response_object["status"]= 'fail'return response_objectif post_data.get('title') is None:response_object['message'] = 'title是必传参数!'response_object["status"]= 'fail'return response_objectif post_data.get('author') is None:response_object['message'] = 'author是必传参数!'response_object["status"]= 'fail'return response_objectif post_data.get('read_status') is None:response_object['message'] = 'read_status是必传参数!'response_object["status"]= 'fail'return response_objecttitle = str(post_data.get('title')).strip(),author = str(post_data.get('author')).strip(),read_status = int(str(post_data.get('read_status')))# 前端传过来字符串处理为intif title[0] is None or title[0] is '':response_object['message'] = 'title不能为空!'response_object["status"] = 'fail'return response_objectif author[0] is None or author[0] is '':response_object['message'] = '作者不能为空!'response_object["status"] = 'fail'return response_objectif read_status != 0 and read_status != 1:response_object['message'] = '阅读状态只能为0和1!'response_object["status"] = 'fail'return response_objectinsert_data(title=title[0], author=author[0], read_status=read_status)response_object['message'] = '图书添加成功!'return response_object# 前端通过传id删除书籍
@app.route('/delete', methods=['POST'])  # 改为post方法
def delete():response_object = {'status': 'success'}if request.method == 'POST':post_data = request.get_json()print('调用delete方传过来的参数是:', post_data)if post_data.get('id') is None:response_object['message'] = 'id是必传参数!'response_object["status"]= 'fail'return response_objectid = post_data.get('id')result = delete_data(id)  # 删除方法调用if result is False:response_object['message'] = '需要删除的图书不存在!'response_object["status"] = 'fail'return response_objectelse:response_object['message'] = '图书被删除!'return response_object# 前端通过传参title、author、read_status修改书籍
@app.route('/update', methods=['POST'])
def update():response_object = {'status': 'success'}if request.method == 'POST':post_data = request.get_json()print('调用update方传过来的参数是', post_data)if post_data.get('id') is None:response_object['message'] = 'id是必传参数!'response_object["status"]= 'fail'return response_objectif post_data.get('title') is None:response_object['message'] = 'title是必传参数!'response_object["status"]= 'fail'return response_objectif post_data.get('author') is None:response_object['message'] = 'author是必传参数!'response_object["status"]= 'fail'return response_objectif post_data.get('read_status') is None:response_object['message'] = 'read_status是必传参数!'response_object["status"]= 'fail'return response_object# 查询所有数据book_list = select_data_all()# 拼接所有的id到列表print(book_list)#  这里的逻辑写错了,有bug,改一下book_id = []for i in range(len(book_list)):book_id.append(book_list[i]['id'])print('book_id是', book_id)# 判断书籍id在不在列表内if post_data.get('id') not in book_id and int(post_data.get('id')) not in book_id: #  这里也有bug,改一下response_object['message'] = '需要修改的图书id不存在!'response_object["status"]= 'fail'return response_objecttitle = str(post_data.get('title')).strip(),author = str(post_data.get('author')).strip(),#print("处理前",post_data.get('read_status'))read_status = int(post_data.get('read_status'))  # 前端传过来字符串处理为int#print("处理后", read_status)if title[0] is None or title[0] is '':response_object['message'] = 'title不能为空!'response_object["status"] = 'fail'return response_objectif author[0] is None or author[0] is '':response_object['message'] = '作者不能为空!'response_object["status"] = 'fail'return response_objectif read_status != 0 and read_status != 1:response_object['message'] = '阅读状态只能为0和1!'response_object["status"] = 'fail'return response_objectbooks_id = post_data.get('id')title = post_data.get('title')author = post_data.get('author')read_status = read_status# 这里原来的post_data.get('read_status')改为read_status,上面已经处理了update_data(id=books_id, title=title, author=author, read_status=read_status)response_object['message'] = '图书已更新!'return response_object# 前端通过不传参默认查询所有书籍,传id查询对应书籍
@app.route('/query', methods=['POST'])
def query():response_object = {'status': 'success'}if request.method == 'POST':post_data = request.get_json()print('调用query方传过来的参数是', post_data)# if post_data.get('id') is None:id = str(post_data.get('id')).strip()if id is None or id is '':books = select_data_all()response_object['message'] = '查询所有图书成功!'response_object['data'] = booksreturn response_object# id = str(post_data.get('id')).strip()# if id is None or id is '':#     response_object['message'] = 'id不能为空!'#     response_object["status"] = 'fail'#     return response_objectbook = select_data_by_id(id)if book is False:response_object['message'] = '需要查询的图书不存在!'response_object["status"] = 'fail'return response_objectelse:response_object['message'] = '图书查询成功!'response_object['data'] = bookreturn response_objectif __name__ == '__main__':# 默认是5000,这里设置5001避免本地冲突。打开debug方便调试# db.create_all()  # 创建表(表创建好后可注释掉)# insert_data("《水浒传》", "吴承恩", 1) # 利用这个可以添加数据或者直接数据库手动加入# 注意这个时候没开启校验title唯一性是因为不是前端过来的请求app.run(debug=True, port=5001)

2、前端HelloWorld.vue全部代码

<!--
Element-ui框架实现对数据库的增删改查
这里利用Vue进行简单的增删改查操作,可以与后台进行结合,进行增删改查的过程,只需要将接口改一下名字。
其中element-ui组件库经常与vue进行结合使用
vue被称为组件,那是因为一个vue文件由HTML、JS、CSS构成--><!--一、 HTML部分,用的是element-ui 模板template -->
<template><div class="back"><h1>{{ msg }}</h1><el-button :span="8" type="primary" @click="addbook" class="add-btn" plain>添加图书</el-button><el-input :span="8" placeholder="请输入编号搜索" v-model="id" class="add-btn"clearable></el-input><el-button :span="8" slot="append" icon="el-icon-search" @click="check"class="button"></el-button><el-table :data="bookInfo" style="width: 100%"><el-table-column prop="id" label="编号" width="180"></el-table-column><el-table-column prop="title" label="书名" width="180"><template slot='header'><span class ="star">*</span><span >书名</span></template></el-table-column><el-table-column prop="author" label="作者" width="180"><template slot='header'><span class ="star">*</span><span >作者</span></template></el-table-column><!-- 表头提示在这里用 --><el-table-column prop="read_status" label="阅读状态" width="180" :render-header="renderHeader"><!-- 这里红星星没生效还需要找原因 --><template slot='header'><span class ="star">*</span><span >阅读状态</span></template></el-table-column><el-table-column align="right"><template slot-scope="scope"><!-- plain改变按钮显示方式,element 称为朴素按钮--><el-button size="mini" type="info" @click="detail(scope.row,scope.row.id)" >详情</el-button><el-button size="mini" type="success" @click="edit(scope.row,scope.row.id)">编辑</el-button><el-button size="mini" type="danger" @click.native.prevent="deleteRow(scope.row.id)">删除</el-button></template></el-table-column></el-table><!-- 数据分页页面,还没做好--><div class="block" ><!--换行用br标签--><br><br/><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage4":page-sizes="[20, 30, 50, 100]":page-size="100"layout="total, sizes, prev, pager, next, jumper":total="400"></el-pagination></div><!--增加对话框--><el-dialog title="增加图书信息" :visible.sync="addbook_dialogVisible" width="30%" :before-close="handleClose1"><div><el-form ref="form" :model="editObj1" label-width="80px"><el-form-item label="书名" required="true"><el-input v-model="editObj1.title" placeholder="请输入书名"></el-input></el-form-item><el-form-item label="作者" required="true"><el-input v-model="editObj1.author" placeholder="请输入作者"></el-input></el-form-item><!--鼠标在此标签区域显示提示--><el-form-item label="阅读状态" required="true" title="阅读状态只能输入0或者1;0代表未读,1代表已读"><el-input v-model="editObj1.read_status" placeholder="请输入阅读状态"></el-input></el-form-item></el-form></div><span slot="footer" class="dialog-footer"><el-button @click="addbook_dialogVisible = false">取消</el-button><el-button type="primary" @click="confirm_add">确定</el-button></span></el-dialog><!--编辑对话框 --><el-dialog title="编辑图书信息" :visible.sync="edit_dialogVisible" width="30%" :before-close="handleClose"><div><el-form ref="form" :model="editObj" label-width="80px"><el-input type="hidden" v-model="editObj.id"></el-input><!--required显示红星表示必填项,placeholder为输入框注释 --><el-form-item label="书名" required="true" ><el-input v-model="editObj.title" placeholder="请输入书名"></el-input></el-form-item><el-form-item label="作者" required="true" ><el-input v-model="editObj.author" placeholder="请输入作者"></el-input></el-form-item><el-form-item label="阅读状态" required="true" title="阅读状态只能输入0或者1;0代表未读,1代表已读"><el-input v-model="editObj.read_status" placeholder="请输入阅读状态"></el-input></el-form-item></el-form></div><span slot="footer" class="dialog-footer"><el-button @click="edit_dialogVisible = false">取消</el-button><el-button type="primary" @click="confirm">确定</el-button></span></el-dialog><!--详情对话框,新建一个对话框把编辑的代码复制过来,然后逻辑复制编辑额逻辑,再把确定和取消按钮去掉即可 --><el-dialog title="图书详情信息" :visible.sync="detail_dialogVisible" width="30%" :before-close="detail_handleClose"><div><el-form ref="form" :model="editObj" label-width="80px"><el-input type="hidden" v-model="editObj.id"></el-input><el-form-item label="书名" required="true"><el-input v-model="editObj.title" :disabled="true"></el-input></el-form-item><el-form-item label="作者" required="true"><el-input v-model="editObj.author" :disabled="true"></el-input></el-form-item><el-form-item label="阅读状态" required="true" title="阅读状态只能输入0或者1;0代表未读,1代表已读"><el-input v-model="editObj.read_status" :disabled="true"></el-input></el-form-item></el-form></div><!--详情对话框的确定和取消按钮去掉 <span slot="footer" class="dialog-footer"><el-button @click="edit_dialogVisible = false">取消</el-button><el-button type="primary" @click="confirm">确定</el-button></span>--></el-dialog></div>
</template><!--二、下面是JS部分-->
<script>export default {data() {return {msg: "欢迎访问图书管理系统",edit_dialogVisible: false,addbook_dialogVisible: false,detail_dialogVisible: false,id: '',title: '',author: '',read_status: '',bookInfo: [{id: '',title: '',author: '',read_status: ''}],editObj: {id: '',title: '',author: '',read_status: ''},editObj1: {title: '',author: '',read_status: ''},userIndex: 0,}},mounted() {this.check();},methods: {//1、显示方法getnetwork() {// console.log(this.bookinfo.id);var that = this this.$axios.post("http://127.0.0.1:5001/query",{id: "",  //这里不传id查所有}).then(function(res) {console.log(res.data) that.bookInfo = res.data.datathat.bookInfo = that.bookInfo.map(item=>{item.read_status = String(item.read_status)return item})// console.log(this.bookInfo)}).catch(function(err) {console.log(err)})},//2、查询方法check() {//确定查询按钮// console.log(this.bookname)var that = this//网络请求获取数据axiosthis.$axios.post("http://127.0.0.1:5001/query", {id: this.id,}).then(function(res) { //请求成功,方法回调//回调方法不能用thisconsole.log(res.data) console.log(res.data.data) that.bookInfo = res.data.datathat.bookInfo = that.bookInfo.map(item=>{//布尔类型转字符串item.read_status = String(item.read_status)return item})// console.log(this.data.id)}).catch(function(err) { //请求失败console.log(err)})},addbook() {this.addbook_dialogVisible = true;},edit(item, id) {this.id = id;console.log(id)this.editObj = {id: item.id,title: item.title,author: item.author,read_status: item.read_status,};this.edit_dialogVisible = true;},detail(item, id) {this.id = id;console.log(id)this.editObj = {id: item.id,title: item.title,author: item.author,read_status: item.read_status,};this.detail_dialogVisible = true;},//3、删除方法deleteRow(id) {console.log(id) if (confirm('确定要删除吗') == true) {var that = this//网络请求获取数据axiosthis.$axios.post("http://127.0.0.1:5001/delete", {id:id}).then(res =>{ //请求成功,方法回调 //回调方法不能thisthis.getnetwork()// getnetwork();console.log(res.data) }).catch(function(err) { //请求失败console.log("失败了" + err)})}},// 对话框右上角的×按钮handleClose() {//编辑this.edit_dialogVisible = false;},handleClose1() {//增加this.addbook_dialogVisible = false;},detail_handleClose() {//详情this.detail_dialogVisible = false;},//4、修改方法confirm() { //确认修改if (this.editObj.title === '') {this.$message({message: '书名不能为空!',type: 'warning'});return}if (this.editObj.author === '') {this.$message({message: '作者不能为空!',type: 'warning'});return}if (this.editObj.read_status === '') {this.$message({message: '阅读状态不能为空!',type: 'warning'});return}var that = this//网络请求获取数据axiosthis.$axios.post("http://127.0.0.1:5001/update", {id: this.editObj.id,title: this.editObj.title,author: this.editObj.author,read_status: this.editObj.read_status}).then(function(res) { //请求成功,方法回调//回调方法不能this  that.getnetwork()console.log(res.data) }).catch(function(err) { //请求失败console.log(err)}) this.edit_dialogVisible = false;// Vue.set(this.tableData, this.userIndex, this.editObj);},//5、 增加方法confirm_add() {// 确定增加按钮if (this.editObj1.title === '') {this.$message({message: '书名不能为空!',type: 'warning'});return}if (this.editObj1.author === '') {this.$message({message: '作者不能为空!',type: 'warning'});return}if (this.editObj1.read_status === '') {this.$message({message: '阅读状态不能为空!',type: 'warning'});return}var that = this//网络请求获取数据axiosthis.$axios.post("http://127.0.0.1:5001/add", {title: this.editObj1.title,author: this.editObj1.author,read_status: this.editObj1.read_status}).then(function(res) { //请求成功,方法回调//   this.$message.success('图书添加成功!');//回调方法不能用thisthat.getnetwork() // if (this.editObj1.read_status == success)console.log(res.data)//that.newsList = res.data}).catch(function(err) { //请求失败console.log(err)}) this.addbook_dialogVisible = false;// Vue.set(this.tableData, this.userIndex, this.editObj);},// 给表头增加提示renderHeader(h,{column}){const serviceContent= [h('div',{slot:"content",},"提示:true代表已读,false代表未读")]return h("div",[h("span",column.label),h("el-tooltip",{props:{placement:"top"}},[serviceContent,h("i",{class:"el-icon-warning-outline",style:"color:blue;margin-left:5px;"})])]);},},}
</script>
<!-- 三、CSS部分 颜色、样式自己调试,这里就能体会有UI工程师的好处-->
<style>
/**标签为class属性就用.修饰,标签属性为id的话用#修饰。**/.add-btn{ width:450px }   .input{ width: 220px; height: 70px; } .button{color: rgb(246, 241, 248);background-color: rgb(187, 187, 221);}#app{ width: 1024px; margin: 0 auto; } #back{ height: 200px; }.block{text-align:left}.star{color: #F56C6C;font-size: 14px;margin-right: 4px;}
</style>

有疑问来评论区或者私信一起学习交流

Flask+VUE 实现页面增删改查显示开发+测试(图文教程附源码)相关推荐

  1. SpringBoot+vue+jpa+mysql前后台分离实现增删改查分页和三级联动(附源码)(一)

    数据库命名为:demo demo.sql内容如下: (可以直接运行demo.sql文件) /*Navicat Premium Data TransferSource Server : MysqlSou ...

  2. Struts2增删改查 myeclipse开发文档加项目源码及eclipse开发项目源码

    Struts2增删改查 myeclipse开发文档加项目源码及eclipse开发项目源码 git里只有myeclipse开发的项目 文档及项目github下载地址:https://github.com ...

  3. Flask+mysql 实现增删改查接口开发+测试(图文教程附源码)

    目录 一.前言 二.环境准备 2.1 安装python 2.2 安装mysql 三.工具准备 3.1 安装pycharm 3.2 安装Navicat 3.3 安装postman 四.mysql数据库准 ...

  4. 前端vue+后端koa,全栈式开发bilibili首页(附源码)

    技术栈 前端:vue3 + vuex + vite + stylus + nginx 后端:koa2 源码下载: 源码下载链接:https://wwb.lanzouy.com/iwSVW0bpr4be ...

  5. Vue学习(增删改查、ES6模块化概念)-学习笔记

    文章目录 Vue学习(增删改查.ES6模块化概念)-学习笔记 增删改查案例 ES6模块化概念 Vue学习(增删改查.ES6模块化概念)-学习笔记 增删改查案例 <!DOCTYPE html> ...

  6. vue结合php增删改查实例,从vue基础开始创建一个简单的增删改查的实例

    1.安装vue-clicnpm install vue-cli -g  --执行全局安装 2.创建一个webpack的基础项目:命令:vue init webpack myproject; 以下是项目 ...

  7. flask对mysql数据库增删改查_Flask学习(三) - Flask-SQLAlchemy对数据库增删改查

    Flask-SQLAlchemy对数据库增删改查 安装 pip install flask-sqlalchemy 具体不多说了,主要是对数据库进行简单的增删改查,上代码,看注释 @app.route( ...

  8. flask 蓝图 使用蓝图,增删改查用户

    Flask 中的  蓝图 蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? 比如说,你有一个客户管理系统, ...

  9. 使用SpringBoot一小时快速搭建一个简单后台管理(增删改查)(超详细教程)

    最近也是临近期末了,各种的期末大作业,后台管理也是很多地方需要用到的,为了方便大家能快速上手,快速搭建一个简单的后台管理,我花了两天时间整理了一下 我会从0开始介绍,从数据库的设计到前端页面的引入最后 ...

最新文章

  1. 把JS 脚本嵌入CS运行
  2. 混淆矩阵是什么?Python多分类的混淆矩阵计算及可视化(包含原始混淆矩阵及归一化的混淆矩阵):基于skelarn框架iris数据集
  3. php+ajax简单实现跨域(http+https)请求调用
  4. Java System类
  5. BZOJ1509: [NOI2003]逃学的小孩(树的直径)
  6. sts集成jboss_与JBoss BPM Travel Agency更新了Modern BPM数据集成
  7. mysql的Innodb为什么使用B+树
  8. Linux多线程同步
  9. SQL Server Storage
  10. 小米八显示无服务器,二修小米8无服务案例
  11. 现代通信理论与新技术 - 填空自测
  12. Oracle日期函数总结
  13. 卸载 Creative Cloud 桌面应用程序(macOS、Windows)
  14. 记在2019,winter is coming
  15. android的权限一览表和RGB颜色对照表
  16. java jtextarea.setfont_如何在JTextArea中更改文本颜色?
  17. 设计模式: 单例模式
  18. 添加打印机还显示脱机_打印机脱机状态怎么解除
  19. 【RGSS3 与旧版的比较】
  20. 分段概率密度矩估计_南昌大学概率论与数理统计练习答案.doc

热门文章

  1. AWS EC2 instance IP网络 - Private/Public/Elastic IP address
  2. 参考 | 辨别真假笔记本三星内存条 (ddr4)
  3. 每日一个小技巧:1分钟告诉你如何录音翻译成文字
  4. excel 查找两列的共同元素
  5. 软件测试真实BAT大厂技术总监三面,已成功入职【建议收藏】附标准答案
  6. 瀑布模型,v模型与双V模型
  7. oracle dml commit,Oracle dml开始到commit期间的流程
  8. JIRA基本操作了解
  9. Excel如何将表转换为另一种格式的表(表1转换为表2),表转换的绿色工具,支持一行变多行,多行变一行,行变列,列边行等等
  10. echarts的dataZoom里的endValue设置固定长度