zoukankan      html  css  js  c++  java
  • Flask 和 Vue.js 开发及整合部署实例

    本文主要参考 Flask和Vue.js构建全栈单页面web应用【通过Flask开发RESTful API】的前部分,英文原文在这里 Developing a Single Page App with Flask and Vue.js

    开发过程中我们可以保持 Flask 和  Vue.js 为单独的两个项目,并启动各自的服务,比如 Flask 是 http://localhost:5000, Vue.js 项目通过 npm run serve 启动在 http://localhost:8080,借助于 node js 的功能,修改 Vue.js 项目的内容能够自动刷新网页。要是开发中把静态文件全放在  Flask 项目中,那么任何对静态文件的修改都必须重启 Flask  服务。虽然 Debug 模式启动的 Flask 在看到它的目录中有任何修改时也能自动重启,但对静态文件的修改重启 Flask 没这个必要性。 

    但部署时需进一步整合,最终只需要启动 Flask  服务,而无须两个,方便部署。如果是以 Docker 容器的方式发布,使用 docker-compose 来编排两个容器来发布也还算不错。更专业的部署方式应该是 Vue.js 的静态内容放到专门的 Web 服务器,如  Apache/Nginx 中,Flask 也通过 wsgi 与 Web 服务器集成起来。

    介于原文中所用的 Vue CLI 稍稍显老,所以实践中也有些区别,先注明本文写作时所依赖的各主要组件版本

    • Vue v2.6.11
    • Vue CLI v4.6.6
    • Node v14.4.0
    • npm v6.14.4
    • Flask v1.1.2
    • Python v3.7

    创建 Flask 项目

    创建项目目录

    $ mkdir flask-vue-app
    $ cd flask-vue-app

    接下来创建 Python 虚拟环境

    $ python3.7 -m venv .venv
    $ source .venv/bin/activate

    安装 Flask 和 Flask-CORS 扩展,前面说过,由于开发中启动了两个服务,需要跨域访问服务,所以要用到 Flask-CORS

    (.venv) $ pip install flask-cors

    Flask 本身会被自动安装,当前日期为 2020-06-30, 所安装的 flask-cors 版本为 3.0.8, Fask 为 1.1.2。也可以锁定版本来安装扩展,如  pip install flask-cors==3.0.8。现在查看下所有的第三方依赖

    $ pip freeze
    click==7.1.2
    Flask==1.1.2
    Flask-Cors==3.0.8
    itsdangerous==1.1.0
    Jinja2==2.11.2
    MarkupSafe==1.1.1
    six==1.15.0
    Werkzeug==1.0.1

    有需要的话,保存为 requirements.txt 放到版本服务器上

    现在在 flask-vue-app 下创建一个  backend 目录,并在其中创建文件 app.py, 内容为

    简单说明一下上面的代码

    1. CORS(app, resources={r'/*': {'origins': '*'}}) 允许来自于 Vue 的跨域访问请求
    2. 定义以 /api/* 开头的 Flask 的路由,由 Flask 来处理
    3. / 请求直接发送一个静态文件 /index.html,由于不会用到 Flask 的模板系统,所以也就无需调用  render_template() 方法去渲染。
    4. 后面会将到在 backend 目录中会建立一个到 Vue.js 项目打包后的 dist 目录的符号链接 static, 所以其中有 index.html 等
    5. @app.rout('/<path:fallback>') 里是个关键,凡是 Flask 未定义的路由都会落到这里来。如果访问的是 static(dis) 中的 css, js, img 或 favicon.ico 文件,直接送出内容,其他的请求转到 Vue 的入口 index.html, 最后将由 Vue 中定义的路由来处理
    6. 如果 Vue 的 Router 工作在 hash 模式的话,fallback 方法可以不要,因为 /#/home 到 /#/about 的切换本身不产生 HTTP 请求,Flask 只需要 / 一个路由进入 Vue 入口页面

    运行 Flask

    (.venv) $ python backend/app.py

    Flask 会在 localhost:5000 中启动服务,用 curl 命令验证

    $ curl http://localhost:5000/api/ping
    "pong!"

    创建 Vue 项目

    开始转到 Vue 项目来,将使用 Vue CLI 工具来生成它,首先是安装  Vue CLI

    $ npm install -g @vue/cli

    当前日期 2020-06-30, 安装后用 vue --version 看到的版本是 @vue/cli 4.4.6。安装时欲锁定版本用命令 npm install -g @vue/cli@4.4.6

    正式创建项目 frontend,在 flask-vue-app 目录下运行

    $ vue create frontend                  # 选择 Manually select features, 接下回答几个问题

    启动 Vue 服务

    $ cd frontend
    $ npm run serve

    打开浏览器访问 http://localhost:8080 会有一个  "Wellcome to Your Vue.js App" 的界面。后面对 frontend 项目的修改会自动刷新网页。

    下面是如何在 Vue.js(8080) 中调用到 Flask(5000) 的 /api/ping 服务,当前在 frontend 目录中

    创建 src/components/Ping.vue 文件,内容为

    编辑 src/router/index.js 文件,高亮行为新加的内容

    对 src/App.vue 的 <template> 中的导航部分删除,内容变为

    浏览器中访问 http://localhost:8080/ping, "Hello!" 显示的还是 src/components/Ping.vue 中 data 的内容

    现在开始将  Ping.vue 与 Flask 的 /api/ping API 进行连接,Vue 中要用 Ajax 来访问,先要安装 axios,命令如下

    $ npm install axios --save

     

    目前安装的是 axios@0.19.2, 安装后可在 package.json 里看到 dependencies 中的 "axios": "^0.19.2"

    编辑 src/components/Ping.vue 文件,修改为

    高亮行为新加的代码, 保存后 http://localhost:8080/ping 窗口中的内容自动刷新为

    pong! 消息是来自于 Flask 的 /api/ping API 的响应。由于我们前面是以 Debug 模式启动的 Flask backend 应用, 所以在控制台也能够看到一个对 /api/ping 的请求

    127.0.0.1 - - [01/Jul/2020 02:53:06] "GET /api/ping HTTP/1.1" 200 -

    访问 http://localhost:8080/ping_xyz 指向了同一个 Vue 组件,所以效果上与 http://localhost:8080/ping 是一样的。

    Flask 与 Vue.js  整合

    开发的时候启动两个服务很方面,但我们希望在部署后只启动一个 Flask  服务,那么可以这样做

    首先用 npm 对 fronend 中的静态内容打包

    $ npm run build

    将会在 frontend 下生成 dist 目录,其下内容为

    css      favicon.ico   img  index.html   js

    绿色为目录

    这时修只要在 backend 中创建一个符号链接

    $ ln -s ../front/dist static

    创建后在 backend 目录中的内容为

    -rw-r--r-- 1  yanbin root 690 Jul 1 01:01 app.py
    lrwxr-xr-x 1 yanbin root 16 Jun 30 22:33 static -> ../frontend/dist

    因为 Flask 是以 Debug 模式启动的,对 Flask 项目 backend 的改动也可能会触发  Flask 的重新启动,需要的话手动重启  Flask (CTRL+C 退出再重启)

    $ python backend/app.py

    现在  Vue.js 那个服务可以停止了,不管是 Flask 还是 Vue.js  的路由都能够通过  http://localhost:5000 来访问了

    http://localhost:5000/ping

    http://localhost:5000/ping_xyz

    Flask + Vue 对 http://localhost:5000/ping 和  http://localhost:5000/ping_xyz 的处理过程是

    1. 对 localhost:5000 的请求发往 Flask, Flask 的  @app.route('/<path:fallback>') 进行处理
    2. 不是 css/js/img 和  favicon.iso 的请求,交由 Vue.js 的入口 index.html 处理
    3. Vue.js 在自己的路由表中找到了 /ping 和 /ping_xyz, 进它们进行渲染
    4. 如随意一个 http://localhost:5000/abc,也会转给 Vue.js 的入口 index.html,但 Vue.js 未定 /abc 路由,页面得不到渲染,一面空白

    最后,Flask 与 Vue.js 这样整合后,Vue.js 路由中访问 Flask API 要与 Flask 实际启动的 IP 端口保持一致,因为只有一个服务也就不存在跨域访问的问题,允许跨域相关的 Python 代码也就可以移除掉了。

    本文演示的是一个 Vue.js 多页面程序,如果是单页面程序(用 /#/abc) 导引的,在 Flask 中处理起来还稍微简单些,只要 "/" 请求交给 Vue.js 的入口 index.html, 其他全当是静态文件,Flask 的 API 还是最好约定为 /api/* 的形式。

    VueRouter 的 history 和 hash 模式

    如果 VueRouter  使用 hash 模式,在服务端可以更简单的些,前面说过在 app.py 中的 fallback() 方法可以不需要了。Vue 默认的模式是 hash, 只是用 vue 命令生成的项目设置成了 history 模式,重新启用 hash 模式的方法是修改 src/router/index.js 文件中,把 mode 值改为 hash 或去掉 mode 行

    这时候打开 http://localhost:8080 会自动跳转到 http://localhost:8080/#/, 其他的路由也加上了 #, 如 /#/ping 

    浏览时看到原来的 localhost:8080/ping 变成了 localhost:8080/#/ping, 使用 hash 的好处是每次 Vue 的路由跳转其时是一个锚点链接(anchor),它相当于当前页的位置跳转,不会重新刷新整个页面,且本身不会产生与服务端的 HTTP 请求,所以可减少许多的因 Vue  跳转而产生的交互,虽然前也简单的跳转回 Vue 的入口文件 index.html,但怎么着也是省了不少来回。

    接下来将在 Vue.js 中试验 Bootstrap 和 BootstrapVue 的集成。

    本实例代码已推送到了 github, 仓库地址为 https://github.com/yabqiu/flask-vue-app.git,姓没变,欢迎检阅

    相关链接:

      1. Flask和Vue.js构建全栈单页面web应用【通过Flask开发RESTful API】
      2. Developing a Single Page App with Flask and Vue.js
      3. Vue SPA and Flask together
      4. Best practices to deploy a Flask and Vue app?
  • 相关阅读:
    软件测试模型
    功能测试用例是怎么写
    Web测试需要注意的点
    WEB测试方法总结-笔记
    安全性测试的测试点
    删除功能测试的测试点
    压力测试的测试点
    异常测试的测试点
    解决Plugin org.apache.maven.plugins:maven-archetype-plugin:RELEASE or one of its dependencies...
    中国联通:本公司将继续在纽约证交所上市交易
  • 原文地址:https://www.cnblogs.com/caicaizi/p/14326148.html
Copyright © 2011-2022 走看看