基于Vue与flask的前后端分离开发

8,706 阅读5分钟
原文链接: github.com

公司的项目是以后端为主的传统MVC模式构建的,处于业务发展需要,以后可能需要给别人提供API,而且移动端和小程序也要上线,所以为了以后的便利和代码复用,现在需要采取前后端分离的模式。

连我在内,公司一共四个开发,他们仨都没做过,所以搭架子这种事也就自然落到我头上了。

技术选型

之前是用Python作为后端语言,Flask框架,view层采用 Jinja2 模板引擎。现在整体业务已经成型,所以后端是没法再变的,依然采用Python + Flask,能变的只能是 view 层,将 view 层完全抽离出去,全部由前端负责。

前端最终采用的是 Vue 全家桶,原因无它,对于这种小体量公司,用 Node 作为中间层这种模式,我深信如果踩到坑,他们以后填起来会很痛苦,而且也没法发挥出 Node 做中间层的优点。

架子搭建

基础结构

project
    | -- backend       // backend 文件夹作为后端文件的根目录
    | -- dist          // dist 文件夹里放的是前端打包的最终代码,也就是 npm run build 生成的代码
    | -- frontend      // frontend 自然就是存放前端开发环境的代码了。

我没有把前端打包生成好的代码放到后端的 static 或者 template 文件夹下,主要原因是为了前后端能够分开发布,你肯定不想陪着后端人员一起,大半夜的守在电脑面前部署代码吧。

前端环境

前端使用的是 Vue.js 一整套的东西,具体使用和配置直接看官网就好了。

进入到 frontend 文件夹,然后在命令行工具里,通过 vue-cli 执行:

vue init webpack

然后安装好我们前端开发时需要的包,目录结构就变成了下面的样子

image

不过生产环境的构建配置还需要做点小修改,打开 config 文件夹里的 index.js 文件,并将 build 时候的配置:

build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),

修改为:

build: {
    // Template for index.html
    index: path.resolve(__dirname, '../../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../../dist'),

这样在执行 npm run build 进行生产打包时,文件就能输出到我们想要的位置了。

后端环境

Python 是最新的 V3.6,这个不说了,大家自己去官网下载安装就行了。

打开 cmd,进入到 backend 目录:

image

Python 不像 Node.js,通过 NPM 安装包时,只需要一个参数就能区分全局和当前项目环境,安装在当前项目环境的包永远不会影响其它的项目环境。但是 Python 不行,所以为了各个项目之间的环境独立,我们需要安装 virtualenv,把每个项目都放在一个封闭的虚拟环境中,这样项目彼此间就不会影响了。

安装 virtualenv:

pip install virtualenv

创建虚拟环境:

virtualenv venv

venv 是虚拟环境的名字,所以只要你喜欢,换成什么都可以。

进入虚拟环境:

venv\Scripts\activate

image

退出虚拟环境:

venv\Scripts\deactivate

安装 Flask:

pip install Flask

安装 flask-cors,用来解决开发时的跨域问题:

pip install flask-cors

安装 pylint,用来检查代码:

pip install pylint

安装 yapf,用来格式化代码:

pip install yapf

编辑器我采用的是 vscode,别问我为什么不用 pycharm,我现在开发用的电脑还是大学买的 13寸超级本,性能一般,打开 pycharm 实在是慢。

正如你所想,我们公司没有开发电脑,每天盯着我这13寸的屏,感觉眼睛都要瞎了。。。

image

后端代码

代码我就不一行一行写出来解释了,直接写在代码的注释里:

# run.py

'''
    render_template 是渲染模板用的,这里我们用来返回 index.html
    flask_cors 用来解决跨域的问题
'''
from flask import Flask, render_template
from flask_cors import CORS

# 通过 static_folder 指定静态资源路径,以便 index.html 能正确访问 CSS 等静态资源
# template_folder 指定模板路径,以便 render_template 能正确渲染 index.html
APP = Flask(
    __name__, static_folder="../dist/static", template_folder="../dist")

CORS(APP)


@APP.route("/")
def home():
    '''
        当在浏览器访问网址时,通过 render_template 方法渲染 dist 文件夹中的 index.html。
        页面之间的跳转交给前端路由负责,后端不用再写大量的路由
    '''
    return render_template('index.html')


@APP.route('/test', methods=['GET', 'POST'])
def test():
    ''' 这个API用来测试跨域 '''
    return 'success'


if __name__ == '__main__':
    # 开启 debug模式,这样我们就不用每更改一次文件,就重新启动一次服务
    # 设置 host='0.0.0.0',让操作系统监听所有公网 IP
    # 也就是把自己的电脑作为服务器,可以让别人访问
    APP.run(debug=True, host='0.0.0.0')

启动后端服务:

python run.py

image

开发环境测试

写个 ajax 请求,调用服务端的 /test 接口,然后执行:

npm run dev

image

打开控制台可以看见,我们跨域调用成功了。

生产环境测试

随便写点用来测试的前端代码,然后执行:

npm run build

然后在浏览器中访问:

你的电脑 IP + 端口号

比如 http://192.168.5.18:5000,页面成功展示,静态资源也成功加载。

image

生产环境也没有问题,完美收工!

前端代码我没有细写,因为在写这篇文章的时候我已经写了一些业务代码了,所以就不给大家贴出来了,不过我相信大家的前端代码应该也没什么问题,如有疑问,可以在下面留言。