flask+vue:创建一个数据列表并实现简单的查询功能(一)
之前写过一个数据构造工具,当时用的Django+vue,后来又用flask重写了一下后端逻辑
本次打算在现有基础上加点东西:新增一个数据列表,数据列表中展示曾经创建好的数据
拆解下这次要做的功能:
1、每创建一次数据,都把数据写到数据库中;
2、从数据库中查询创建好的数据返给前端;
3、前端构建一个数据列表,把后端数据渲染到列表中;
4、数据列表添加查询功能;
5、数据列表添加分页功能
1、添加查询功能
在页面添加列表查询功能,我需要构造2个查询条件:
【数据类型】,把它做成下拉框形式,筛选对应类型的数据
【创建日期】,通过日期筛选创建日期在所选时间范围内的数据
点【查询】会把对应参数传到请求中,筛选符合条件的结果;
点【重置】会清空查询框输入的条件;
DatePicker 日期选择器
这部分样式代码如下
<el-row><el-col :span="24">
<div class="grid-content bg-purple-dark">
<el-form :inline="true" :model="form" size="small" ref="ruleForm" class="demo-form-inline" style="margin-left: 10px">
<el-form-item label="数据类型" prop="class">
<el-select v-model="form.class" placeholder="请选择数据类型" clearable>
<el-option label="电话" value="1"></el-option>
<el-option label="身份证ID" value="2"></el-option>
<el-option label="姓名" value="3"></el-option>
</el-select>
</el-form-item>
<el-form-item label="创建日期" prop="create_date">
<el-date-picker
v-model="form.create_date"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd HH:mm:ss"
:default-time="['00:00:00', '23:59:59']">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">查询</el-button>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</el-col>
</el-row>
对应的js代码
<script>export default {
data() {
return {
form: {
class: '',
create_date: '',
}
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let payload = { // 定义请求参数
class_type: this.form.class,
create_date: this.form.create_date
}
console.log("打印查询条件输入的参数payload")
console.log(payload)
console.log("打印日期框选择框填写的日期")
console.log(this.form.create_date)
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
}
}
</script>
实现效果
代码说明:
1、点击【重置】,能够清空输入框输入的内容
,分别绑定到【查询】【重置】按钮
prop属性
;
DatePicker 的使用配置
2022-01-13 00:00:00~2022-01-15 23:59:59
在element-ui官方文档中,可以找到相关配置参数
指定绑定值的格式,
指定起始日期的时刻与结束日期的时刻,
3、定义请求参数,查看一下前端传的参数的具体值是什么样的
submitForm()方法中先定义了查询接口触发时所需的参数:一个是数据类型,一个是创建日期
class_type表示数据类型,create_date表示创建日期
它们分别获取前端传来的参数,打印一下结果
可以看到create_date是一个包含开始日期和结束日期数组,
接下来再看一下参数为空的清空
(1)数据类型、创建日期默认为空时,传的参数如下
''
(2)数据类型、创建日期先填写值再重置,传的参数如下
['']
,
['']
所以后端处理create_date为空的情况时需要考虑这种情况
2、添加列表
组件添加一个列表展示数据
样式代码
<el-table:data="tableData"
border
height="350"
style="width: 100%; margin-top: 30px;margin-left: 10px">
<!-- height 表格默认高度,添加height属性,即可实现固定表头的表格
-->
<el-table-column
type="index"
width="50">
</el-table-column>
<el-table-column
prop="date"
label="日期"
width="180"
align="center"> <!--使用align控制对齐方式-->
</el-table-column>
<el-table-column
prop="type"
label="类型"
width="180"
align="center">
</el-table-column>
<el-table-column
prop="value"
label="生成的测试数据"
align="center">
</el-table-column>
</el-table>
控制每列标题的对齐方式,
,表示往列表中插入的数据
对应js代码
<script>export default {
data() {
return {
tableData: [{
date: '2022-01-10',
type: '电话号码',
value: '13140845519'
}, {
date: '2022-01-10',
name: '电话号码',
value: '18136773435'
}, {
date: '2022-01-10',
type: '电话号码',
value: '14592741294'
}]
}
}
}
</script>
tableData
3、添加分页功能
组件给列表进行分页
样式代码
<div class="block" style="margin-top: 10px; text-align: right;"> <!--使用text-align控制div右对齐--><el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="[5, 10, 20, 30, 50]"
:page-size="5"
layout="total, sizes, prev, pager, next, jumper"
:total="parseInt(count)">
</el-pagination>
</div>
对应js代码
<script>export default {
data() {
return {
form: {
class: '',
create_date: '',
},
currentPage: 1,
pageSize:5,
count: null,
tableData: null
};
},
methods: {
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
this.pageSize = val
console.log("打印当前的pageSize")
console.log(this.pageSize)
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let payload = { // 定义请求参数
class_type: this.form.class,
create_date: this.form.create_date,
page_num: this.currentPage,
page_size: this.pageSize
}
console.log("打印查询条件输入的参数payload")
console.log(payload)
console.log("打印日期框选择框填写的日期")
console.log(this.form.create_date)
} else {
console.log('error submit!!');
return false;
}
});
}
}
}
</script>
page-size、当前页码current-page
是根据当前查询条件查询后后端返回的数据总量;
这2个参数需要跟着请求发送,后端根据参数来返回对应查询结果
下新增了4个参数:
用来接收后端返回的数据总量,它的值必须为整数
用来接收接口返回并处理后的列表数据
current-page和page-size
时,这个2个参数能够传给后端实时的数值
事件
.sync 修饰符
currentPage
也会获取到最新的值
事件
方法,它的回调参数就是每页条数
绑定这个事件,那么当每页条数发生变化时,就会触发这个事件,回调参数即是当前的每页条数
参数,
就能得到最新的每页条数了
this.pageSize = val
赋一个初始值,这样每次刷新页面,当前每页条数就显示这个定义的初始值
,这俩参数其实是我传给后端请求接口中的2个参数
的值
在控制台打印下结果,可以看到每次切换当前条数和页码,都能获取到最新的值
4、后端处理
前端代码先写到这里,接下来先在后端把接口定义出来
我们需要定义一个接口来供前端调用,根据前端传参,来返回列表所需的数据
page_size
因为数据创建好后存到了数据库中,所以我们需要从数据库中查出数据返给前端
编写sql时需要考虑到如下几点:
- 当某个查询条件为空时,sql语句中则不加这个条件;
- );
- 因为涉及到分页,根据前端请求参数,控制查询第一页数据、第二页数据等以及每页数据条数;
.py
# coding: utf-8"""
author: hmk
detail:
create_time:
"""
from flask import Blueprint
from flask_restful import Api, Resource
from flask import request
from utils.connect_db import MysqlConnect
import time
select_data_bp = Blueprint('select_data', __name__) # 创建一个蓝本
api = Api(select_data_bp) # 使用这个蓝本创建一个Api对象
class SelectData(Resource):
def __init__(self):
self.db = MysqlConnect()
def get(self):
"""列表查询接口"""
class_type = request.args.get("class_type") # 获取前端参数"type"
create_date = request.args.getlist("create_date[]") # 获取前端传来的list格式数据(前端叫做array,数组)
page_num = int(request.args.get("page_num")) # 当前页码
page_size = int(request.args.get("page_size")) # 每页显示数据条数
print("********************")
# print(class_type)
print(create_date)
# print(page_num)
# print(page_size)
# print(type(page_num))
class_type_data = { # 定义一个字典,映射数据类型与类型编号的关系
"1": "电话号码",
"2": "身份证id",
"3": "姓名"
}
sql1 = None
sql2 = None
if class_type == "":
if not create_date or create_date == ['']:
sql1 = "select type_name, value, date_format(create_time, '%Y-%m-%d') from data_list LIMIT {},{}"\
.format((page_num-1)*page_size, page_size)
sql2 = "select count(*) from data_list;"
else:
startDate = create_date[0] # request.args.get("startDate")
endDate = create_date[1] # request.args.get("endDate")
sql1 = "select type_name, value, date_format(create_time, '%Y-%m-%d') from data_list where " \
"create_time between '{}' AND '{}' LIMIT {},{};"\
.format(startDate, endDate, (page_num-1)*page_size, page_size)
sql2 = "select count(*) from data_list where create_time between '{}' AND '{}';"\
.format(startDate, endDate)
elif class_type != "":
if not create_date or create_date == ['']:
sql1 = "select type_name, value, date_format(create_time, '%Y-%m-%d') from data_list " \
"where type_name='{}' LIMIT {},{};"\
.format(class_type_data[class_type], (page_num-1)*page_size, page_size)
sql2 = "select count(*) from data_list where type_name='{}';".format(class_type_data[class_type])
else:
startDate = create_date[0] # request.args.get("startDate")
endDate = create_date[1] # request.args.get("endDate")
sql1 = "select type_name, value, date_format(create_time, '%Y-%m-%d') from data_list " \
"where type_name='{}'" \
"and create_time between '{}' AND '{}' LIMIT {},{};"\
.format(class_type_data[class_type], startDate, endDate, (page_num-1)*page_size, page_size)
sql2 = "select count(*) from data_list " \
"where type_name='{}'" \
"and create_time between '{}' AND '{}';".format(class_type_data[class_type], startDate, endDate)
print("################### 打印sql1 #########################")
print(sql1)
history_data = self.db.select_all(sql1)
print("################### 打印查询到的所有数据 #########################")
print(history_data)
print("################### 打印sql2 #########################")
print(sql2)
count = self.db.select_one(sql2)[0]
print("################### 打印查询到的数据总条数 #########################")
print(count)
self.db.close()
data = {
"code": 200,
"records": history_data,
"count": count
}
time.sleep(0.5)
return data
api.add_resource(SelectData, '/api/select_data')
代码说明:
是用来查询数据总量的,显示当前查询条件下共有多少条数据;
(2)这里定义该接口为get请求,所以用request.args.get来获取前端传来的参数;
注意:在提取日期参数时,是这样提取的
getlist
来实现返回对应数据,如下
假如每页显示10条,那么
第1页的数据为1~10,
第2页的数据为11~20,
第3页的数据为21~30,依此类推
对应到sql中limit方法下,
第1页数据为limit 0, 10; 从第1行开始,检索10条记录
第2页数据为limit 10, 10; 从第11行开始,检索10条记录,也就是11~20
第3页数据为limit 20, 10; 从第21行开始,检索10条记录,也就是21~30
后,就可以写出如下sql
这里查出来的数据为元组,如果直接返回到前端会解析为列表
前端请求后,接口返回如下
5、前端发送请求,处理接口返回数据
方法中添加axios发送请求
submitForm(formName) {this.$refs[formName].validate((valid) => {
if (valid) {
let url1 = "http://127.0.0.1:5000/"
let payload = { // 定义请求参数
class_type: this.form.class,
create_date: this.form.create_date,
page_num: this.currentPage,
page_size: this.pageSize
}
console.log("打印查询条件输入的参数payload")
console.log(payload)
console.log("打印日期框选择框填写的日期")
console.log(this.form.create_date)
axios({
timeout: 10000,
method: "get",
params: payload, //发送get请求,使用params关键字接收请求参数
url: url1+"api/select_data"
}).then(res => {
console.log(res.data.records) //打印返回的原始数据
let data_list = res.data.records.map(function(array) {
let rObj = {};
rObj["date"] = array[2]
rObj["type"] = array[0]
rObj["value"] = array[1]
return rObj;})
console.log(data_list)
this.tableData = data_list
// let data_count = res.data.count
this.count = res.data.count
// console.log(data_list)
// console.log(data_count)
if(res.data.code === 200){ //判断响应中的code是否为200
// console.log(res.data)
this.$message({ // 接口调用成功后,添加页面toast提示
message: '接口调用成功',
type: 'success'
});
}
else{
console.log(res.data)
}
}).catch((reason)=>{
console.log(reason)
this.$message({
message: '接口调用失败,请检查系统是否正常',
type: 'warning'
});
})
// console.log(typeof this.currentPage)
} else {
console.log('error submit!!');
return false;
}
});
},
代码说明:
是发送请求后返回的原始数据,即接口中定义的records
但是它的格式如下,不能直接给前端列表用
前端列表需要如下格式的数据
对象
来实现,代码如下
在map中定义了一个函数,它的作用就是构造一个对象,分别用date、type、value作为键,然后分别赋上接口返回数组中每个小数组对应的值,这样处理后,接口返回的数组就变为了如下形式
count
它的作用是把接口返回的数据总数赋给count
之前在分页组件中我们把count的值赋给了total,如下
到这里为止,基本目的就达到了,从后端取出数据渲染到前端,同时可以分页、显示数据总量、并且可以查询
以上是 flask+vue:创建一个数据列表并实现简单的查询功能(一) 的全部内容, 来源链接: utcz.com/z/374807.html