如何连接 Vue.js 作为前端和 Fastapi 作为后端
How to connect Vue.js as frontend and Fastapi as backend
我正在 Jobs Portal 上构建一个项目,我需要 Vue 作为前端和 Fastapi 作为后端(添加、删除更新)。我想知道我是否可以将它们连接起来。
I want to know if i can connect these both or not.
快速回答:是的,您可以连接。
但是有很多方法,您可以使用 Jinja 之类的东西呈现模板,或者您可以使用 Vue CLI 之类的东西创建一个完全不同的项目,您可能想使用 Nginx 或 Apache 等东西来连接两者。
让我们用 Jinja 创建一个示例应用程序
结构
├── main.py
└── templates
└── home.html
后端- main.py
- 我们在
/
中为我们的前端提供服务,并在该路径中呈现我们的 home.html
。
- 我们正在使用模板文件夹来保存我们的 HTML 并将其传递给 Jinja。
- 此外,我们将从我们的 front-end 向
/add
发送请求。
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
templates = Jinja2Templates(directory="templates")
app = FastAPI()
class TextArea(BaseModel):
content: str
@app.post("/add")
async def post_textarea(data: TextArea):
print(data.dict())
return {**data.dict()}
@app.get("/")
async def serve_home(request: Request):
return templates.TemplateResponse("home.html", {"request": request})
前端 - home.html
- 让我们创建一个具有文本区域和按钮的虚拟应用程序。
- 我们正在使用 Axios 将我们的请求发送到后端。
- 由于它们 运行 在同一个端口上,我们可以将
/add
直接传递给 Axios。
<html>
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<body>
<div id="app">
<textarea name="" id="content" cols="30" rows="10" v-model="content"></textarea>
<button @click="addText" id="add-textarea">click me</button>
</div>
<script>
new Vue({
el: "#app",
data: {
title: '',
content: ''
},
methods: {
addText() {
return axios.post("/add", {
content: this.content
}, {
headers: {
'Content-type': 'application/json',
}
}).then((response) => {
console.log("content: " + this.content);
});
}
}
});
</script>
</body>
</html>
最后,您将得到一个看起来很糟糕的文本区域和一个按钮。但它会帮助你更好地理解事物。
{'content': 'Hello textarea!'}
INFO: 127.0.0.1:51682 - "POST /add HTTP/1.1" 200 OK
你可以做到,在我看来,这是一种非常干净的方式。
我能想到的最好办法是使用 Node.js/npm 将 Vue 应用程序捆绑到 dist/
文件夹(默认情况下)
vue-cli-service build
然后我使用这样的项目文件夹结构
├── dist/ <- Vue-CLI output
└── index.html
├── src/ <- Vue source files
└── app.py
要实现相同的项目设置,您只需使用 vue create
初始化一个 Vue 项目并在同一文件夹中创建您的 Python 项目(使用 IDE 如 Pycharm 例如,请确保您不会用另一个覆盖一个)。
然后你可以使用FastAPI.staticfiles.StaticFiles
来为他们服务
# app.py
app.mount('/', StaticFiles(directory='dist', html=True))
记得将上面的 app.mount()
行放在所有其他路由之后,因为它会覆盖后面的每条路由。
你甚至可以使用vue-cli-service build --watch
,这样Vue代码的每一个变化都会立即反映在HTML文件中,你只需要在浏览器上按F5就可以看到这些变化。
您也可以将 dist
文件夹输出更改为其他内容,使用 vue-cli-service build --dest=<folder name>
并更改上面 app.mount()
行中的 directory
参数。 (根据 Vue-CLI docs)
这是我使用该设置的项目之一:https://github.com/KhanhhNe/sshmanager-v2
我正在 Jobs Portal 上构建一个项目,我需要 Vue 作为前端和 Fastapi 作为后端(添加、删除更新)。我想知道我是否可以将它们连接起来。
I want to know if i can connect these both or not.
快速回答:是的,您可以连接。
但是有很多方法,您可以使用 Jinja 之类的东西呈现模板,或者您可以使用 Vue CLI 之类的东西创建一个完全不同的项目,您可能想使用 Nginx 或 Apache 等东西来连接两者。
让我们用 Jinja 创建一个示例应用程序
结构
├── main.py
└── templates
└── home.html
后端- main.py
- 我们在
/
中为我们的前端提供服务,并在该路径中呈现我们的home.html
。 - 我们正在使用模板文件夹来保存我们的 HTML 并将其传递给 Jinja。
- 此外,我们将从我们的 front-end 向
/add
发送请求。
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
templates = Jinja2Templates(directory="templates")
app = FastAPI()
class TextArea(BaseModel):
content: str
@app.post("/add")
async def post_textarea(data: TextArea):
print(data.dict())
return {**data.dict()}
@app.get("/")
async def serve_home(request: Request):
return templates.TemplateResponse("home.html", {"request": request})
前端 - home.html
- 让我们创建一个具有文本区域和按钮的虚拟应用程序。
- 我们正在使用 Axios 将我们的请求发送到后端。
- 由于它们 运行 在同一个端口上,我们可以将
/add
直接传递给 Axios。
<html>
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<body>
<div id="app">
<textarea name="" id="content" cols="30" rows="10" v-model="content"></textarea>
<button @click="addText" id="add-textarea">click me</button>
</div>
<script>
new Vue({
el: "#app",
data: {
title: '',
content: ''
},
methods: {
addText() {
return axios.post("/add", {
content: this.content
}, {
headers: {
'Content-type': 'application/json',
}
}).then((response) => {
console.log("content: " + this.content);
});
}
}
});
</script>
</body>
</html>
最后,您将得到一个看起来很糟糕的文本区域和一个按钮。但它会帮助你更好地理解事物。
{'content': 'Hello textarea!'}
INFO: 127.0.0.1:51682 - "POST /add HTTP/1.1" 200 OK
你可以做到,在我看来,这是一种非常干净的方式。
我能想到的最好办法是使用 Node.js/npm 将 Vue 应用程序捆绑到 dist/
文件夹(默认情况下)
vue-cli-service build
然后我使用这样的项目文件夹结构
├── dist/ <- Vue-CLI output
└── index.html
├── src/ <- Vue source files
└── app.py
要实现相同的项目设置,您只需使用 vue create
初始化一个 Vue 项目并在同一文件夹中创建您的 Python 项目(使用 IDE 如 Pycharm 例如,请确保您不会用另一个覆盖一个)。
然后你可以使用FastAPI.staticfiles.StaticFiles
来为他们服务
# app.py
app.mount('/', StaticFiles(directory='dist', html=True))
记得将上面的 app.mount()
行放在所有其他路由之后,因为它会覆盖后面的每条路由。
你甚至可以使用vue-cli-service build --watch
,这样Vue代码的每一个变化都会立即反映在HTML文件中,你只需要在浏览器上按F5就可以看到这些变化。
您也可以将 dist
文件夹输出更改为其他内容,使用 vue-cli-service build --dest=<folder name>
并更改上面 app.mount()
行中的 directory
参数。 (根据 Vue-CLI docs)
这是我使用该设置的项目之一:https://github.com/KhanhhNe/sshmanager-v2