Heim > php教程 > PHP开发 > Integrieren Sie Rails, Webpack, Vuejs

Integrieren Sie Rails, Webpack, Vuejs

高洛峰
Freigeben: 2016-11-08 14:33:41
Original
1435 Leute haben es durchsucht

Vorwort

Wenn Sie jemals meinen Artikel über die ersten Schritte mit Vue Webpack gelesen haben, habe ich darin erwähnt, dass es einfach mit herkömmlichen MVC-Frameworks (Rails, ASP.NET MVC) usw. kombinierbar ist. Dieser Artikel dient hauptsächlich dazu, vorzustellen, wie es gemacht wird und warum ich das sage.

Lass es mich zuerst zugeben! Ich muss nicht immer die SPA-Architektur verwenden, aber für viele kleine Projekte, oder besser gesagt Projekte, bei denen das UI/UX-Design selbst sehr einfach ist, ist es Zeitverschwendung. Daher richtet sich der Ansatz dieses Artikels an diejenigen, deren Projekt nicht darin besteht, SPA mit API-Architektur zu verwenden, die jedoch der Meinung sind, dass das vorhandene MVC-Framework für ihre Entwicklungsanforderungen ausreichend ist, und die die meisten von diesen Frameworks bereitgestellten Funktionen beibehalten möchten (dies). Artikel (nur für Rails eingeführt).

Es gibt viele Möglichkeiten, Rails und Webpack im Internet zu integrieren, und sie sind tatsächlich sehr gut. In diesem Artikel wird nur eine der Integrationsmethoden vorgestellt, die meiner Meinung nach genau richtig ist. Viele der Konzepte sind nicht neu, sondern wurden lediglich aus früheren Lernerfahrungen zusammengestellt.

Anforderungen

Lassen Sie uns zunächst über unsere Bedürfnisse sprechen und warum wir keine Asset-Pipeline verwenden. Tatsächlich handelt es sich lediglich um die folgende Liste:

Wir möchten neu verwenden Unterstützte Syntax wie ES2015 erfordert Babel.

Viele auf Bower kompilierte Pakete sind unvollständig, werden nicht unterstützt oder haben andere Probleme, die uns dazu veranlassen, npm zu verwenden.

Wir wollen Abhängigkeiten durch Module verwalten.

assets-org und gem eignen sich nicht so gut für die Verwaltung von Front-End-Asset-Bundles.

Ich hoffe, dass die Bereitstellung so einfach wie möglich sein kann.

Vorbereitung

Im Allgemeinen verwendet diese integrierte Architektur npm (Garn kann auch verwendet werden), um Front-End-Ressourcen zu verwalten, während gem nur für den Back-End-Teil verantwortlich ist.

Nodejs und npm installieren

Ruby und Rails installieren

Postgre SQL installieren (verwenden Sie Postgre SQL, da es in einer Demonstration auf Heroku bereitgestellt wird)

Schritt 1 – Erstellen Sie ein Projekt

# 由於示範部署至 Heroku
# 因此無法使用 sqlite3
$ rails _5.0.0.1_ new [project_name] --database postgresql
$ cd [project_name]
$ bundle install
$ rails db:create

$ rails g controller pages index # 建立測試頁面
$ rails server # 完成建立一個 Rails 專案
# 開啟 http://localhost:3000/pages/index
Nach dem Login kopieren

npm importieren

$ npm init --yes

# 過程中,如果需要測試一下 webpack 指令則需要安裝全域
$ npm i -g webpack webpack-dev-server

# 安裝所需的前端函式庫
$ npm i jquery@^2.1.4 -S
$ npm i jquery-ujs@~1.1.0-1 -S
$ npm i lodash@~3.0.0 -S
$ npm i vue -S

# 安裝開發環境所需的套件與函式庫
$ npm i webpack \
    webpack-dev-server \
    webpack-manifest-plugin \
    extract-text-webpack-plugin -D

$ npm i babel-core \
    babel-loader babel-runtime \
    babel-plugin-transform-runtime \
    babel-preset-es2015 -D # Babel 相關

$ npm i coffee-loader coffee-script -D

$ npm i css-loader \
    style-loader \
    node-sass \
    sass-loader -D

$ npm i exports-loader -D # 匯出檔案
$ npm i expose-loader -D # 將物件加到全域(Javascript)
$ npm i file-loader url-loader -D
$ npm i imports-loader -D # 使用的模組可相依於全域
Nach dem Login kopieren

Um Ihre schnelle Installation zu erleichtern, wird unten package.json bereitgestellt

"dependencies": {
  "jquery": "^2.2.4",
  "jquery-ujs": "^1.1.0-1",
  "lodash": "^3.0.1",
  "vue": "^2.0.5"
},
"devDependencies": {
  "babel-core": "^6.18.2",
  "babel-loader": "^6.2.7",
  "babel-plugin-transform-runtime": "^6.15.0",
  "babel-preset-es2015": "^6.18.0",
  "babel-runtime": "^6.18.0",
  "coffee-loader": "^0.7.2",
  "coffee-script": "^1.11.1",
  "css-loader": "^0.25.0",
  "exports-loader": "^0.6.3",
  "expose-loader": "^0.7.1",
  "extract-text-webpack-plugin": "^1.0.1",
  "file-loader": "^0.9.0",
  "imports-loader": "^0.6.5",
  "node-sass": "^3.11.2",
  "sass-loader": "^4.0.2",
  "style-loader": "^0.13.1",
  "url-loader": "^0.5.7",
  "webpack": "^1.13.3",
  "webpack-dev-server": "^1.16.2",
  "webpack-manifest-plugin": "^1.1.0"
},
"babel": {
  "presets": [
    "es2015"
  ],
  "plugins": [
    [
      "transform-runtime",
      {
        "polyfill": false,
        "regenerator": true
      }
    ]
  ]
}
Nach dem Login kopieren

Schritt 2 – Organisationsstruktur

Um die Bereitstellung und die nachfolgenden Einstellungen zu vereinfachen, haben wir uns entschieden, die Javascript- und CSS-Ressourcendateien aus ihren ursprünglichen Verzeichnissen zu extrahieren und gleichzeitig die standardmäßigen zugehörigen Funktionen von Rails beizubehalten. Die grobe Struktur sieht wie folgt aus. Wir platzieren alle Front-End-Ressourcen im Client-Verzeichnis. Wenn Sie es Webpack oder Frontend nennen möchten, ist dies natürlich auch in Ordnung.

.
├── /app
│   ├── /assets
│   ├── /controllers
│   ├── /views
│   └── ...
├── /bin
├── /config
├── /db
├── /public
├── ...
├── /client
│   ├── /fonts
│   ├── /images
│   ├── /javascripts
│   ├── /stylesheets
│   ├── development.config.js
│   ├── production.config.js
└── ...
Nach dem Login kopieren

Sofern Sie nicht befehlsgesteuert sind, können Sie den Editor verwenden, um relevante Dateien und Verzeichnisse zu erstellen.

$ mkdir -p client/javascripts
$ mkdir client/fonts
$ mkdir client/images
$ mkdir client/stylesheets
# 新增 Entry Point 檔案
$ touch client/javascripts/application.js
$ touch client/javascripts/home.coffee # 測試 coffee 使用
$ touch client/fonts/.keep
$ touch client/images/.keep
$ touch client/stylesheets/home.scss

$ touch client/development.config.js
$ touch client/production.config.js
Nach dem Login kopieren

Beachten Sie, dass in diesem Projekt Nodejs gemischt sind, daher sollten Sie Add Verwandte Einstellungen für .gitignore.

# Node
node_modules
jspm_packages
.npm
.eslintcache
npm-debug.log*
pids
*.pid
*.seed
*.pid.lock
.nyc_output
.grunt
.lock-wscript
build/Release
Nach dem Login kopieren

Einfaches Verifizierungsbeispiel

javascripts/home.coffee

console.log "Hello, CoffeeScript!"
Nach dem Login kopieren

stylesheets/home.scss

/* 記得放一張圖片 */.home-banner { 
 background-image: url('../images/banner.png');
 }
Nach dem Login kopieren

javascripts/application . js

import styles from '../stylesheets/home.scss'
import Home from './home'
Nach dem Login kopieren

Schritt 3 – Webpack konfigurieren

development.config.js

var path = require('path')
var _ = require('lodash')
var webpack = require('webpack')
var assetsPath = path.join(__dirname, '..', 'public', 'assets')
var ExtractTextPlugin = require('extract-text-webpack-plugin')

var config = {
  context: path.join(__dirname, '..'),
  entry: {
    /* 定義進入點與其檔案名稱 */
    application: [
      path.join(__dirname, '/javascripts/application.js')
    ]
  },
  output: {
    path: assetsPath,
    filename: '[name]-bundle.js',
    publicPath: '/assets/'
  },
  resolve: {
    extensions: ['', '.js', '.coffee', '.json']
  },
  debug: true,
  displayErrorDetails: true,
  outputPathinfo: true,
  devtool: 'cheap-module-eval-source-map',
  module: {
    loaders: [
      {
        test: require.resolve('jquery'),
        loader: 'expose?jQuery'
      },
      {
        test: require.resolve('jquery'),
        loader: 'expose?$'
      },
      {
        test: /\.js$/,
        loader: 'babel',
        exclude: /node_modules/
      },
      {
        test: /\.coffee$/,
        loader: 'coffee'
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)\??.*$/,
        loader: 'url?limit=8192&name=[name].[ext]'
      },
      {
        test: /\.(jpe?g|png|gif|svg)\??.*$/,
        loader: 'url?limit=8192&name=[name].[ext]'
      },
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style', 'css')
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract('style', 'css!sass')
      }
    ]
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    }),
    new ExtractTextPlugin('[name]-bundle.css', {
      allChunks: true
    })
  ]
}

module.exports = config
Nach dem Login kopieren

production.config.js

var path = require('path')
var _ = require('lodash')
var webpack = require('webpack')
var assetsPath = path.join(__dirname, '..', 'public', 'assets')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var ManifestPlugin = require('webpack-manifest-plugin')

var config = {
  context: path.join(__dirname, '..'),
  entry: {
    application: path.join(__dirname, '/javascripts/application.js')
  },
  output: {
    path: assetsPath,
    filename: '[name]-bundle-[chunkhash].js',
    publicPath: '/assets/'
  },
  resolve: {
    extensions: ['', '.js', '.coffee', '.json']
  },
  debug: true,
  displayErrorDetails: true,
  outputPathinfo: true,
  devtool: 'cheap-module-eval-source-map',
  module: {
    loaders: [
      {
        test: require.resolve('jquery'),
        loader: 'expose?jQuery'
      },
      {
        test: require.resolve('jquery'),
        loader: 'expose?$'
      },
      {
        test: /\.js$/,
        loader: 'babel',
        exclude: /node_modules/
      },
      {
        test: /\.coffee$/,
        loader: 'coffee'
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)\??.*$/,
        loader: 'url?limit=8192&name=[name]-[hash].[ext]'
      },
      {
        test: /\.(jpe?g|png|gif|svg)\??.*$/,
        loader: 'url?limit=8192&name=[name]-[hash].[ext]'
      },
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style', 'css')
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract('style', 'css!sass')
      }
    ]
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    }),
    new ExtractTextPlugin('[name]-bundle-[chunkhash].css', {
      allChunks: true
    }),
    new ManifestPlugin({
      fileName: 'client_manifest.json'
    })
  ]
}

module.exports = config
Nach dem Login kopieren

完成之後執行,測試看看是否有地方錯誤。如果您對於 webpack 並不陌生可以閱讀設定檔理解一下。

$ webpack --config client/development.config.js
$ webpack --config client/production.config.js
Nach dem Login kopieren

查看 public/assets 目錄底下看看編譯的結果。

第四步 - 整合 Rails

到此您應該已經理解,我們就是將前端的部份交給 webpack 處理,然後遵循 Rails 的架構將最終的資源檔編譯輸出到 public/assets。

現在的問題是,我們該如何讀取編譯好的資源呢?

由於我們希望能夠盡可能的遵循 Rails 的慣例,因此下一步我們在 app/views/layouts/application.html.erb 放入

<%= client_stylesheet_link_tag &#39;application&#39; %>
<%= client_javascript_include_tag &#39;application&#39; %>
Nach dem Login kopieren

上面是我們希望的作法(看起來就像是預設支援),所以接著下來我們需要做一些修改好讓 Rails 支援上面兩個 helpers。

首先因為 webpack 加上 hash 的編譯結果,Rails 並無法得知對應的檔案。於是我們需要在 production.config.js 使用ManifestPlugin 匯出 manifest 讓 Rails 得知如何對應檔案。

config/application.rb

require_relative &#39;boot&#39;

require &#39;rails/all&#39;

Bundler.require(*Rails.groups)

module RailsWepback
  class Application < Rails::Application
    config.webpack = {
      asset_manifest: {}
    }
  end
end
Nach dem Login kopieren

新增 config/initializers/webpack.rb

asset_manifest = Rails.root.join(&#39;public&#39;, &#39;assets&#39;, &#39;client_manifest.json&#39;)

if File.exist?(asset_manifest)
  Rails.configuration.webpack[:manifest] = JSON.parse(
    File.read(asset_manifest)
  ).with_indifferent_access
end
Nach dem Login kopieren

完成這些前置作業之後我們可以讀取到 manifest 了,但您知道的;原生的 Rails 並沒有剛剛那兩個 helpers ,我們需要在app/helplers/application_helper.rb 加上

def client_javascript_include_tag(name)
  filename = "#{name}-bundle.js"
  asset_url = Rails.application.config.asset_host
  src = "#{asset_url}/assets/#{filename}"

  if Rails.env.development?
  elsif Rails.configuration.webpack[:manifest]
    asset_name = Rails.configuration.webpack[:manifest]["#{name}.js"]
    if asset_name
      src = "#{asset_url}/assets/#{asset_name}"
    end
  end
  "<script src=\"#{src}\"></script>".html_safe
end

def client_stylesheet_link_tag(name)
  filename = "#{name}-bundle.css"
  asset_url = Rails.application.config.asset_host
  src = "#{asset_url}/assets/#{filename}"

  if Rails.env.development?
  elsif Rails.configuration.webpack[:manifest]
    asset_name = Rails.configuration.webpack[:manifest]["#{name}.css"]
    if asset_name
      src = "#{asset_url}/assets/#{asset_name}"
    end
  end
  "<link rel=\"stylesheet\" href=\"#{src}\">".html_safe
end
Nach dem Login kopieren

這上面的 asset_host 是為了讓事情單純一點,我們選擇在 config/environments/development.rb 和 production.rb 加上

# 路徑請依據實際的狀況調整
config.action_controller.asset_host = &#39;127.0.0.1:3000&#39;
Nach dem Login kopieren

您可以採取任何您覺得更好的方式取得路徑。

完成第一階段

到這一步,其實我們已經完成最上面我們列出的需求了。

先在 terminal 中執行

$ webpack --config client/development.config.js --watch

開啟另一個 session 執行

$ rails server

最後在 views/pages/index.html.erb 中的任一 tag 補上 class="home-banner" 您就可以觀察到變化。webpack 在背後一直觀察client 底下檔案的變化,Rails 的開發伺服器則負責原來的工作,載入那些編譯後的檔案。

只是這樣每一次要測試都要打兩條指令很麻煩。

優化開發指令

新增 npm scripts

再往下走之前,我們可以先把 webpack 的指令與其單配的參數先整理到 npm script

"scripts": {
  "build:dev": "webpack --config=client/development.config.js --display-reasons --display-chunks --progress --color --watch",
  "build": "webpack --config=client/production.config.js -p"
}
Nach dem Login kopieren

接著為了讓我們往後只使用一道指令就能夠輕鬆寫意的開發。最簡單的方式就是使用 foreman

$ gem install foreman

安裝完 foreman 之後我們需要設定 Procfile 讓其為我們同時啟動兩道指令。

新增 Procfile.dev

Procfile support 類型程式預設使用 Procfile 為設定檔,如果直接使用該檔案可能會遇到問題,例如:當我們要使用 Heroku 的話,後續可能在部署的時候產生問題,主要是目前的設定僅限於開發階段使用,於是我們改使用其他的檔名 Procfile.dev。

在專案跟目錄下新增 Procfile.dev

web: bundle exec rails server -p 3000
webpack: npm run build:dev
Nach dem Login kopieren

使用 foreman

$ foreman s -f Procfile.dev

啟動後您應該看到類似的訊息:

18:30:56 web.1     | started with pid 16693
18:30:56 webpack.1 | started with pid 16694
18:30:57 webpack.1 |
18:30:57 webpack.1 | > example@1.0.0 build:dev /Users/andyyou/Workspace/sandbox/rails_vuejs_integrate_1/example
18:30:57 webpack.1 | > webpack --config=client/development.config.js --display-reasons --display-chunks --progress --color --watch
18:30:57 webpack.1 |
Hash: 2fdcbe01c557b347442e
18:31:00 web.1     | => Booting Puma
18:31:00 webpack.1 | Version: webpack 1.13.3
18:31:00 web.1     | => Rails 5.0.0.1 application starting in development on http://localhost:3000
18:31:00 webpack.1 | Time: 2893ms
Nach dem Login kopieren

支援 Hot Reload

基本上到了上一步就已經可以滿足大多數的開發情境,不過您可能也聽多了關於 Hot Replacement Mode (HRM) 的優點,如果我們也想支援呢?

原理上很單純,我們只需要讓前端資源檔換成是由 webpack-dev-server 所提供即可。

新增 devserver.config.js

注意到基本上這邊只有加入 webpack/hot/dev-server 和 publicPath 不同的差異,可以有更精簡的方式,不過這邊為了讓之後維護比較明顯直覺一點所以將其獨立一個檔案:

var path = require(&#39;path&#39;)
var _ = require(&#39;lodash&#39;)
var webpack = require(&#39;webpack&#39;)
var assetsPath = path.join(__dirname, &#39;..&#39;, &#39;public&#39;, &#39;assets&#39;)
var ExtractTextPlugin = require(&#39;extract-text-webpack-plugin&#39;)

var config = {
  context: path.join(__dirname, &#39;..&#39;),
  entry: {
    application: [
      &#39;webpack/hot/dev-server&#39;,
      path.join(__dirname, &#39;/javascripts/application.js&#39;)
    ]
  },
  output: {
    path: assetsPath,
    filename: &#39;[name]-bundle.js&#39;,
    publicPath: &#39;http://localhost:8080/assets/&#39;
    /* publicPath: &#39;/assets/&#39; */
  },
  resolve: {
    extensions: [&#39;&#39;, &#39;.js&#39;, &#39;.coffee&#39;, &#39;.json&#39;]
  },
  debug: true,
  displayErrorDetails: true,
  outputPathinfo: true,
  devtool: &#39;cheap-module-eval-source-map&#39;,
  module: {
    loaders: [
      {
        test: require.resolve(&#39;jquery&#39;),
        loader: &#39;expose?jQuery&#39;
      },
      {
        test: require.resolve(&#39;jquery&#39;),
        loader: &#39;expose?$&#39;
      },
      {
        test: /\.js$/,
        loader: &#39;babel&#39;,
        exclude: /node_modules/
      },
      {
        test: /\.coffee$/,
        loader: &#39;coffee&#39;
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)\??.*$/,
        loader: &#39;url?limit=8192&name=[name].[ext]&#39;
      },
      {
        test: /\.(jpe?g|png|gif|svg)\??.*$/,
        loader: &#39;url?limit=8192&name=[name].[ext]&#39;
      },
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract(&#39;style&#39;, &#39;css&#39;)
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract(&#39;style&#39;, &#39;css!sass&#39;)
      }
    ]
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: &#39;jquery&#39;,
      jQuery: &#39;jquery&#39;
    }),
    new ExtractTextPlugin(&#39;[name]-bundle.css&#39;, {
      allChunks: true
    })
  ]
}

module.exports = config
Nach dem Login kopieren

增加 npm scripts

"dev": "webpack-dev-server --config=client/devserver.config.js --inline --hot --no-info"
Nach dem Login kopieren

更新 app/helpers/application.rb

因為目前有兩種開發模式,所以我們透過環境變數 HRM=true 來區分支不支援 HRM 模式。這邊遭遇的問題就單純是路徑不一樣,您絕對可自行調整優化,而這篇文章旨在記錄這個流程與概念。

def client_javascript_include_tag(name)
  filename = "#{name}-bundle.js"
  asset_url = Rails.application.config.asset_host
  src = "#{asset_url}/assets/#{filename}"

  if Rails.env.development?
    if ENV["HRM"]
      src = "http://localhost:8080/assets/#{filename}"
    else
      src = src
    end
  elsif Rails.configuration.webpack[:manifest]
    asset_name = Rails.configuration.webpack[:manifest]["#{name}.js"]
    if asset_name
      src = "#{asset_url}/assets/#{asset_name}"
    end
  end
  "<script src=\"#{src}\"></script>".html_safe
end

def client_stylesheet_link_tag(name)
  filename = "#{name}-bundle.css"
  asset_url = Rails.application.config.asset_host
  src = "#{asset_url}/assets/#{filename}"

  if Rails.env.development?
    if ENV["HRM"]
      src = "http://localhost:8080/assets/#{filename}"
    else
      src = src
    end
  elsif Rails.configuration.webpack[:manifest]
    asset_name = Rails.configuration.webpack[:manifest]["#{name}.css"]
    if asset_name
      src = "#{asset_url}/assets/#{asset_name}"
    end
  end
  "<link rel=\"stylesheet\" href=\"#{src}\">".html_safe
end
Nach dem Login kopieren

Procfile.devserver

web: bundle exec rails server -p 3000
webpack: npm run dev
Nach dem Login kopieren

使用指令

# 平常開發模式
$ foreman s -f Procfile.dev

# 支援 Hot Reload
$ HRM=true foreman start -f Procfile.devserver

# Ctrl + C 中止
Nach dem Login kopieren

漸進式的 Vue.js 是 MVC 框架的好朋友

在 Javascript 當道的今天我想您很容易找到很多關於 SPA 的主流作法。但這篇文章要說明的是把 JS 當作配角的作法。

首先我們需要更新設定檔,使其支援主角 Vue.js v2

$ npm i -g vue-loader vue-hot-reload-api -D
Nach dem Login kopieren

webpack 所有的 config loader 的部分補上:

{
  test: /\.vue$/,
  loader: &#39;vue&#39;}
Nach dem Login kopieren

另外 resolve 的部分,因為我們需要 standalone 版本的功能所以需要下面設定:

resolve: {
  extensions: [&#39;&#39;, &#39;.js&#39;, &#39;.coffee&#39;, &#39;.json&#39;],  /**
   * Vue v2.x 之後 NPM Package 預設只會匯出 runtime-only 版本,若要使用 standalone 功能則需下列設定
   */
  alias: {
    vue: &#39;vue/dist/vue.js&#39;
  }
}
Nach dem Login kopieren

首先新增元件

$ mkdir client/javascripts/components
$ touch client/javascripts/components/Car.vue
Nach dem Login kopieren

Car.vue 範例程式如下

<script>
export default {
  data () {
    return {
      brand: &#39;BMW 3 Series&#39;,
      mileage: 0
    }
  },

  mounted () {
    this.handle = setInterval(() => {
      this.mileage++
    }, 1000)
  },

  destroyed () {
    clearInterval(this.handle)
  }
}
</script>

<style scoped>
$pink: pink;

.brand {
  color: $pink;
  font-size: 1.4em;
}
</style>
Nach dem Login kopieren

更新 application.js

import styles from &#39;../stylesheets/home.scss&#39;
import Home from &#39;./home&#39;
import Vue from 'vue'
import Car from './components/Car.vue'

document.addEventListener('DOMContentLoaded', function () {
  new Vue({
    el: '#app',
    data: {
      message: 'Hello, Rails with Vue.js'
    },
    components: {
      car: Car
    }
  })
})
Nach dem Login kopieren

app/views/pages/index.html.erb

<div id="app" v-cloak>
  <h1 class="home-banner">{{ message }}</h1>
  <car inline-template>
    <div>
      I am <span class="brand">{{ brand }}</span>! I runned {{ mileage }}.
      The important thing is the variable from controller#action wheel is <%= @wheel %>
    </div>
  </car>
</div>
Nach dem Login kopieren

如果您曾使用過 Vue.js 可能會覺得這樣好奇怪,為什麼 component 裡面沒有