Как я могу объединить Vue.js с Flask?

Я хочу использовать Vue.js и Flask вместе: Vue.js для динамического front-end и Flask для внешнего. Как я могу это сделать?

Ответ 1

У меня недавно была эта проблема (объединение Vue.js и Flask).

Существует по крайней мере два способа их объединения, в зависимости от того, создаете ли вы 1) простое приложение Vue.js или 2) более сложное приложение Vue.js, которому для объединения Single-File необходимо использовать пакетный модуль, такой как Webpack. Компоненты или пакеты npm.


Простое приложение Vue.js:

Это на самом деле довольно легко и очень мощно само по себе:

  1. Если вы хотите, чтобы функциональность Vue.js("приложение") находилась на отдельной странице, создайте новый файл шаблона .html. В противном случае просто откройте файл шаблона .html вы хотите разместить приложение.
    • Вот куда пойдет ваш код шаблона Vue.js.
  2. Если вы согласны с тем, что ваш код JavaScript Vue.js находится в том же файле, что и ваш 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>
    
    • Обратите внимание, что этот пример включает код JavaScript Vue.js в файл шаблона Flask, поэтому вам не нужно отдельно включать JavaScript Vue.js. Это может быть проще для небольших проектов.
  3. В качестве альтернативы, если вы хотите, чтобы код JavaScript Vue.js находился в своем собственном файле:
    1. Создайте новый файл JavaScript в вашей static папке, назовите его после того приложения, которое вы хотите создать.
      • Вот куда пойдет ваш JavaScript-код Vue.js.
    2. В нижней части файла шаблона .html включите тег сценария для включения Vue.js.
      • <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
        • Обратите внимание, что номер версии изменится, поэтому не просто скопируйте эту строку. Вы можете получить ссылку на самую последнюю версию здесь.
    3. Также в этом файле шаблона, также внизу, есть тег script для загрузки файла JavaScript, который вы только что создали.
      • <script src="%% url_for('static', filename='js/YOUR_APP_NAME.js') %%"></script>
    4. Создайте новый div в файле шаблона .html с id app.
      • <div id="app"></div>
  4. Если вы используете 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-Bootstrap не будет работать, если вы переключите синтаксис Flask, так как Flask-Bootstrap имеет свои собственные шаблоны, которые по-прежнему будут содержать синтаксис "{{"/"}}". Вы можете увидеть здесь, как изменить синтаксис Vue.js, это даже проще, чем изменить синтаксис колбы.
  5. Служите странице как обычно./Отобразить файл шаблона как обычно.
  6. Если вы хотите, используйте JSFiddle Vue.js 2.0 Hello World для более быстрого создания прототипов, а затем скопируйте код в файлы .html и .js.
    • Убедитесь, что скрипка использует самую последнюю версию Vue.js!

Легко!


Более сложное приложение Vue.js с использованием Webpack:

  1. Установите Node (он поставляется с npm, что нам и нужно).
  2. Установите vue-cli:
    • npm install -g @vue/cli
  3. Создайте новый проект Vue.js Webpack:
    • vue create my-project
    • Один из способов сделать это - создать папку server папку client, где папка server содержит код сервера Flask, а папка client содержит код проекта Vue.js.
    • Другой способ заключается в том, чтобы проект Vue.js содержался в папке внутри вашего проекта Flask.
  4. Настройте конфигурацию Webpack таким образом, app.html файл app.html создавался в папке Flask server/templates, а статический JavaScript и CSS, необходимые для app.html, создавался в папке server/static/app/, изолированной от статических ресурсов. используется не-Vue части вашего приложения Flask.
  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 и статические ресурсы.

Потому что мы направляем Webpack на создание статических ресурсов в "статической" папке Flask (/static/app/)...

  1. Относительные URL-адреса для включения этих активов в html файл будут автоматически правильно настроены 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 Blueprints (<blueprint_name>.route), но вам это не нужно.

Ответ 2

При использовании 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")

Обратите внимание, что в static_folder и template_folder не могут быть одинаковыми.