Docker上にRails6を構築し、Rails経由でVue.jsファイルを読み込んでブラウザ上に表示する方法についてです。
フロントエンドはVue.jsで作成し、DBなどのバックエンドをRailsで構築するアプリケーションを想定しています。
特に、Docker上でRails6を使ってVue.js使う設定にすると、Webpackerでファイルがコンパイルできないといった不具合に見舞われることがあります。
それらの対処法も踏まえて解説しています。最終的に、次のようなページを表示します。
Docker上に構築したRails6でVue.jsを表示するまでの流れ
Docker上に構築したRails6でVue.jsを表示するまでの流れは次のようになります。
- Dcoker上にRailsを構築する
- DBの設定をする
- ビューファイルを作成する
- WebpackerでVueをインストールする
- vue-loaderのバージョンを下げる(コンパイルエラー対応)
- Babelの設定を変更する(大量の警告を非表示にする)
- コンパイルするファイル名の変更(hello_vue.js → main.js)
- ビューファイルを編集してVue.jsの内容を表示する
- Vueテンプレートを作成して読み込む
- Vuetifyを使う
実際には、1~7までで、Vue.jsの内容を表示することができます。より実用的な使い方のために、(8)vueテンプレートの切出しと読み込み、(9)Vuetifyの活用方法を追加しています。
(追記)Webpackerのコンパイルが遅い場合は以下をご参考ください。
【簡単】Dcoker上のRailsでWebpackerのコンパイルが遅すぎるを解決する方法
Dcoker上にRailsとDBサーバーを構築する
Dcoker上にRailsを構築します。次の5つのファイルが必要になります。
- Dockerfile
- Gemfile
- Gemfile.lock
- entrypoint.sh
- docker-compsoe.yml
最初にプロジェクトのルートディレクトリを作成し、移動しておきます。
$ mkdir rails-vue
$ cd rails-ve
Dockerfileの作成
Rubyのバージョンに指定がない場合は、Ruby公式サイトで安定版を調べた後、docker hubのRubyイメージで該当するものを確認します。
Rails6からはJavaScriptや画像などのアセットを管理するためにWebpackerを使います。Webpackerをインストールするために、Node.jsとYarnをインストールしておく必要があります。
DBはPostgreSQLを指定しています。
$ vim Dockerfile
FROM ruby:2.7.4
#apt-keyとdevconfのエラー対策
ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
ENV DEBCONF_NOWARNINGS=yes
# node.jsと必要なライブラリのインストトール
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client \
curl apt-transport-https wget
# yarnのインストール
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn
#aptキャッシュの削除
RUN rm -rf /var/lib/apt/lists/*
# ディレクトリ・ファイルの作成
RUN mkdir /rails-vue
WORKDIR /rails-vue
COPY Gemfile /rails-vue/Gemfile
COPY Gemfile.lock /rails-vue/Gemfile.lock
# gem(Rails6)のインストール
RUN bundle install
COPY . /rails-vue
RUN yarn install --check-files
RUN bundle exec rails webpacker:compile
# コンテナ起動時に毎回実行するスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# rails起動コマンド
CMD ["rails", "server", "-b", "0.0.0.0"]
ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
apt-keyのエラー対策として、環境変数でAPT_KEY_DONT_WARN_ON_DANGEROUS_USAGEを設定しています。値は「DontWarn」を指定していますが、1でも何でもいいです。
ENV DEBCONF_NOWARNINGS=yes
apt-utilsがないために表示されるエラー対策として、環境変数でENV DEBIAN_FRONTENDを設定しています。
apt-utilsはなくても問題なく動くため、軽量化のためにもインストールしません。
rm -rf /var/lib/apt/lists/*
aptが自動生成したキャッシュが溜まっていくと容量を圧迫します。軽量化のため削除しています。
Gemfileの作成
GemfileとはRailsのライブラリであるgemを管理するためのファイルです。bundle install
を実行すると、Gemfileを参照して、まだインストールされていないgemがあればインストールします。
インストールしたいgemがあればGemfileに追記してから、bundle install
を実行します。
$ vim Gemfile
source 'https://rubygems.org'
gem 'rails', '~>6'
~>6 というのは、バージョン6系の最新版という意味です。
Gemfile.lockの作成
Gemfile.lockはインストール済みのgemとそのバージョンの一覧です。内容は自動で生成されるので、自分で中身を編集する必要はありません。
ここではファイルを生成するのみです。
touch Gemfile.lock
GemfileとGemfile.lockの違い
ファイル | 内容 | 直接編集 |
---|---|---|
Gemfile | インストール対象のgem | ○ |
Gemfile.lock | インストール済みのgem | × |
entrypoint.sh
コンテナ起動時に実行するシェルスクリプトを作成します。
vim entrypoint.sh
#!/bin/bash
set -e
# 初期に作成されるPIDを削除する
rm -f /rails-vue/tmp/pids/server.pid
# DockerfileのCMDにセットしたすべての引数を実行する
exec "$@"
#!/bin/bash
#! の後にこのファイルに書かれているスクリプトを指定します。ここでは bash で読み込むという指定です。bashのシェルスクリプトを作成するときは冒頭に必ず記載します。
set -e
エラー発生時にシェルスクリプトを終了するための設定を有効化しています。
(参考)シェルスクリプトの罠を避ける三つの tips
rm -f /PJ名/tmp/pids/server.pid
server.pidファイルにはプロジェクトのPIDが入ります。これがあると、railsを起動したときに、A server is already running. というエラーが発生するので、削除します。
exec “$@”
execは処理を実行するコマンドです。”$@” はすべての引数を展開する記述です。DcokerfileのCMDで記述した["rails", "server", "-b", "0.0.0.0"]
の4つの引数が入ります。
つまり、 exec rails server -b 0.0.0.0
となります。
exec rails server -b 0.0.0.0
rails server
はrailsの起動コマンドです。rails s
と同じです。bオプションはrailsをどのIPアドレスに紐づけるかを指定します。0.0.0.0はすべてのIPアドレスを指します。
つまり、コンテナ内のすべてのIPアドレスに紐付ける形でrailsを起動しています。
docker-compose.ymlの作成
Dcoker上でRailsコンテナとDBコンテナを紐付けて起動するための処理をdocker-compose.ymlに記述します。
$ vim docker-compose.yml
version: '3'
services:
db:
image: postgres
container_name: rails-vue-db
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
POSTGRES_HOST_AUTH_METHOD: 'trust'
web:
build: .
container_name: rails-vue-web
command: bash -c "rm -f tmp/pids/server.pid && rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/rails-vue
ports:
- "3000:3000"
depends_on:
- db
プロジェクトのビルド
railsアプリケーションの作成
docker-sompose runコマンドでwebコンテナを起動し、起動したコンテナの中で、rails new
コマンドを実行します。
$ docker-compose run web rails new . --force --no-deps --database=postgresql
サービス名 web
以降はすべて引数として渡すデータです。rails new
でアプリケーション名は現在のディレクトリ 「.」を指定し、以下のオプションをつけて実行しています。
--force
: 既存ファイルがある場合は強制的に上書き--no-deps
: リンクしたサービスを起動しない(ここではdbサービス)--database=postgresql
: DBはPostgreSQLを指定
最初に作成した5つのファイルに加えてファイルが生成されます。
$ ls -a
. .git Dockerfile Rakefile config entrypoint.sh package.json test
.. .gitattributes Gemfile app config.ru lib postcss.config.js tmp
.DS_Store .gitignore Gemfile.lock babel.config.js db log public vendor
.browserslistrc .ruby-version README.md bin docker-compose.yml node_modules storage yarn.lock
アプリケーションのビルド
rails newによりgemfileが書き変わるので、書き換わったファイルでイメージをビルドしなおします。
ビルドを実行すると、Dockerfileがもう一度実行されるので、bundle install
も実行されます。
$ docker-compose build
Successfully built 33a02920b593、Successfully tagged rails-vue_web:latestのように表示されればビルド成功です。
追記するのは、3行のみです。
DBの設定
データベース設定ファイルの編集
DBに接続するための情報をconfig/database.ymlに追記します。
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
#####追記#####
host: db
username: postgres
passowrd:
#############
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
production:
<<: *default
database: myapp_production
username: myapp
password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>
Dockerコンテナ内に作成したRailsアプリケーションの中でDBを生成します。
$ docker-compose run web rails db:create
「アプリケーション名_development」と「アプリケーション名_test」の2つのBが生成されます。
$ docker-compose run web rails db:create
Starting rails-vue_db_1 ... done
Creating rails-vue_web_run ... done
Created database 'rails_vue_development'
Created database 'rails_vue_test'
コンテナを起動
Dockerコンテナ内のrailsの下準備が終わったので、コンテナを起動します。
$ docker-compose up
きちんと起動できるか確かめるために、-dオプションは付けない方が推奨です。
-dをつけた場合はバックグラウンドでの起動となるため、エラーやアクセスログが表示されません。
http://0.0.0.0:3000 にアクセスして、Railsのページが表示されれば成功です。
ビューファイルを作成する
http://0.0.0.0:3000/home/index で別のページが表示されるようにします。
homeコントローラーのindexアクションを指定して、ビューファイルを作成します。
rails g <コントローラ名> <アクション名>
実例
コンテナの外から、コマンドを実行します。
$ docker-compose run web rails g controller home index
Creating rails-vue_web_run ... done
Running via Spring preloader in process 22
create app/controllers/home_controller.rb
route get 'home/index'
invoke erb
create app/views/home
create app/views/home/index.html.erb
invoke test_unit
create test/controllers/home_controller_test.rb
invoke helper
create app/helpers/home_helper.rb
invoke test_unit
invoke assets
invoke scss
create app/assets/stylesheets/home.scss
コントローラ、ビューファイル、SCSS、ルーティングなど、ページ表示に必要なファイル群が一気に生成されます。
http://0.0.0.0:3000/home/index にアクセスして以下のページが表示されればOKです。
WebpackerでVueをインストールする
RailsでVue.jsを読み込むために、Webpackerを使ってRailsにVueを追加します。これを追加することで、Vueファイルのコンパイルが可能になります。
また、デフォルトで、hello_vue.jsという「Hello Vue!」をブラウザに表示するテスト用のファイルも生成してくれます。
rails webpacker:install:vue
実例
Dockerコンテナの外から実行する場合は、サービスを指定して、引数でコマンドを渡します。
$ docker-compose run web rails webpacker:install:vue
省略
Webpacker now supports Vue.js 🎉
webpack関連のファイルが更新され、app.vueやhello_vue.jsといったファイルが生成されます。
modified: config/webpack/environment.js
modified: config/webpacker.yml
modified: package.json
modified: yarn.lock
Untracked files:
(use "git add <file>..." to include in what will be committed)
app/javascript/app.vue
app/javascript/packs/hello_vue.js
config/webpack/loaders/
vue-loaderのバージョンを下げる(コンパイルエラー対応)
rails webpacker:install:vue
でVueをインストールした状態では、コンパイルエラーが発生します。
これは、vue-loaderのバージョンが新しすぎて、必要なライブラリが入っていないためです。このため、vue-loaderのバージョンを15系まで落とします。
package.jsonファイルの修正
Webpackerはgemではなくyarn(node.js)で管理されているので、package.jsonに記載されている vue-loaderのバージョンを修正します。
"dependencies": {
(省略)
"vue-loader": "15.9.2",
(省略)
},
インストール
yarnを使って、package.jsonの内容を読み込み必要なライブラリをインストールします。
# yarn install
▼Dockerコンテナの外から実行する場合
docker-compose.ymlファイルのあるディレクトリで以下を実行します。
# docker-compose run <Railsのサービス名> yarn install
実例
$ docker exec -it rails-vue-web bash
root@59229383d91c:/rails-vue# yarn install
yarn install v1.22.5
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.3.2: The platform "linux" is incompatible with this module.
info "fsevents@2.3.2" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@1.2.13: The platform "linux" is incompatible with this module.
info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > vue-loader@15.9.2" has unmet peer dependency "css-loader@*".
[4/4] Building fresh packages...
success Saved lockfile.
Done in 21.29s.
vue-loader@15.9.2″のインストールが完了しました。
エラー内容の詳細についてはこちらをご参考。
Babelの設定を変更する(大量の警告を非表示にする)
デフォルトの状態では、コンパイル時にBabel関連の警告が大量に表示されるため、この表示をオフにします。
(エラーではなく警告なのでコンパイルは実行できるのですが、コンパイルのたびにターミナル(黒画面)が警告で埋まります)
["@babel/plugin-proposal-private-methods", { "loose": true }]
をルート直下にあるbabel.config.jsファイルに追記します。
plugins: [
(省略),
["@babel/plugin-proposal-private-methods", { "loose": true }]
].filter(Boolean)
保存すれば完了です。
次回のコンパイル以降は警告が表示されなくなります。
実際の記述例
module.exports = function(api) {
var validEnv = ['development', 'test', 'production']
var currentEnv = api.env()
var isDevelopmentEnv = api.env('development')
var isProductionEnv = api.env('production')
var isTestEnv = api.env('test')
if (!validEnv.includes(currentEnv)) {
throw new Error(
'Please specify a valid `NODE_ENV` or ' +
'`BABEL_ENV` environment variables. Valid values are "development", ' +
'"test", and "production". Instead, received: ' +
JSON.stringify(currentEnv) +
'.'
)
}
return {
presets: [
isTestEnv && [
'@babel/preset-env',
{
targets: {
node: 'current'
}
}
],
(isProductionEnv || isDevelopmentEnv) && [
'@babel/preset-env',
{
forceAllTransforms: true,
useBuiltIns: 'entry',
corejs: 3,
modules: false,
exclude: ['transform-typeof-symbol']
}
]
].filter(Boolean),
plugins: [
'babel-plugin-macros',
'@babel/plugin-syntax-dynamic-import',
isTestEnv && 'babel-plugin-dynamic-import-node',
'@babel/plugin-transform-destructuring',
[
'@babel/plugin-proposal-class-properties',
{
loose: true
}
],
[
'@babel/plugin-proposal-object-rest-spread',
{
useBuiltIns: true
}
],
[
'@babel/plugin-transform-runtime',
{
helpers: false
}
],
[
'@babel/plugin-transform-regenerator',
{
async: false
}
],
["@babel/plugin-proposal-private-methods", { "loose": true }]
].filter(Boolean)
}
}
エラーの詳細やコンパイル結果についてはこちらをご参照ください。
hello_vue.jsをmain.jsに変更する
Webpackのコンパイル対象となる大元のファイル名をhello_vue.jsからmain.jsに変更します。(変更しなくても使えますが、変更するとより本格的に見えるようになります)
ファイル名の変更
hello_vue.js を main.js に変更します。
$ mv app/javascript/packs/hello_vue.js app/javascript/packs/main.js
home/index.html.erbの修正
app/views/home/index.html.erb にWebpackerを使ってコンパイル後の hello_vue.js を読み込んでいる記述を変更します。
<%= javascript_pack_tag 'main' %>
<%= stylesheet_pack_tag 'main' %>
manifest.jsonの修正
manifest.jsonはコンパイル時にWebpackerが自動で生成するファイルです。元のファイルとコンパイル後のファイルの対応表になっています。
hello_vue.jsの状態で既にコンパイルされているため、この記述を変更します。
hello_vue を main に一括置換します。
{
"application.js": "/packs/js/application-e421b4aa3f716bebdab1.js",
"application.js.map": "/packs/js/application-e421b4aa3f716bebdab1.js.map",
"entrypoints": {
"application": {
"js": [
"/packs/js/application-e421b4aa3f716bebdab1.js"
],
"js.map": [
"/packs/js/application-e421b4aa3f716bebdab1.js.map"
]
},
"main": {
"js": [
"/packs/js/main-f10dedba5d1ccdc85afe.js"
],
"js.map": [
"/packs/js/main-f10dedba5d1ccdc85afe.js.map"
]
}
},
"main.js": "/packs/js/main-f10dedba5d1ccdc85afe.js",
"main.js.map": "/packs/js/main-f10dedba5d1ccdc85afe.js.map",
}
(参考)修正前のファイル
{
"application.js": "/packs/js/application-e421b4aa3f716bebdab1.js",
"application.js.map": "/packs/js/application-e421b4aa3f716bebdab1.js.map",
"entrypoints": {
"application": {
"js": [
"/packs/js/application-e421b4aa3f716bebdab1.js"
],
"js.map": [
"/packs/js/application-e421b4aa3f716bebdab1.js.map"
]
},
"hello_vue": {
"js": [
"/packs/js/hello_vue-f10dedba5d1ccdc85afe.js"
],
"js.map": [
"/packs/js/hello_vue-f10dedba5d1ccdc85afe.js.map"
]
}
},
"hello_vue.js": "/packs/js/hello_vue-f10dedba5d1ccdc85afe.js",
"hello_vue.js.map": "/packs/js/hello_vue-f10dedba5d1ccdc85afe.js.map",
}
以上でmain.jsへの置き換えは完了です。保存して、ブラウザをリロードしページが表示されればOKです。
ビューファイルを編集してVue.jsの内容を表示する
ここまでで、Vue.jsファイルをコンパイルする準備が整ったので、実際に、ブラウザにVue.jsの内容を出力します。
出力するファイルは、rails webpacker:install:vue
で自動生成されたテスト用の、app.vueを使います。
表示するルーティングには作成済みのHomeコントローラーのindexアクションを使います。app/views/home/index.html.erb を以下のように書き換えます。
<%= javascript_pack_tag 'hello_vue' %>
<%= stylesheet_pack_tag 'hello_vue' %>
保存して、Railsを起動するとコンパイルが走ります。
http://localhost:3000/home/index にアクセスして「Hello Vue!」と表示されればvue.jsファイルの表示に成功です。
<%= javascript_pack_tag ‘hello_vue’ %>とは?
javascript_pack_tagはWebpackerでコンパイルしたjsファイルを読み込むためのヘルパーメソッドです。
Webpackerは app/javascript/packs 配下にあるJavaScriptファイルを、コンパイルして public/packs/js 配下に出力します。そのコンパイルしたファイルを読み込んでいます。
javascript_pack_tag '元のファイル名'
として使います。元のファイル名は .js を省略して指定します。
<%= stylesheet_pack_tag ‘hello_vue’ %>とは?
stylesheet_pack_tagはWebpackerでコンパイルしたcssファイルを読み込むためのヘルパーメソッドです。
Webpackerは app/assets/stylesheets 配下にあるscssやcssファイルを、コンパイルして public/assets 配下に出力します。そのコンパイルしたファイルを読み込んでいます。
stylesheet_pack_tag '元のファイル名'
として使います。元のファイル名は拡張子を省略して指定します。
<%= %>とは?
<%= 処理 %>
は、erbの中で使うHTMLタグと一緒に使う記述で、記載した処理結果を出力(print)するためのものです。
<% 処理 %>
とした場合は、処理は行いますが、その結果を出力しません。
なお、<%== 処理 %>
のようにイコールを2つにすると、中に記述したタグなどをエスケープせずそのまま表示します。<%# %>
はコメントアウトに使います。
vueファイルの編集
Hello Vue!を表示しているページの内容を編集します。以下のように「picture」いうテキストと画像を表示します。
画像の追加
app/assets/images配下に画像を追加します。ここでは、mountain.jpgを追加しました。
app/assets/images/mountain.jpg
app.vueの編集
app.vueを以下のように変更します。
<template>
<div id="app">
<p>{{ message }}</p>
<div class="picture-wrapper">
<p>picture</p>
<img src="../assets/images/mountain.jpg" alt="">
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
message: "Hello Vue!",
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
.picture-wrapper{
margin: 0 auto;
max-width: 60%;
}
.picture-wrapper img{
width: 100%;
}
</style>
保存してリロードすれば完成です。
テンプレートファイルを作成して読み込む
現在使っているvueファイルは app.vueのみですが、他のテンプレートパーツを作成して読み込むようにします。
テンプレートファイルの作成
先ほどページに追加したテキストと画像を別のテンプレートに切り出して読み込みます。
app/javascript配下に components ディレクトリを作成し、Mountain.vue ファイルを作成します。
<template>
<div class="picture-wrapper">
<p>picture</p>
<img src="../../assets/images/mountain.jpg" alt="">
</div>
</template>
<script>
export default {
name: 'Mountain'
}
</script>
<style>
p{
text-align: center;
}
.picture-wrapper{
margin: 0 auto;
max-width: 60%;
}
.picture-wrapper img{
width: 100%;
}
</style>
画像のパスが間違っているとコンパイルエラーが発生するので注意してください。
app.vueでテンプレートを読み込む
続いて、作成したテンプレートをapp.vueの中で読み込みます。
<template>
<div id="app">
<p>{{ message }}</p>
<Mountain/>
</div>
</template>
<script>
import Mountain from "./components/Mountain"
export default {
components: {
Mountain
},
data: function () {
return {
message: "Hello Vue!",
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>
保存してリロードすれば、先ほどと同じ内容のページが表示されます。(※「picture」のスタイルからfont-size: 2em; が外れます。理由は以下ご参照)
(補足)スタイルについて
VueファイルはHTMLとスタイルを合わせて記述します(単一コンポーネントファイルと言います)。スタイルは各ファイルのみで適用となるため、
app.vueで指定しているスタイルは、テンプレートとして読み込んでいるファイルには適用されません。それぞれ個別に指定する必要があります。
すべてのVueファイルにスタイルを共通で設定したい場合は、app/assets/stylesheets/application.css に記述します。
p{
color: red;
}
保存してコンパイルすると、app.vueと、mountain.vueの両方のファイルにスタイルが適用されます。
Vuetifyを使う
VuetifyはVue.jsで使うことができるマテリアルデザインのUIフレームワークです。簡単にいうと、おしゃれなボタンなどのパーツをとても簡単に設置できるパーツのライブラリです。
(参考)Vuetify公式ページ
Vuetify公式ページのWebpackでのインストール手順を参考にしていきます。
Vuetifyのインストール
Railsコンテナ内でyarn add vuetify
を実行します。コンテナの外から実行する場合は以下になります。
docker-compose run web yarn add vuetify
webの部分は、docker-composeで指定してあるRailsのサービス名を記載してください。
hello_vue.jsの編集
Vuetifyのインスタンスを生成し、変数vuetifyに格納します。 Vueのインスタンス初期化を行うところで、vuetifyをオプションとして渡します。
import Vue from 'vue'
import App from '../app.vue'
import Vuetify from 'vuetify' //追加
import 'vuetify/dist/vuetify.min.css' //追加
Vue.use(Vuetify) //追加
const vuetify = new Vuetify(); //追加
document.addEventListener('DOMContentLoaded', () => {
const app = new Vue({
vuetify, //追加
render: h => h(App)
}).$mount()
document.body.appendChild(app.$el)
console.log(app)
})
GoogleフォントのCDNリンク設置
VuetifyはGoogleのRobotoフォントとMaterial Designアイコンを使用するため、CDNのリンクを共通レイアウトのheadタグ内に含めます。
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
共通レイアウトは app/views/layouts/application.html.erb です。
また、application.jsは使っていないため削除します。
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
修正後のapplication.html.erb
<!DOCTYPE html>
<html>
<head>
<title>RailsVue</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<%= yield %>
</body>
</html>
以上でVuetifyを使う準備は完了です。
Vuetifyを使う
VuetifyのUIコンポーネントをテンプレート内で呼び出します。
Vuetifyはv-appタグの中で使う必要があります。v-appタグの中にない場合、指定したスタイルが適用されないなどの不具合が発生します。(※この中で読み込むテンプレートには不要です。)
まずは、簡単にアラートUIを表示してみます。app/javascript/app.vue の
- templateタグの中のdivタグをv-appタグに変更します。
- v-alertタグを追加します。スタイルの調整は決められた属性を使います。
<template>
<v-app id="app">
<p>{{ message }}</p>
<Mountain/>
<v-alert
type="success"
width="400px"
color="green"
class="mx-auto"
>Alert created by Vuetify</v-alert>
</v-app>
</template>
<script>
import Mountain from "./components/Mountain"
export default {
components: {
Mountain
},
data: function () {
return {
message: "Hello Vue!",
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>
保存してページをリロードします。画像の下に次のようなVuetifyのUIコンポーネントが表示されれば正しく読み込めています。
Vuetify UIコンポーネントのスタイル指定方法
Vuetify UIコンポーネントのスタイルを指定するときは、各コンポーネント毎に使えるスタイルを公式ページで確認します。
例えば、Vuetify alertsコンポーネントの場合だと、右側のオプションでスタイルを選択することができます。
スタイルが決まったら下に表示されているコードをvueファイルのテンプレート内にコピペすれば完了です。
他に、全体的に使える属性として、widthやheightがあります。それぞれpxや%で指定することができます。
marginやpaddingを指定したい場合は、専用の表記で指定します。例えば、左右方向のmarginをautoにしたい場合は、mx-auto をclass属性の値として指定します class="mx-auto"
。加えて、margin-topを40pxにしたい場合は、mt-10を追加します class="mx-auto mt-10"
。(※4の倍数で用意されているため)
ブレイクポイントも指定することができます。詳細は、Vuetify公式 Spacingをご参照ください。
今回の例では以下のスタイルをセットしています。
- type=”success” : チェックマークのアイコンを表示
- width=”400px” :幅400px
- color=”green” : 背景色 緑(※文字色ではなく背景色の指定になります)
- class=”mx-auto” : 左右中央寄せ
<v-alert
type="success"
width="400px"
color="green"
class="mx-auto"
>Alert created by Vuetify</v-alert>
Vuetifyをテンプレートとして呼び出す
ヘッダーテンプレートの作成
最後にVuetifyをテンプレートとして呼び出します。共通ヘッダーを作ります。
app/javascript/components配下に Header.vue ファイルを作成します。
<template>
<v-card
color="grey lighten-4"
flat
tile
>
<v-toolbar dense>
<v-app-bar-nav-icon/>
<v-toolbar-title>Rails-Vue-App</v-toolbar-title>
<v-spacer/>
<v-btn icon>
<v-icon>mdi-magnify</v-icon>
</v-btn>
<v-btn icon>
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</v-toolbar>
</v-card>
</template>
<script>
export default {
}
</script>
<style>
</style>
テンプレートの読み込み
app/javascript/app.vue で Header.vueをコンポーネントとして読み込みます。
<template>
<v-app id="app">
<Header/>
<p class="page-title">{{ message }}</p>
<Mountain/>
<v-alert
type="success"
width="400px"
color="green"
class="mx-auto"
>Alert created by Vuetify</v-alert>
</v-app>
</template>
<script>
import Mountain from "./components/Mountain"
import Header from "./components/Header"
export default {
components: {
Mountain,
Header
},
data: function () {
return {
message: "Hello Vue!",
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
.page-title{
margin-top: 20px;
}
</style>
保存して読み込むといい感じに、ヘッダーナビゲーションが表示されます。
(補足)Headerテンプレートの構成
Headerテンプレートでは7つのVuerity UIコンポーネントを使っています。
- v-card
- v-toolbar
- v-app-bar-nav-icon
- v-toolbar-title
- v-spacer
- v-btn
- v-icon
v-card
v-cardは外枠となるdivタグとして使われる要素です。
(参考)https://vuetifyjs.com/ja/components/cards/
v-toolbar
v-toolbarはナビゲーションなどを構成する要素を使うためのコンポーネントです。v-cardやv-navigation-drawerの中で使います。
この中に、v-app-bar-nav-iconなどの要素を設置していきます。
(参考)https://vuetifyjs.com/ja/components/toolbars/
v-app-bar-nav-icon
v-app-bar-nav-iconは三本線のアイコンになります。v-toolbar と v-app-barの中で使用します。
コンポーネントではなくサブコンポーネント(API)の位置づけになります。
(参考)https://vuetifyjs.com/ja/api/v-app-bar-nav-icon/
v-toolbar-title
v-toolbar-titleはv-toolbarの中でタイトルテキストを表示するためのサブコンポーネント(API)です。
(参考)https://vuetifyjs.com/ja/api/v-toolbar-title/
v-spacer
v-spacerを使うとその前後のコンポーネントが左右にプッシュされます。後ろの検索アイコンなどを右端に寄せたい場合に設置します。
grids systemの中で定義されるサブコンポーネント(API)です。
(参考)https://vuetifyjs.com/ja/components/grids/
(参考)https://vuetifyjs.com/ja/api/v-spacer/
v-btn
v-btnはbuttonタグをおしゃれに表示してくれるコンポーネントです。テキストを入れることで文字が表示されます。
アイコンを表示する場合もラッパーとして使います。その場合は、オプションにicon
を指定します。
(参考)https://vuetifyjs.com/ja/components/buttons/
v-icon
v-iconはアイコンを表示するためのコンポーネントです。 MDIとFont Awesomeのアイコンが使えます。
ボタンの中にアイコンを表示する場合はオプションにicon
を指定します。
(参考)https://vuetifyjs.com/ja/components/icons/
以上で完了です。お疲れ様でした。