我们通常说三端,pc端,android端和ios端。如果前后端不分离,相当是要做三套系统。如果前后端分离的话,可以共用一个后端,前端各自做自己的,不用管后端。
前后端不分离
在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高。
这种应用模式比较适合纯网页应用,但是当后端对接App时,App可能并不需要后端返回一个HTML网页,而仅仅是数据本身,所以后端原本返回网页的接口不再适用于前端App应用,为了对接App后端还需再开发一套接口。
前后端分离
在前后端分离的应用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制前端的效果。至于前端用户看到什么效果,从后端请求的数据如何加载到前端中,都由前端自己决定,网页有网页的处理方式,App有App的处理方式,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。
在前后端分离的应用模式中 ,前端与后端的耦合度相对较低。
在前后端分离的应用模式中,我们通常将后端开发的每个视图都称为一个接口,或者API,前端通过访问接口来对数据进行增删改查。
OK, 我们来尝试用vue做前端,flask做后端,来做一个前后端分离的系统。
首先用CLI来装vue.
Vue- CLI是vue官方提供的脚手架工具,默认已经帮我们搭建好了一套利用webpack管理vue的项目结构。
我们网上看到的很多文档,都是CLI2的,都会有各种配置文件。我们现在用CLI3,就不需要怎么配置。省心很多。
在Vue- CLI3以后生成的项目结构中已经没有了build文件夹和config文件夹。
首先,我们要配置源:
npm config set registry https://registry.npm.taobao.org
或者:
npm install --registry=https://registry.npm.taobao.org
全局安装:
npm install -g @vue/cli
检查是否安装成功:
vue -V
创建项目:
vue create my-project
项目就创建好了,打开看一下
src文件夹:代码文件夹
|----assets文件夹: 存储项目中自己的一些静态文件(图片/字体等)
|----components文件夹: 存储项目中的自定义组件(小组件,公共组件)
|----views文件夹:存储项目中的自定义组件(大组件,页面级组件,路由级别组件)
|----router文件夹:存储VueRouter相关文件
|----store文件夹:存储Vuex相关文件
|----App.vue:根组件
|----main.js:入口js文件
运行:
npm run serve
浏览器里面输入地址,就可以看到页面了。
CLI3里面还有一个可以用UI界面来控制的。
敲入:
vue ui
就可以通过ui来创建项目,配置插件和打包了,很方便的。
好了,看完前端,来配置后端:
Python 不像 Node.js,通过 NPM 安装包时,只需要一个参数就能区分全局和当前项目环境,安装在当前项目环境的包永远不会影响其它的项目环境。但是 Python 不行,所以为了各个项目之间的环境独立,我们需要安装 virtualenv,把每个项目都放在一个封闭的虚拟环境中,这样项目彼此间就不会影响了。
安装 virtualenv:
pip install virtualenv
创建虚拟环境:
virtualenv venv
venv 是虚拟环境的名字,所以只要你喜欢,换成什么都可以。
进入虚拟环境:
venvScriptsactivate
退出虚拟环境:
venvScriptsdeactivate
安装 Flask:
pip install Flask
安装 flask-cors,用来解决开发时的跨域问题:
pip install flask-cors
安装 pylint,用来检查代码:
pip install pylint
安装 yapf,用来格式化代码:
pip install yapf
先将前端的代码写好,现在对vue还不是太熟,就简单写一个index:
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><link rel="icon" href="<%= BASE_URL %>favicon.ico"><script src="https://unpkg.com/axios/dist/axios.min.js"></script><title><%= htmlWebpackPlugin.options.title %></title></head><body><noscript><strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><!-- built files will be auto injected --><input v-model="message"><button type="button" @click="get_password">submit</button><p>account is: {{ message }}</p><p>password is: {{ password }}</p><script>var v1 = new Vue({el: '#app1',data: {message: 'stest',password: '',},watch : {my(v) {this.password = this.get_password();}},methods: {get_password() {axios.get('/accounts', {headers: {'Access-Control-Allow-Origin': '*',},crossDomain: true,contentType: "application/json",params: {account: this.message,//接口配置参数(相当于url?id=xxxx)},}).then((res) => {console.log(res.data['password']);//处理成功的函数 相当于successthis.password = res.data['password']}).catch(error => console.log(error))}}})</script></body>
</html>
然后在项目里面建一个文件夹,叫backend,建一个app.py
from flask import Flask,render_template,request,jsonifyapp = Flask(__name__)# 通过 static_folder 指定静态资源路径,以便 index.html 能正确访问 CSS 等静态资源
# template_folder 指定模板路径,以便 render_template 能正确渲染 index.html
app = Flask(__name__, static_folder="../dist/static", template_folder="../dist")@app.route('/')
def index():'''当在浏览器访问网址时,通过 render_template 方法渲染 dist 文件夹中的 index.html。页面之间的跳转交给前端路由负责,后端不用再写大量的路由'''return render_template("index.html")@app.route('/accounts', methods=['GET'])
def get_accounts():if request.method == "GET":username = request.args.get("account")password = "aaa" #query_account(username)if password == "":return "no result"else:#return render_template("home.html",message=username,password=password)return jsonify({"password": password})if __name__ == '__main__':app.run()
接着将前端build一下,生成一个dist目录
然后运行:
flask run
浏览器中输入:127.0.0.1:5000
看起来通了。
这个关键点是:
# 通过 static_folder 指定静态资源路径,以便 index.html 能正确访问 CSS 等静态资源
# template_folder 指定模板路径,以便 render_template 能正确渲染 index.html
app = Flask(__name__, static_folder="../dist/static", template_folder="../dist")
美中不足是,vue还不熟练,还有些小问题要处理。
好了,前后端能通了,也能融合到一起了。
更多精彩,请关注微信公众号:python粉丝团