このチュートリアルでは、私は、単一ページのアプリケーションとバックエンドのVueのフラスコを接続する方法を紹介します。
あなたはVueのフレームワークフラスコを使用したい場合は簡単に言えば、問題ありません。しかし、ここでは、そこに文法のための二重の中括弧の使用をレンダリングするよう実際に明白な問題は、フラスコのテンプレートエンジンJijaとVueのであると競合神社は、Vueのをテンプレートは、良い解決策です こちらの壁紙。
私は異なることにしたいです。フラスコ単一ページのアプリケーションとバックエンドを行う方法、Vue.jsは、フロントエンド(単一ページのコンポーネントと、HTML5履歴パターン「VUE-ルータ」と他の良い特性)をどう作りますか?簡単に言えば、このアプリケーションは次のようになります。
- フラスコは、「index.htmlの」Vue.jsアプリが含まれているを駆動するために使用され、
- 私はWebPACKのフロントエンド開発プロセスの特性を使用し、それはすべてのクールなを提供しています
- フラスコ私は、SPAのAPIからのポートへのアクセス権を持っています
- 私は、フロントエンドを開発したとき、私はNode.jsのAPIアクセスポートを実行することができました
右興味深いサウンド、?ここに私達は行きます。
以下は、すべてのコードへのリンクがあり
ます。https://github.com/oleg-agapov/flask-vue-s ...
クライアント
基本Vue.jsファイル構造を生成するために、私が使用する VUE-CLIを。あなたはそれをインストールしない場合、次のコマンドを実行します。
$ NPMは、-g VUE-CLIをインストール
クライアントとバックエンドのコードでは、前部を初期化するには、次のコマンドを実行し、別のフォルダに分割されます:
$ MKDIR flaskvue
$ CD flaskvue
$ VUEのinit WebPACKのフロン直感的
以下は、インストール時に私の設定です:
- Vueのビルド---実行時のみ
- VUE-ルータをインストールしますか? - - はい
- あなたのコードをlintのESLintを使用しますか? - - はい
- ESLintプリセットを選択---標準
- カルマ+モカとセットアップユニットテスト?---なし
- ナイトウォッチでセットアップE2Eテスト?---なし
次へ:
Cdが$フロントエンド インストールNPM $ #は、インストールの完了後、次のコマンドを実行して $のNPMの実行DEV
ここでは、Vue.jsにそれをインストールする必要があります!のは、いくつかのページを追加してみましょう。
で frontend/src/components
[追加]フォルダ Home.vue
と About.vue
二つのファイル。そして、対応するファイルに次の行を追加します。
// コンテンツHome.vueファイル
<テンプレート>
の<div>
<p型>ホーム</ p型>
</ div>
</テンプレート>
と
// コンテンツAbout.vueファイル
<テンプレート>
の<div>
<p型> </ p型について>
</ div>
</テンプレート>
私たちは、現在の場所(アドレスバー)を識別し、それらを正しく使用します。今、私たちは変更する必要が frontend/src/router/index.js
私たちの新しいコンポーネントを提示するファイルを:
インポートヴューから ' VUE ' インポートルータから ' VUEルータ' のconst routerOptions = [ {:パス' / '成分、:' ホーム' }、 {パス:' /約'、成分:' について' } ] CONSTルート = routerOptions.map(ルート=> { リターン{ ...経路、 成分:() => インポート( `@ /コンポーネント/$ {} route.component .vue`) } }) Vue.use(ルータ) のエクスポートデフォルト新しいルータ({ 路線、 モード:' 歴史' })
あなたは、入力しようとする localhost:8080
と localhost:8080/about
、ページが表示されるはずです。
静的な資産を含むパッケージを作成するには、プロジェクトをビルドする準備がほぼ整いました。それまでは、私たちが彼らのために出力ディレクトリを再定義してみましょう。フロントエンドで frontend/config/index.js
のインデックス。セットの下で発見
インデックス: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 中激活虚环境请参考此文档 docs.
在虚环境中安装 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 Hello world 代码略有不同。主要的不同之处在于,我们指定了静态和模板文件夹来用前端包指向 /dist
文件夹,在根文件夹中运行 Flask 服务:
(venv) FLASK_APP=run.py FLASK_DEBUG=1 flask run
这将在 localhost:5000
上启动一个 web 服务器。FLASK_APP
指向服务器启动文件,FLASK_DEBUG=1
将在调试模式下运行。如果一切都是正确的,您将看到熟悉的主页,您在 Vue 上所做的。
与此同时,如果你试图添加一个 /about
页面。 Flask 将抛出一个页面未找到的错误。 确实如此,因为我们在 vue-router
中使用了 HTML5 历史模式,我们需要去 配置我们的服务器 让所有路由跳转到 index.html
. 这个在 Flask 中很容易做到 。将现有的路由修改为如下内容:
@app.route('/', defaults={'path': ''}) @app.route('/<path:path>') 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
<template>
<div>
<p>404 - Not Found</p>
</div>
</template>
现在通过运行 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('/<path:path>') def catch_all(path): return render_template("index.html")
首先,我从 'Flask' 库导入了 'random' 库和 'jsonify' 函数。然后我添加了新的路由 ' /api/random ' 来返回 JSON,如下所示:
{ "randomNumber": 36 }
您可以通过导航到 localhost:5000/api/random
来测试此路由。
此时,服务器端工作已经完成。是时候在客户端展示了。我会改 Home.vue
组成来显示我的随机数:
<template> <div> <p>Home page</p> <p>Random number from backend: {{ randomNumber }}</p> <button @click="getRandom">New random number</button> </div> </template> <script> export default { data () { return { randomNumber: 0 } }, methods: { getRandomInt (min, max) { min = Math.ceil(min) max = Math.floor(max) return Math.floor(Math.random() * (max - min + 1)) + min }, getRandom () { this.randomNumber = this.getRandomInt(1, 100) } }, created () { this.getRandom() } } </script>
在这个阶段,我只是在客户端模拟随机数生成过程。所以,这个组件是这样工作的:
- 初始化变量
randomNumber
等于0
- 在
methods
部分 ,我们又getRandomInt(min, max)
方法, 它将返回一个指定范围内的数字,getRandom
函数,将调度之前的函数,并将其值赋给randomNumber
- 创建组件方法后,将调用
getRandom
来初始化randomNumber
- 触发按钮事件后,我们将调用
getRandom
获取新数字
在前端,现在在首页你应该看到我们的随机数产生。让我们把它连接到后端。
为此,我们将使用 ' axios' 库,它允许我们发出 HTTP 请求并返回带有 JSON 响应的 JavaScriptPromise
。让我们安装它:
(venv) cd frontend
(venv) npm install --save axios
再次打开 Home.vue
文件并 在 <script>
区域添加一些更改:
import axios from 'axios' methods: { getRandom () { // this.randomNumber = this.getRandomInt(1, 100) this.randomNumber = this.getRandomFromBackend() }, getRandomFromBackend () { const path = `http://localhost:5000/api/random` axios.get(path) .then(response => { this.randomNumber = response.data.randomNumber }) .catch(error => { console.log(error) }) } }
在最开始我们导入 axios 库。然后有一个新方法 getrandomfrombackend
,它将使用 AXIOS 异步访问 API 并检索结果。最后,方法 getRandom
现在应该使用 getRandomFromBackend
函数来获取随机值。
保存文件,转到浏览器中,再次运行开发服务器,刷新 localhost:8080
然后… 您应该在控制台中看到一个错误,并且没有随机值。但别担心,一切都正常。我们得到 [cors](http s://developer.mozilla.org/en-us/docs/web/http/cors)错误,这意味着我们的 flask 服务器 API 默认关闭到其他 Web 服务器(在我们的情况下,它是运行 vue.js 应用程序的 node.js 服务器)。如果您使用 npm run build
创建一个 bundle 并打开 localhost:5000
(就是 flask 服务器),您将看到正在工作的应用程序。但是,每次对客户端应用程序进行一些更改时,创建一个包并不十分方便。
让我们使用 Flask 的 CORS 插件,这将允许我们为 API 访问创建规则。 插件名为 [flask-cors](http://flask-cors.readthedocs.io/en/latest/),让我们安装它:
(venv) pip install -U flask-cors
您可以阅读插件的文档,文档中更好地说明了再服务器上启用 CORS 的方法。 我将使用特定于资源的方法并将 {“origin”“:”*“}
应用于所有 / api / *
路由(所以每个人都可以使用我的 / api
端点)。在 run.py
中:
from flask_cors import CORS app = Flask(__name__, static_folder = "./dist/static", template_folder = "./dist") cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
通过以上更改,您可以直接从前端开发服务器调用 Flask API。
更新:
实际上,如果你通过 Flask 提供静态文件,则不需要更新 CORS 扩展。 感谢 [Carson Gee](https://github.com/carsongee)这个技巧。
解决思路如下。 如果应用程序处于调试模式,它将只代理我们的前端服务器。 否则(在生产模式)提供静态文件。 以下是实现的代码:
import requests @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def catch_all(path): if app.debug: return requests.get('http://localhost:8080/{}'.format(path)).text return render_template("index.html")
实现方式简单而优雅,像魔术一样✨!
现在,您拥有一个使用自己喜欢的技术构建的全栈应用程序啦。
后记
最后,我想就如何改进此解决方案说几句话。
首先,只有在您想要让 API 可供外部服务器访问时才使用 CORS 扩展。 否则只需使用代理前端开发服务器的技巧。
另一项改进是避免在前端硬编码 API 路由。 也许您需要创建一个包含 API 路由名称的词汇集。 因此,当您更改 API 路由时,您只需刷新这个词汇集即可。 前端关于路由名称的代码不需要更改。
通常在开发过程中,您将至少需要两个终端窗口:一个用于 Flask ,另一个用于 Vue.js 。 在生产环境中,你将不需要为 Vue 运行单独的 Node.js 服务器。
获取源码及相关视频教程加群887934385 免费领取