打开浏览器,访问 :5000 这个地址,它会重定向至 :5000/home,但是这里显示的界面仍然是 ./templates/home.html 文件的内容,而非 ./vtemplates/home.html。如果蓝图要访问的模板文件与应用中的重名了,那么 Flask 渲染模板的顺序可能和你所想的不同。在 github 的 issue 中有一些相关的讨论:https://github.com/pallets/flask/issues/2664,基本上是讨论模板的渲染顺序问题。为了防止渲染错误的页面,我们直接将 templates 路径下的重名文件删除,再次访问 :5000/home,出现的内容是 “Hello, this is a home page (it will be built by vue-cli commands).”。
好了,一个基本的 Flask 后端程序就完成了(目前仅仅提供 HTML 文件的渲染)。前端将会由 Vue 构建的项目处理。
Vue 前端创建一个 Vue 项目比较简单,Vue 的官方文档也比较详细,就不过多介绍了。在项目根目录下创建一个名为 frontend 的子项目:
vue create frontend如果没有什么要定制的话,回车使用默认配置即可。完成后会在项目根目录下面看到 frontend 文件夹。进入该文件夹,便是前端项目了。
在 frontend 文件夹中,输入 yarn serve 会打开一个开发用的服务器,根据项目源代码改动情况自动重新加载服务器;输入 yarn build 会在 /frontend 文件夹中构建用于生产环境的 dist 文件夹。前面说过,我们想让 home 蓝图的模板路径为 /vtemplates,因此我们需要对 Vue-cli 做一些配置。
在 /frontend 文件夹中新建一个名为 vue.config.js 的文件,并添加以下内容:
module.exports = { chainWebpack: config => { config.module.rules.delete('eslint'); }, pages: { home: { entry: 'src/home/main.js', template: 'public/index.html', filename: 'home.html', title: 'Home Page', chunks: ['chunk-vendors', 'chunk-common', 'home'] }, user: { entry: 'src/user/main.js', template: 'public/index.html', filename: 'user.html', title: 'User Page', chunks: ['chunk-vendors', 'chunk-common', 'user'] } }, assetsDir: 'vstatic', configureWebpack: { devtool: 'source-map', }, devServer: { index: 'home.html', proxy: { '/api': { target: 'http://127.0.0.1:5000/api/', changeOrigin: true, pathRewrite: { '^/api': '' } }, '/user': { target: 'http://127.0.0.1:8080/user.html/', changeOrigin: false, pathRewrite: { '^/user': '' } } } }, outputDir: '../vtemplates' }在这个文件中,配置了将会输出两个 html 文件:home.html 和 user.html。并且将输出目录放在了根目录下的 vuetempletas 文件夹中,将静态文件路径设为了 vstatic。
我想让 home 作为一个 SPA(single page app 单页应用),user 作为另一个 SPA。你可以按照自己喜欢的方式组织代码。
在 /frontend/src 目录下新建一个 home 文件夹,用于放置 home 应用的代码,代码简略结构图如下:
/ # 项目根目录 |- frontend # 前端子项目 |- ... |- src |- home |- venv # python virtualenv |- templates # 用 Jinja2 语法编码的模板 -- ... -- app.py # 后端应用在 /frontend/src/home 中添加 home.js,现在的代码很简单,只用导入 Vue 依赖和 App.vue 文件就好。如果想要做成一个复杂的单页应用,那么你还需要使用路由,如 vue-router,官网上对单页应用有相应的 可供参考。:
import Vue from 'vue' import App from './App.vue' import VueRouter from 'vue-router' Vue.use(VueRouter) Vue.config.productionTip = false import Index from './pages/Index.vue' const routes = [ { path: 'http://www.likecs.com/', name: 'index', component: Index, alias: ['/home', '/index'], }, ]; const router = new VueRouter({ routes, mode: 'hash' }); new Vue({ router, render: h => h(App), }).$mount('#app')注意这里要调用 Vue.use(VueRouter) 加载 VueRouter 插件,否则不会显示相应的子界面。
使用 yarn serve 启动开发服务器,在浏览器中输入 localhost:8080/home.html 就可以看到如下带有 Vue Logo 和 “Hello, this is Home App” 的界面了。
注意在上面 vue.config.js 配置文件中,我将 devServer 的 index 字段设为了 'home.html',因此直接访问 localhost:8080 和访问 localhost:8080/home.html 的效果是一样的。
前后端结合有时候在开发过程中,我们想要通过类似 localhost:8080/home 的方式而不用在路径末尾加上 .html 后缀的方式访问路由。比如现有的服务器路由就是不带后缀名的,那么我们可以通过修改 devServer 的配置,使得在开发前端界面时保持多页面的路径统一。
我在 webpack dev server 的配置中找了一下,如果前端的路由采用的是 history 模式,也就是传统的 url 模式,那么可以在 devServer 中加入以下内容,重写路径:
devServer: { historyApiFallback: true, historyApiFallback: { rewrites: [ { from: '/^home', to: 'home.html'}, { from: '/^user', to: 'user.html'}, ] }, }