前言
在前面的
Api
開發中,我們使用
FastApi
已經可以很好的實作。但是實際使用中,我們通常建議前後端項目分離。今天我們就使用
FastApi+Vue+LayUI
做一個前後端分離的
Demo
。
項目設計
後端
後端我們采用
FastApi
在新的
test
視圖中,定義一個路由,并将其注冊到
app
中,并且在
test
視圖中定義一個接口,實作模拟從資料庫讀取資料供前端調用渲染。
代碼
test.py
from fastapi import FastAPI,Depends,Header,HTTPException,APIRouter
from fastapi.param_functions import Body
from starlette.requests import Request
from starlette.templating import Jinja2Templates
from starlette import status
import uvicorn
from deta import Deta
from fastapi.responses import StreamingResponse
from fastapi.responses import JSONResponse
# 執行個體化路由器
router = APIRouter()
templates = Jinja2Templates('templates')
# 注意,視圖這裡使用router來聲明請求方式&URI
@router.get('/info')
def user_list():
# vue的響應資料
items = [
{'id':'1','name':'phyger'},
{'id':'2','name':'fly'},
{'id':'3','name':'enheng'},
]
return JSONResponse(content=items)
@router.get('/')
def welcome():
return "這裡是測試路由"
'''
實際上,這裡的home.html也是需要前端服務去向使用者渲染的,
但是我們為了友善示範,未啟動前端伺服器,直接将前端代碼寫在了home.html中,
實際上,當使用者請求/check的時候,前端代碼會去請求/info接口擷取資料,
進而實作前端頁面的資料渲染。
'''
@router.get('/check')
def home(request:Request):
return templates.TemplateResponse(name='home.html',context={'request':request,})
複制
前端
前端我們直接導入
Vue、LayUI、Axios
的
JS
和
CSS
的
CDN
資源,在
Vue
執行個體的
mount
階段,使用
axios
調用後端接口拿到資料,使用
LayUI
的樣式對
table
元素進行美化。
代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/vue@next"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 引入 layui.css -->
<link rel="stylesheet" href="https://www.layuicdn.com/layui/css/layui.css"/>
<!-- 引入 layui.js -->
<script src="https://www.layuicdn.com/layui/layui.js" type="text/javascript" charset="utf-8"></script>
<title>Home</title>
</head>
<body>
<div id="app">
<table class="layui-table">
<tr v-for="p in infos">
<td>[[ p.id ]]</td>
<td>[[ p.name ]]</td>
</tr>
</table>
</div>
<table id="test" class="layui-table"></table>
<script type="text/javascript">
const Vapp = Vue.createApp({
data() {
return {
infos: [{id:1,name:'phyger'}],
info: "hello vue..."
}
},
mounted() {
this.showinfo();
},
methods: {
showinfo(){
axios.get('/test/info')
.then(response=>{
this.infos=response.data;
console.log(response);
console.log(this.infos);
})
,err=>{
console.log(err);
};
},
},
})
Vapp.config.compilerOptions.delimiters = ['[[', ']]']
Vapp.mount('#app')
</script>
</body>
</html>
複制
運作項目
啟動
FastApi
後端伺服器,通路
/test/check
接口。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAjM2EzLcd3LcJzLcJzdllmVldWYtl2Pn5GcuU2N4QDM0MTOhNmZyMWN3IGMzkDNzEmYzYjYkF2NjRWMvwlM1ATNzcDOtUGall3LcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.png)
Q&A
Q:為什麼在請求
/info
接口總會出現一個
Temporary Redirect
重定向呢?
A:原因是因為我們在
FastApi
接口定義的時候,
uri
的格式不規範導緻,
uri
的結尾不需要
/
,如果你接口增加了
/
,我們使用浏覽器通路
uri
,浏覽器會忽略結尾的
/
,
FastApi
會在内部進行查重定向,将浏覽器不帶
/
的請求重定向到我們定義的帶
/
的視圖函數上。