web-dev-qa-db-ja.com

Vue.jsをFlaskと組み合わせるにはどうすればよいですか?

Vue.jsとFlaskを一緒に使用したい:動的なフロントエンドにはVue.js、バックエンドにはFlask。それを行う?

17
Nathan Wailes

最近この問題が発生しました(Vue.jsとFlaskの組み合わせ)。

作成するのが1)単純なVue.jsアプリであるか、2)Webpackなどのモジュールバンドラーを使用して組み合わせる必要がある、より複雑なVue.jsアプリであるかに応じて、少なくとも2つの方法があります 単一ファイルコンポーネント またはnpmパッケージ。


シンプルなVue.jsアプリ:

これは実際にはかなり簡単で、それ自体で非常に強力です。

  1. Vue.js機能(「アプリ」)を独自のページに配置する場合は、新しいテンプレート_.html_ファイルを作成します。それ以外の場合は、アプリを入れたい_.html_テンプレートファイルを開きます。
    • これは、Vue.jsテンプレートコードが配置される場所です。
  2. Vue.js JavaScriptコードをHTMLと同じファイルに含めても問題がない場合、以下は、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を個別に含める必要がないことに注意してください。これは、小規模なプロジェクトの場合に簡単です。 。
  3. または、Vue.js JavaScriptコードを独自のファイルに含める場合:
    1. staticフォルダーに新しいJavaScriptファイルを作成し、作成するこのアプリの名前を付けます。
      • ここにVue.js JavaScriptコードが入ります。
    2. _.html_テンプレートファイルの下部に、Vue.jsを含めるスクリプトタグを含めます。
      • _<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>_
        • そのバージョン番号は変わるので、その行をコピーしないでください。最新バージョンのリンク here を取得できます。
    3. また、そのテンプレートファイルの下部にも、作成したJavaScriptファイルをロードするためのスクリプトタグを含めます。
      • <script src="%% url_for('static', filename='js/YOUR_APP_NAME.js') %%"></script>
    4. _.html_テンプレートファイルにdivid。の新しいappを作成します
      • _<div id="app"></div>_
  4. テンプレートのレンダリングにJinja2を使用している場合、変数をレンダリングするために_{{ }}_構文を使用しないようにJinja2に指示するために数行のコードを追加する必要があります。 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-Bootstrapには独自のテンプレートがあり、 "{{"/"}}"構文がまだ含まれているため、Flaskの構文を切り替えると、Flask-Bootstrapは機能しません。 here Vue.jsの構文を変更する方法を確認できます。Flaskの構文を変更するよりも簡単です。
  5. 通常どおりページを提供します。 /テンプレートファイルを通常どおりレンダリングします。
  6. 必要に応じて、 Vue.js 2.0 Hello World JSFiddle を使用してプロトタイプをすばやく作成し、コードを_.html_および_.js_ファイルにコピーします。
    • バイオリンがVue.jsの最新バージョンを使用していることを確認してください!

かんたん!


Webpackを使用したより複雑なVue.jsアプリ:

  1. Install Node (npmが付属していますが、これが必要です)。
  2. インストール vue-cli
    • _npm install -g @vue/cli_
  3. 新しいVue.js Webpackプロジェクトを作成します:
    • _vue create my-project_
    • これを行う1つの方法は、serverフォルダーとclientフォルダーを作成することです。ここで、serverフォルダーにはFlaskサーバーコード、 clientフォルダーにはVue.jsプロジェクトコードが含まれています。
    • もう1つの方法は、Vue.jsプロジェクトをFlaskプロジェクト内のフォルダーとして含めることです。
  4. _app.html_ファイルがFlask _server/templates_フォルダーに作成され、_app.html_で必要な静的JavaScriptおよびCSSが作成されるように、Webpack構成をセットアップします。 _server/static/app/_フォルダー内、Vue以外の部分で使用される静的アセットから分離Flask app。
  5. Vue.jsプロジェクトをFlaskプロジェクトと組み合わせる場合は、npm run build_を生成するVue.jsプロジェクトを含むフォルダー内から_.html_を実行しますファイルといくつかの静的ファイル(JavaScriptとCSS)。

私のWebpack構成に行った正確な変更(私のgit commitを介して):

_client/build/webpack.dev.conf.js_:

_new HtmlWebpackPlugin({
-   filename: 'index.html',
-   template: 'index.html',
+   filename: 'app.html',
+   template: 'app.html',
_

ここ(上)で、Vue.jsの「起動」ファイルの名前を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ファイルと静的アセットを作成する場所を設定しています。

なぜなら、Flaskの「静的」フォルダー(_/static/app/_)内に静的アセットを生成するようにWebpackに指示しているからです...

  1. htmlファイルにこれらのアセットを含める相対URLは、Webpackによって自動的に正しく設定されます。
    • 例:_src=/static/app/js/app.f5b53b475d0a8ec9499e.js_
  2. これらの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_)を使用していますが、使用する必要はありません。

29
Nathan Wailes

Vue-cliまたはWebpackを使用すると、プロセスを簡略化できます。単に作成する

vue.config.js Vueプロジェクト内、参照: Vue config

module.exports = {
    outputDir: "../dist",

    // relative to outputDir
    assetsDir: "static" 
};

次に、flask app:

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を同じにすることはできません。

2
Sycjam