如何将 Vue.js 与 Flask 结合使用?
Posted
技术标签:
【中文标题】如何将 Vue.js 与 Flask 结合使用?【英文标题】:How can I combine Vue.js with Flask? 【发布时间】:2018-02-23 03:28:01 【问题描述】:我想同时使用 Vue.js 和 Flask:Vue.js 用于动态前端,Flask 用于后端。我该怎么做?
【问题讨论】:
【参考方案1】:当使用 vue-cli 或 Webpack 时,可以简化流程。只需创建
vue.config.js
在您的 Vue 项目中,请参阅:Vue config
module.exports =
outputDir: "../dist",
// relative to outputDir
assetsDir: "static"
;
然后配置你的烧瓶应用程序:
app.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 中的static_folder
和template_folder
不能相同。
【讨论】:
你回答中的最后一行在被难倒了很长一段时间后救了我。当您尝试使用相同的静态和模板文件夹时,Flask 不会产生任何有意义的错误,它只是不起作用(对于 static_folder 中的任何内容都是 404)。【参考方案2】:我最近遇到了这个问题(结合 Vue.js 和 Flask)。
至少有两种方法可以组合它们,具体取决于您是在创建 1) 简单的 Vue.js 应用程序还是 2) 需要使用像 Webpack 这样的模块捆绑器来组合的更复杂的 Vue.js 应用程序Single-File Components 或 npm 包。
简单的 Vue.js 应用:
这实际上是相当简单且非常强大的:
-
如果您希望 Vue.js 功能(“应用程序”)位于其自己的页面上,请创建一个新模板
.html
文件。否则,只需打开您希望应用程序所在的任何 .html
模板文件。
这是您的 Vue.js 模板代码所在的位置。
如果您可以将 Vue.js javascript 代码与 HTML 放在同一个文件中,下面是一个简单的“Hello World”示例模板,您可以使用它来了解 Flask 模板中需要包含的内容文件:
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
</head>
<body>
<div id="app">
<p> message </p>
</div>
<script>
new Vue(
el: '#app',
data:
message: 'Hello Vue.js!'
)
</script>
</body>
请注意,此示例将 Vue.js JavaScript 代码包含在 Flask 模板文件中,因此您无需单独包含 Vue.js JavaScript。对于较小的项目,这可能更容易。
或者,如果您希望 Vue.js JavaScript 代码位于其自己的文件中:
-
在您的
static
文件夹中创建一个新的JavaScript 文件,以您要创建的应用程序命名。
这是您的 Vue.js JavaScript 代码所在的位置。
.html
模板文件的底部包含一个脚本标记以包含 Vue.js。
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
请注意,版本号会发生变化,因此不要只复制该行。您可以获取最新版本的链接here。
同样在该模板文件的底部,包括一个脚本标签以加载您刚刚创建的 JavaScript 文件。
<script src="%% url_for('static', filename='js/YOUR_APP_NAME.js') %%"></script>
在.html
模板文件中创建一个新的div
,它的id
为app
。
<div id="app"></div>
如果你使用 Jinja2 来渲染你的模板,你需要添加几行代码告诉 Jinja2 不要使用
语法来渲染变量,因为我们需要 Vue 的那些双花括号符号.js。以下是您需要添加到 app.py
的代码:
class CustomFlask(Flask):
jinja_options = Flask.jinja_options.copy()
jinja_options.update(dict(
variable_start_string='%%', # Default is '', I'm changing this because Vue.js uses '' / ''
variable_end_string='%%',
))
app = CustomFlask(__name__) # This replaces your existing "app = Flask(__name__)"
请注意,如果您切换 Flask 的语法,Flask-Bootstrap 将无法工作,因为 Flask-Bootstrap 有自己的模板,仍然包含“”/“”语法。可以看here怎么改Vue.js的语法,比改Flask的语法还要简单。
照常提供页面。 / 照常渲染模板文件。
如果您愿意,可以使用Vue.js 2.0 Hello World JSFiddle 进行更快的原型设计,然后将代码复制到您的.html
和.js
文件中。
确保小提琴使用的是最新版本的 Vue.js!
简单!
使用 Webpack 的更复杂的 Vue.js 应用:
-
Install Node(它带有 npm,这是我们需要的)。
安装vue-cli:
npm install -g @vue/cli
新建一个 Vue.js Webpack 项目:
vue create my-project
一种方法是创建一个server
文件夹和一个client
文件夹,其中server
文件夹包含Flask 服务器代码,client
文件夹包含Vue.js 项目代码。
另一种方法是将 Vue.js 项目作为文件夹包含在 Flask 项目中。
设置您的 Webpack 配置,以便在 Flask server/templates
文件夹中创建 app.html
文件,并在 server/static/app/
文件夹中创建 app.html
所需的静态 JavaScript 和 CSS,与静态资产隔离由 Flask 应用的非 Vue 部分使用。
如果您想将 Vue.js 项目与 Flask 项目结合起来,请在包含 Vue.js 项目的文件夹中运行 npm run build
,这将生成一个 .html
文件和几个静态文件(JavaScript 和 CSS) .
我对 Webpack 配置所做的确切更改(通过我的 git 提交):
client/build/webpack.dev.conf.js
:
new HtmlWebpackPlugin(
- filename: 'index.html',
- template: 'index.html',
+ filename: 'app.html',
+ template: 'app.html',
在这里(上图)我将 Vue.js 'launch' 文件的名称更改为 app.html,这样它就不会与我的 Flask 应用程序的 'index.html' 冲突。
client/config/index.js
:
module.exports =
build:
env: require('./prod.env'),
- index: path.resolve(__dirname, '../dist/index.html'),
- assetsRoot: path.resolve(__dirname, '../dist'),
- assetsSubDirectory: 'static',
- assetsPublicPath: '/',
+ index: path.resolve(__dirname, '../../server/templates/app.html'),
+ assetsRoot: path.resolve(__dirname, '../../server/static/app'),
+ assetsSubDirectory: '',
+ assetsPublicPath: '/static/app',
这里(上图)我正在设置 app.html 文件和静态资源的创建位置。
因为我们正在指导 Webpack 在 Flask 的“静态”文件夹 (/static/app/
) 中生成静态资源...
-
在
html
文件中包含这些资产的相对 URL 将由 Webpack 自动正确设置。
例如:src=/static/app/js/app.f5b53b475d0a8ec9499e.js
当查询这些 URL 上的文件时,Flask 将自动知道如何提供它们,因为它们位于 static/
文件夹中,Flask 假定该文件夹具有 /static/etc.
URL。
唯一需要 Flask 路由的生成文件是 app.html
文件。
client/build/webpack.prod.conf.js
:
new HtmlWebpackPlugin(
filename: process.env.NODE_ENV === 'testing'
- ? 'index.html'
+ ? 'app.html'
: config.build.index,
- template: 'index.html',
+ template: 'app.html',
这里(上图)我只是重命名了“启动”页面,与webpack.dev.conf.js
中的相同。
routes.py
:
@web_routes.route('/app')
@login_required
def app():
if current_user.datetime_subscription_valid_until < datetime.datetime.utcnow():
return redirect(url_for('web_routes.pay'))
return render_template('app.html')
这里(上图)是我的渲染函数。我正在使用 Flask 的蓝图功能 (<blueprint_name>.route
),但您不必这样做。
【讨论】:
如果你提供链接 github 项目和设置会很好:)。我也偶然发现了这个问题(你回答的第二部分),但问题太多了。 这是个好主意...不幸的是我可以看到这需要我一段时间。我可能会在某个时候解决它。如果您(或其他人)最终这样做,我会将链接添加到答案中。 另外,如果您从头开始,我建议您看看 Nuxt (nuxtjs.org)。 “简单”的方式似乎不适用于外部模块。 @maugch 您尝试使用的外部模块是什么?以上是关于如何将 Vue.js 与 Flask 结合使用?的主要内容,如果未能解决你的问题,请参考以下文章
Heroku 部署混乱:Vue.js 前端与 Flask 后端
由于不允许的预检标头,Vue.js 前端与 Flask 后端 CORS 问题交互