使用 flask 和 vue.js 来构建全栈单页应用 | python优质外文翻译 | python 技术论坛-金年会app官方网

在这个教程中,我将向你展示如何将 vue 的单页面应用和flask后端连接起来。

简单的来说,如果想在 flask 中使用 vue 框架是没有什么问题的。 但在实际中存在一个明显的问题就是 flask 的模版引擎 jija 和 vue 一样使用双花括号来渲染, 对于 jinja 模板和 vue 的语法冲突问题,这里有一个很好的金年会app官方网的解决方案  。

我想做个不一样的。 做一个用 vue.js 做前端(用单页组件,html5历史模式的「vue-router」,以及其他好的特性),用 flask 做后端的单页应用怎么样? 简单地说,这个应用应该是这样的:

  • flask用来驱动一个包含 vue.js app 的「index.html」,
  • 前端开发过程中我用到 webpack 和它提供的所有酷的特性
  • flask 有我能从 spa 访问到的 api 端口
  • 在我开发前端时,我能运行 node.js 来访问 api 端口

听起来很有意思吧?我们开始吧。

以下是所有代码的链接

客户端

为了生成基本的vue.js文件结构,我将使用vue-cli。 如果你没有安装它,请运行下边的命令:

$ npm install -g vue-cli

客户端和后端代码将会被拆分到不同的文件夹中, 请运行下边命令初始化前端部分:

$ mkdir flaskvue
$ cd flaskvue
$ vue init webpack frontend

下边是安装过程中我的设置:

  • vue build --- runtime only
  • install vue-router? --- yes
  • use eslint to lint your code? --- yes
  • pick an eslint preset --- standard
  • setup unit tests with karma mocha? --- no
  • setup e2e tests with nightwatch? --- no

下一步:

$ cd frontend
$ npm install
# 安装完成后运行下边命令
$ npm run dev

到这里,你应该安装好vue.js了吧!那就让我们添加一些页面。

 在frontend/src/components 文件夹中添加home.vue 和 about.vue两个文件。 并添加如下内容到对应的文件中:

// home.vue文件的内容

// about.vue文件的内容

我们将使用它们正确地识别我们当前的位置(根据地址栏)。现在,我们需要更改frontend/src/router/index.js 文件来呈现我们的新组件:

import vue from 'vue'
import router from 'vue-router'
const routeroptions = [
  { path: '/', component: 'home' },
  { path: '/about', component: 'about' }
]
const routes = routeroptions.map(route => {
  return {
    ...route,
    component: () => import(`@/components/${route.component}.vue`)
  }
})
vue.use(router)
export default new router({
  routes,
  mode: 'history'
})

如果您尝试输入localhost:8080localhost:8080/about,您应该会看到相应的页面。

为了创建一个包含静态资产的包,我们几乎已经准备好构建一个项目了。在此之前,让我们为它们重新定义输出目录。在前端 frontend/config/index.js 索引。找到下一个设置

index: path.resolve(__dirname, '../dist/index.html'),
assetsroot: path.resolve(__dirname, '../dist'),

然后把它们变成下面这样

index: path.resolve(__dirname, '../../dist/index.html'),
assetsroot: path.resolve(__dirname, '../../dist'),

因此,带有html/css/js包的 /dist文件夹将与/frontend具有相同的级别。现在您可以运行 $ npm run build 来创建一个包。

back-end

我将使用python 3.6来进行flask 应用程序开发. 在根目录 /flaskvue下创建一个子目录来放后端代码, 并在子目录中初始化一个虚环境: 

$ mkdir backend
$ cd backend
$ virtualenv -p python3 venv

执行下面的命令来激活虚环境 (macos操作系统):

$ source venv/bin/activate

在windows中激活虚环境请参考此文档 .

在虚环境中安装flask:

(venv) pip install flask

现在我们开始开发flask应用程序. 在根目录下创建run.py 文件:

(venv) cd ..
(venv) touch run.py

将下面代码添加到这个文件中:

from flask import flask, render_template
app = flask(__name__,
            static_folder = "./dist/static",
            template_folder = "./dist")
@app.route('/')
def index():
    return render_template("index.html")

这段代码与flask starter 代码略有不同。主要的不同之处在于,我们指定了静态和模板文件夹来用前端包指向 /dist 文件夹,在根文件夹中运行 flask 服务:

(venv) flask_app=run.py flask_debug=1 flask run

这将在 localhost:5000 上启动一个web服务器。flask_app 指向服务器启动文件,flask_debug=1 将在调试模式下运行。如果一切都是正确的,您将看到熟悉的金年会app官方网主页,您在vue上所做的。

与此同时,如果你试图添加一个 /about 页面。 flask 将抛出一个页面未找到的错误。 确实如此,因为我们在 vue-router 中使用了 html5 历史模式,我们需要去  让所有路由跳转到 index.html. 这个在 flask 中 。将现有的路由修改为如下内容:

@app.route('/', defaults={'path': ''})
@app.route('/')
def catch_all(path):
    return render_template("index.html")

新的 url 链接 localhost:5000/about 将会跳转到 index.html ,并且 vue-router 将会自己处理其余的事情。

添加 404 页面

因为我们定义了一个将所有请求跳转到 index.html 的路由,因此 flask 将无法捕获到 404 错误(以及不存在的页面),将一些找不到页面的请求也跳转到 index.html。所以我们需要在 vue.js 的路由文件中设置一条路由规则去处理这种情况。

在 frontend/src/router/index.js 中添加一行:

const routeroptions = [
  { path: '/', component: 'home' },
  { path: '/about', component: 'about' },
  { path: '*', component: 'notfound' }
]

这里的 '*' 是 vue-router 中的通配符,用以代表任何除了我们已经定义好的路由之外的其他情况。 接下来我们在 /components 文件夹中创建一个 notfound.vue 文件,并写几行简单的代码:

// notfound.vue

现在通过运行 npm run dev 来重新运行前端服务器,并尝试一些不存在的 url 链接,例如 localhost:8080/gljhewrgoh 。你就可以看到“not found”的消息提示了.

添加api端点

我的 'vue.js/flask'的最后一个例子。 'vue.js/flask'教程将在服务器端创建api并在客户端发送。我将创建一个简单的端点,它将返回一个从1到100的随机数。

打开 run.py 并添加:

from flask import flask, render_template, jsonify
from random import *
app = flask(__name__,
            static_folder = "./dist/static",
            template_folder = "./dist")
@app.route('/api/random')
def random_number():
    response = {
        'randomnumber': randint(1, 100)
    }
    return jsonify(response)
@app.route('/', defaults={'path': ''})
@app.route('/')
def catch_all(path):
    return render_template("index.html")

首先,我从'flask'库导入了'random'库和'jsonify'函数。然后我添加了新的路由' /api/random '来返回json,如下所示:

{
  "randomnumber": 36
}

您可以通过导航到localhost:5000/api/random来测试此路由。

此时,服务器端工作已经完成。是时候在客户端展示了。我会改home.vue组成来显示我的随机数:


在这个阶段,我只是在客户端模拟随机数生成过程。所以,这个组件是这样工作的:

  • 初始化变量 randomnumber等于 0
  • 在 methods部分 ,我们又 getrandomint(min, max) 方法, 它将返回一个指定范围内的数字, getrandom 函数,将调度之前的函数,并将其值赋给 randomnumber
  • 创建组件方法后,将调用 getrandom 来初始化 randomnumber
  • 触发按钮事件后,我们将调用 getrandom 获取新数字

在前端,现在在金年会app官方网首页你应该看到我们的随机数产生。让我们把它连接到后端。
为此,我们将使用' '库,它允许我们发出http请求并返回带有json响应的javascriptpromise。让我们安装它:

(venv) cd frontend
(venv) npm install --save axios

再次打开 home.vue 文件并 在 

网站地图