【问题标题】:How to connect Vue.js as frontend and Fastapi as backend如何连接 Vue.js 作为前端和 Fastapi 作为后端
【发布时间】:2020-10-25 10:34:38
【问题描述】:

我正在 Jobs Portal 上构建一个项目,我需要 Vue 作为前端,Fastapi 作为后端(添加、删除更新)。我想知道我是否可以将这两个都连接起来。

【问题讨论】:

    标签: vue.js fastapi


    【解决方案1】:

    我想知道我是否可以同时连接这两者。

    快速回答:可以,可以连接。

    但是有很多方法,你可以使用 Jinja 之类的东西渲染模板,或者你可以使用 Vue CLI 之类的东西创建一个完全不同的项目,你可能想使用 Nginx 或 Apache 等东西来连接两者。

    让我们用 Jinja 创建一个示例应用

    结构

    ├── main.py
    └── templates
        └── home.html
    

    后端-main.py

    • 我们在 / 中服务我们的前端,并在该路径中渲染我们的 home.html
    • 我们使用模板文件夹来保存我们的 HTML 并将其传递给 Jinja。
    • 另外,我们将从前端向/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
    

    【讨论】:

    • 如果我使用 file.vue 而不是 file.html 会怎样?
    • Jinja 是一个 HTML 渲染框架,这正是我的意思,如果你想使用组件,你需要独立运行前端和后端,你需要将它们与 Nginx Apache 等合并。
    【解决方案2】:

    你可以做到,IMO 非常干净。 我能想到的最好方法是使用 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 项目(例如,使用像 Pycharm 这样的 IDE,请确保您没有使用其他)。

    那你就可以用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=&lt;folder name&gt; 并更改上面app.mount() 行中的directory 参数。 (根据Vue-CLI docs

    这是我使用该设置的一个项目:https://github.com/KhanhhNe/sshmanager-v2

    【讨论】:

      猜你喜欢
      • 2022-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多