vue-element-admin+flask實(shí)現(xiàn)數(shù)據(jù)查詢項(xiàng)目的實(shí)例代碼
當(dāng)今前端世界最流行的三個(gè)框架Vue,React,Angular。這三個(gè)框架可謂是各有千秋,可以滿足不同場(chǎng)景的需求。我們這套實(shí)踐分享內(nèi)容主要是使用Vue框架,這個(gè)框架上學(xué)習(xí)起來(lái)非常容易,很容易上手。相對(duì)React陡峭的學(xué)習(xí)曲線,Vue顯得格外簡(jiǎn)單和友好。好了,選好了框架后,我們還需要選擇UI組件庫(kù)。基于Vue框架開發(fā)的UI組件庫(kù)也有很多,例如:View UI ,Element UI等等。我們這里使用Element UI做為我們的UI組件庫(kù)。它的生態(tài)很豐富,有很多開源的集成了很多日常開發(fā)中常用的功能。在這個(gè)項(xiàng)目中,我們采用vue-element-admin。vue-element-admin 是一個(gè)后臺(tái)前端解決方案,它基于 vue 和 element-ui實(shí)現(xiàn)。它使用了最新的前端技術(shù)棧,內(nèi)置了 i18n 國(guó)際化解決方案,動(dòng)態(tài)路由,權(quán)限驗(yàn)證,提煉了典型的業(yè)務(wù)模型,提供了豐富的功能組件,可以幫助我們快速搭建企業(yè)級(jí)中后臺(tái)產(chǎn)品。
本文分享一個(gè)使用vue-element-admin+flask實(shí)現(xiàn)的一個(gè)數(shù)據(jù)查詢項(xiàng)目,
填寫數(shù)據(jù)庫(kù)連接信息和查詢語(yǔ)句,即可展示查詢到的數(shù)據(jù)。

前提:已下載vue-element-admin并編譯成功
前端
1、添加路由
src-router-index.js添加路由
{
path: '/idata',
component: Layout,
redirect: '/idata/index',
hidden: false,
children: [
{
path: 'index',
component: () => import('@/views/idata/index'),
name: 'idata',
meta: { title: 'iData設(shè)置', icon: 'list', noCache: true }
}
]
},
2、添加頁(yè)面元素
在src-views下新建idata目錄,目錄下新建index.vue
<template>
<div class="app-container">
<el-card class="box-card">
<el-form :inline="true" ref="formData" :rules="rules" :model="formData" label-width="55px">
<el-form-item label="域名" prop="db_host">
<el-input
v-model="formData.db_host"></el-input>
</el-form-item>
<el-form-item label="端口" prop="db_port" >
<el-input
v-model="formData.db_port" style="width: 80px;"></el-input>
</el-form-item>
<el-form-item label="用戶名" prop="db_user">
<el-input
v-model="formData.db_user" style="width: 80px;"></el-input>
</el-form-item>
<el-form-item label="密碼" prop="db_passwd">
<el-input
v-model="formData.db_passwd" show-password></el-input>
</el-form-item>
<el-form-item label="數(shù)據(jù)庫(kù)" prop="db_name">
<el-input
v-model="formData.db_name"></el-input>
</el-form-item>
<el-row>
<el-input
type="textarea"
:rows="5"
placeholder="請(qǐng)輸入SQL語(yǔ)句"
v-model="formData.sql">
</el-input>
</el-row>
<el-row>
<el-button type="primary" @click="onConnect('formData')">測(cè)試連接</el-button>
<el-button type="primary" @click="onExec('formData')">執(zhí)行SQL</el-button>
<p>{{message}}</p>
</el-row>
</el-form>
</el-card>
<el-card class="box-card">
<el-table
:data="tableData"
style="width: 100%">
<el-table-column v-for="h in tableHead" :key="h"
:prop="h" :label="h">
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
import { getConnect, doConnect, exec } from '@/api/idata'
export default {
name: 'idata',
data() {
return {
rules: {
db_host: [
{ required: true, message: '請(qǐng)輸入域名', trigger: 'blur' }
],
db_port: [
{ required: true, message: '請(qǐng)輸入端口', trigger: 'blur' }
],
db_user: [
{ required: true, message: '請(qǐng)輸入用戶名', trigger: 'blur' }
],
db_passwd: [
{ required: true, message: '請(qǐng)輸入密碼', trigger: 'blur' }
],
db_name: [
{ required: true, message: '請(qǐng)輸入數(shù)據(jù)庫(kù)', trigger: 'blur' }
]
},
title: 'iData設(shè)置',
formData: {
db_charset: 'utf8',
db_host: null,
db_port: null,
db_user: null,
db_passwd: null,
db_name: null,
sql: null,
param: {},
key: 'all'
},
tableData: [],
time: 0,
uniqKey: null,
maxCount: 20,
sql: null,
message:null,
tableHead: [],
result:[]
}
},
methods: {
onConnect (formName) {
this.$refs[formName].validate((valid) =>{
if (valid) {
doConnect({
...this.formData
}).then(res => {
this.uniqKey = res.uniq_key
this.message='連接成功'
this.$message({
message: '連接測(cè)試成功!',
type: 'success'
})
})
}
else {
this.$message({
message: '請(qǐng)檢查必填字段!',
type: 'error'
})
return false
}
}
)//驗(yàn)證函數(shù)結(jié)尾
},
onExec (formName) {
this.$refs[formName].validate((valid) =>{
if (valid) {
if (!this.formData.sql) {
this.$message({
message: 'SQL 語(yǔ)句不能為空。',
type: 'warning'
})
return
}
exec({
...this.formData,
}).then(res => {
if (res.data.length > 0) {
this.tableHead = []
for (let i in res.data[0]) {
this.tableHead.push(i)
}
this.tableData = res.data
this.time = res.time_cost
} else {
this.tableHead = []
this.tableData = []
}
this.message='查詢成功'
this.loading = false
this.$message({
message: '查詢成功',
type: 'success'
}
)
}
).catch(err => {
this.loading = false
console.log(err)
this.$message({
type: 'error'
})
})
}
else {
this.$message({
message: '請(qǐng)檢查必填字段!',
type: 'error'
})
console.log('error submit!!')
return false
}
}
)//驗(yàn)證函數(shù)結(jié)尾
}//onconnect函數(shù)結(jié)尾
}
}
</script>
3、添加請(qǐng)求
在src-api新建idata.js
import request from '@/utils/request'
export function doConnect (data) {
return request({
url: '/api/test',
method: 'post',
data
})
}
export function exec (data) {
return request({
url: '/api/idata',
method: 'post',
data
})
}----拿到ret結(jié)果,根據(jù)結(jié)果來(lái)顯示默認(rèn)按鈕/成功按鈕。
----如何展示查詢到的數(shù)據(jù)呢? 前端實(shí)際有一個(gè)table,動(dòng)態(tài)讀取結(jié)果字段顯示。
----查詢數(shù)據(jù)時(shí),前端一直報(bào)錯(cuò),顯示error,控制臺(tái)顯示uncanght promise報(bào)錯(cuò)。
查了一會(huì),才發(fā)現(xiàn)是后端返回的ret沒有code這個(gè)字段,加上就可以了。
----如何將textraea輸入框?qū)挾仍黾?br />----彈框消息
this.$message({
message: '連接測(cè)試成功!',
type: 'success'
})
----前端方法里的response.data實(shí)際是取的返回結(jié)果data這個(gè)key的值
---- this.$refs 用來(lái)給標(biāo)簽或者組件添加屬性。需要這個(gè)標(biāo)簽或者組件中有ref=
<el-form :inline="true" ref="formData" :rules="rules" :model="formData"
label-width="70px">
----控制臺(tái)可以調(diào)試前端代碼
-----form加:rules="rules" 并且在return里寫上規(guī)則,并且每個(gè)el-form-item要有prop,可以實(shí)現(xiàn)
校驗(yàn)必填 其實(shí)在el-form這個(gè)組件有寫對(duì)于表單的校驗(yàn)
-----加了校驗(yàn)后報(bào)錯(cuò) Cannot read properties of undefined (reading 'validate')
傳參需要加引號(hào)submit('formName')。
this.$refs[formName].validate 這一行是對(duì)的
后端
這里只貼主要代碼,有時(shí)間再繼續(xù)貼。
1、添加路由
app.py添加
app.route('/api/idata', methods=['POST'])(idata)
app.route('/api/test',methods=['POST'])(onconnect)
2、添加函數(shù)
controller下data.py
import json
from flask import request, current_app as app
from constant import SQLTYPE, DBKEYTYPE
from lib.dbpool import DBPool
def idata():
return query(request.json)
def onconnect():
data=request.json
conn_info = warp_db_conn_info(data)
print(conn_info)
db_conn = DBPool.get_conn(**conn_info)
ret = {
"success": False,
"msg": None,
'code':0
}
if not db_conn:
ret['msg'] = '連接目標(biāo)DB失敗,請(qǐng)確認(rèn)連接信息是否正確'
ret['code']=-1
else:
ret['msg'] = '連接成功'
ret['success']=True
ret['code']=0
return ret
def warp_db_conn_info(data):
d = {}
keys = ['db_host', 'db_port', 'db_name', 'db_user', 'db_passwd', 'db_charset']
for key in keys:
if key in data and data[key]:
d[key] = data[key].strip() if isinstance(data[key], (str, bytes)) else data[key]
return d
def query(data):
"""
根據(jù)DB和SQL信息執(zhí)行遠(yuǎn)程查詢并返回結(jié)果
:param data: {
"db_host": "x.x.x.x",
"db_port": 3306,
"db_name": "test",
"db_user": "root",
"db_passwd": "root",
"db_charset": "utf8",
"sql": "select * from tbl_key_info where id=:id limit 1",
"param": {
"id": 100110
},
"key": "all"
}
:return: {
"success": True,
"data": [{"id": 100110, "xxx", "xxx"}],
"type": "SELECT",
"msg": ""
}
"""
app.logger.info(f'query data {json.dumps(data)}')
ret = {
"success": False,
"data": [],
"type": None,
"msg": None,
"code":0
}
if not data:
return ret
conn_info = warp_db_conn_info(data)
# print(conn_info)
db_conn = DBPool.get_conn(**conn_info)
if not db_conn:
ret['msg'] = '連接目標(biāo)DB失敗,請(qǐng)確認(rèn)連接信息是否正確'
return ret
sql = data.get('sql')
if not sql:
ret['msg'] = '查詢語(yǔ)句不能為空'
return ret
# app.logger.info(f'查詢語(yǔ)句: {sql}, 查詢參數(shù): {data.get("param")}')
app.logger.info(f'查詢語(yǔ)句: {sql}, 查詢參數(shù): {data.get("param")}')
# rows = db_conn.query(sql, **data.get('param'))
rows = db_conn.query(sql)
results = []
upper_sql = sql.upper().strip()
if upper_sql.startswith(SQLTYPE.INSERT):
sql_type = SQLTYPE.INSERT
elif upper_sql.startswith(SQLTYPE.UPDATE):
sql_type = SQLTYPE.UPDATE
elif upper_sql.startswith(SQLTYPE.DELETE):
sql_type = SQLTYPE.DELETE
elif upper_sql.startswith(SQLTYPE.SELECT):
sql_type = SQLTYPE.SELECT
key = data.get('key', DBKEYTYPE.FIRST)
if key == 'all':
results = rows.as_dict()
else: # 為了減少網(wǎng)絡(luò)傳輸,默認(rèn)只查詢一行
first = rows.first()
results = [first.as_dict()] if first else []
else:
sql_type = SQLTYPE.UNKNOWN
ret.update(
{
"success": True,
"data": results,
"type": sql_type,
"msg": '',
'code':0
}
)
app.logger.info(f'查詢結(jié)果: {results}')
return ret
dbpool.py用來(lái)進(jìn)行數(shù)據(jù)庫(kù)連接
import records
from urllib import parse
class DBPool:
db_pool = {}
@staticmethod
def get_conn(db_host=None, db_name=None, db_port="3306", db_user='root',
db_passwd='root', db_charset='utf8'):
if db_host is None or db_name is None:
raise ValueError("host and db_name can't be None.")
key = DBPool.make_uniq_key(db_host, db_port, db_name)
if key not in DBPool.db_pool:
sql_str = DBPool.make_conn_str(db_host, db_name, db_port, db_user, db_passwd, db_charset)
print(sql_str)
DBPool.db_pool[key] = records.Database(sql_str, pool_pre_ping=True)
try:
db = DBPool.db_pool[key]
db.query('''select 1''')
except:
db = None
del DBPool.db_pool[key]
return db
@staticmethod
def make_uniq_key(db_host, db_name, db_port):
return f'{db_host}:{db_port}:{db_name}'
@staticmethod
def make_conn_str(db_host, db_name, db_port, db_user, db_passwd, db_charset):
return f'mysql+pymysql://{db_user}:{parse.quote_plus(db_passwd)}@{db_host}:{db_port}/{db_name}?charset={db_charset}'
今天晚了,改天有時(shí)間再詳細(xì)講解。
到此這篇關(guān)于vue-element-admin+flask實(shí)現(xiàn)數(shù)據(jù)查詢項(xiàng)目的文章就介紹到這了,更多相關(guān)vue-element-admin數(shù)據(jù)查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中使用element ui的彈窗與echarts之間的問(wèn)題詳解
這篇文章主要介紹了vue中使用element ui的彈窗與echarts之間的問(wèn)題詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
強(qiáng)烈推薦!Vue3.2中的setup語(yǔ)法糖
script?setup是vue3的新語(yǔ)法糖,并不是新增的功能模塊,只是簡(jiǎn)化了以往的組合式API必須返回(return)的寫法,并且有更好的運(yùn)行時(shí)性能,這篇文章主要給大家介紹了關(guān)于Vue3.2中setup語(yǔ)法糖的相關(guān)資料,需要的朋友可以參考下2021-12-12
vue項(xiàng)目實(shí)現(xiàn)多語(yǔ)言切換的思路
這篇文章主要介紹了vue項(xiàng)目實(shí)現(xiàn)多語(yǔ)言切換的思路,幫助大家完成多語(yǔ)言翻譯,感興趣的朋友可以了解下2020-09-09
vue路由$router.push()使用query傳參的實(shí)際開發(fā)使用
在vue項(xiàng)目中我們用函數(shù)式編程this.$router.push跳轉(zhuǎn),用query傳遞一個(gè)對(duì)象時(shí)要把這個(gè)對(duì)象先轉(zhuǎn)化為字符串,然后在接收的時(shí)候要轉(zhuǎn)化為對(duì)象,下面這篇文章主要給大家介紹了關(guān)于vue路由$router.push()使用query傳參的實(shí)際開發(fā)使用,需要的朋友可以參考下2022-11-11
詳解Vue3.0 + TypeScript + Vite初體驗(yàn)
這篇文章主要介紹了詳解Vue3.0 + TypeScript + Vite初體驗(yàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
解決vue+elementui項(xiàng)目打包后樣式變化問(wèn)題
這篇文章主要介紹了解決vue+elementui項(xiàng)目打包后樣式變化問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
Vue關(guān)于訪問(wèn)外鏈?zhǔn)〉膯?wèn)題
這篇文章主要介紹了Vue關(guān)于訪問(wèn)外鏈?zhǔn)〉膯?wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
vue 中 get / delete 傳遞數(shù)組參數(shù)方法
這篇文章主要介紹了vue 中 get / delete 傳遞數(shù)組參數(shù)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Vue3中ref和reactive的基本使用及區(qū)別詳析
這篇文章主要給大家介紹了關(guān)于Vue3中ref和reactive的基本使用及區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-07-07

