- 投稿日:2020-10-11T23:46:42+09:00
親コンポーネントから子コンポーネントのメソッドを呼ぶ
親コンポーネントのメソッド内で
this.$refs.対象の子コンポーネントに記述したrefの値.メソッド名
を記述します。
今回の例でいうとthis.$refs.child_component.age()
です。サンプルコード
下のコードをhtmlファイルに張り付けて、ブラウザで確認できます(IE非対応)。<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="sample"> <parent></parent> </div> </body> <script> new Vue({ el: "#sample", components: { parent: { methods: { childAge() { this.$refs.child_component.age() } }, template: ` <div> <h1>子供の情報</h1> <child ref="child_component"></child> <button v-on:click="childAge">名前を確認</button> </div> `, components: { child: { data: function() { return { name: "たけし", child_age: 10 } }, methods: { age() { console.log(this.child_age) } }, template: `<p>{{this.name}}</p>` } } }, } }) </script> </html>
- 投稿日:2020-10-11T21:10:31+09:00
Vue.js - ディレクティブ
ディレクティブの備忘録
※今後も更新予定ディレクティブ
条件分岐やループ処理など、複雑な処理をViewに組み込むVueの命令のこと。
v-xxx
の形式でViewに埋め込んで処理を書くディレクティブ一覧
v-text
文字列をテンプレートに埋め込む。
<p v-text="name"></p> <!-- データオブジェクトの name を pタグ内に埋め込む -->※下記と同じ出力がされるためどちらの記法でもよいが、アプリ内ではどちらかに統一すること。
<p>{{ name }}</p> <!-- 通常のマスタッシュ構文 -->v-pre
構文を無効にする。
デリミタをそのまま出力したい時などに使用する。<p v-pre>{{ name }}</p> <!-- 画面では {{ name }} がそのまま出力される -->v-bind
属性値にJavascript式を埋め込む。
<a v-bind:href="url">リンク</a> <!-- データオブジェクト下のurlを埋め込む -->頻繁に利用されるため、省略構文も用意されている。
本来の属性名の頭に:
を付与して表現する。<a :href="url"></a>v-on
イベントとそのイベントが発生した際に実行する処理を定義する(イベントリスナーの設定)
イベントを設定したいタグにv-on:イベント名="イベント発生時に呼び出す処理"
の形で属性を付与する。<!-- pタグクリック時にVueインスタンスのmethodsオブジェクト内に定義されたonclickmethodが呼ばれる --> <p v-on:click="onclickmethod">クリック</p>
v-on
も頻繁に使用されるため省略形が存在する。
v-on:
を@
に置き換えても同様の結果が得られる。<p @click="onclickmethod">クリック</p>また、イベントとして設定できるのはJavascriptで定められている下記リファレンス内のイベントのみ。
https://developer.mozilla.org/en-US/docs/Web/Events参考
・API(ディレクティブ) 日本語ドキュメント ※バージョンが2系より前
https://jp.vuejs.org/v2/api/#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96・API(ディレクティブ) 英語ドキュメント ※3系にも対応
https://v3.vuejs.org/api/directives.html・Javascript イベント一覧
https://developer.mozilla.org/en-US/docs/Web/Events・これからはじめる Vue.js 実践入門 (山田祥寛 著)
https://amazon.co.jp/dp/4815601828
- 投稿日:2020-10-11T18:41:09+09:00
【Vue.js】Vue.jsのdataと、forEachを使う時の注意点
Vue.jsで使うthis.dataと、forEach文を活用するときは、注意が必要という記事になります。
そもそもforEach文とは
// 配列を繰り返す offices.forEach(function(office){ console.log(office) }) // 繰り返す配列を、thisで取得する offices.forEach(function(office){ console.log(this) }, offices)第一引数にはコールバック関数を、第二引数には繰り返す配列を定義することで、thisとして取得できる。
結論:forEachのthisと、Vue.jsのthisは別物
forEach文内でのthisは、繰り返す配列のことを指してしまうので、直接格納することができない
// エラーになる offices.forEach(function(office){ this.array.push(office) })配列の要素を、this.dataの配列に格納したい
以下のような、Vueインスタンスのデータがあるとする。
data () { return { holidays: [], } }そして、以下のレスポンスデータを取得して、Vueインスタンスのデータに格納したい。
[ { "id": 1, "name": "owada" "regular_holidays": [ { "id": 1, "holiday": "mon" }, { "id": 2, "holiday": "tue" }, ・・・省略 ], }, ・・・省略 ]配列の中のオブジェクトの中の配列の要素を、格納したい時
つまり、
"regular_holidays"
の要素群をthis.data
に格納するthis.holidays = res.data.regular_holidays.map((day) => day.holiday);配列の中のオブジェクトの中の配列の中のオブジェクトの値を、格納したい時
つまり、
"regular_holidays"
の要素のオブジェクトキーである"holiday"
をthis.data
に格納するconst holidays = []; this.offices.forEach(function (office) { office.regular_holidays.forEach(function (day) { holidays.push(day.holiday); }); }); this.holidays = holidays;forEach内で、this.dataを取得できないので、うまく工夫する必要がある。
- 投稿日:2020-10-11T18:41:09+09:00
【Vue.js】Vue.jsで、forEachを使う時の注意点
Vue.jsで使うthis.dataと、forEach文を活用するときは、注意が必要という記事になります。
そもそもforEach文とは
// 配列を繰り返す offices.forEach(function(office){ console.log(office) }) // 繰り返す配列を、thisで取得する offices.forEach(function(office){ console.log(this) }, offices)第一引数にはコールバック関数を、第二引数には繰り返す配列を定義することで、thisとして取得できる。
結論:forEachのthisと、Vue.jsのthisは別物
forEach文内でのthisは、繰り返す配列のことを指してしまうので、直接格納することができない
// エラーになる offices.forEach(function(office){ this.array.push(office) })配列の要素を、this.dataの配列に格納したい
以下のような、Vueインスタンスのデータがあるとする。
data () { return { holidays: [], } }そして、以下のレスポンスデータを取得して、Vueインスタンスのデータに格納したい。
[ { "id": 1, "name": "owada" "regular_holidays": [ { "id": 1, "holiday": "mon" }, { "id": 2, "holiday": "tue" }, ・・・省略 ], }, ・・・省略 ]配列の中のオブジェクトの中の配列の要素を、格納したい時
つまり、
"regular_holidays"
の要素群をthis.data
に格納するthis.holidays = res.data.regular_holidays.map((day) => day.holiday);配列の中のオブジェクトの中の配列の中のオブジェクトの値を、格納したい時
つまり、
"regular_holidays"
の要素のオブジェクトキーである"holiday"
をthis.data
に格納するconst holidays = []; this.offices.forEach(function (office) { office.regular_holidays.forEach(function (day) { holidays.push(day.holiday); }); }); this.holidays = holidays;forEach内で、this.dataを取得できないので、うまく工夫する必要がある。
- 投稿日:2020-10-11T18:01:38+09:00
Rails+Vue.jsでユーザー登録機能を作る
Rails6.0+Vue.jsでユーザー登録の機能を作る
RailsとVue.jsを使用したSPAの新規登録機能を作成したため、
自分用にメモ書き。まずはフロント側のVue.jsを作成
共通部分のソースコード
app/javascript/app.vue<template> <div> <router-view></router-view> </div> </template> <script> import Vue from 'vue' import VueRouter from 'vue-router' // User(ユーザー) import UserNewPage from 'user/UserNewPage.vue' const router = new VueRouter({ routes: [ // User(ユーザー) { path: '/users/new', name: 'UserNewPage', component: UserNewPage }, ] }) // ref. https://jp.vuejs.org/v2/guide/plugins.html#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%AE%E4%BD%BF%E7%94%A8 Vue.use(VueRouter) export default { router } </script> <style scoped> </style>新規登録画面のソースコード
app/javascript/user/UserNewPage.vue<template> <div> <user-form-pane :errors="errors" :user="user" @submit="createUser"></user-form-pane> </div> </template> <script> import axios from 'axios'; import UserFormPane from 'user/UserFormPane.vue'; export default { components: { UserFormPane }, data() { return { user: { name: '', email: '', password: '', password_confirmation: '' }, errors: '' } }, methods: { createUser: function() { console.log("動いた") console.log(this.user.password) axios .post('/api/v1/users', this.user) .then(response => { let u = response.data; this.$router.push({ name: 'UserDetailPage', params: { id: u.id } }); }) .catch(error => { console.error(error); if (error.response.data && error.response.data.errors) { this.errors = error.response.data.errors; } }); } } } </script> <style scoped> </style>UserNewPage.vueで呼び出されているUserFormPaneのソース
app/javascript/user/UserFormPane.vue<template> <form @submit.prevent="$emit('submit')"> <div v-if="errors.length != 0"> <ul v-for="e in errors" :key="e"> <li><font color="red">{{ e }}</font></li> </ul> </div> <div> <label>Name</label> <input v-model="user.name" type="text"> </div> <div> <label>Email</label> <input v-model="user.email" type="text"> </div> <div> <label>Password</label> <input v-model="user.password" type="password"> </div> <div> <label>Password(Confirmation)</label> <input v-model="user.password_confirmation" type="password"> </div> <button type="submit">Commit</button> </form> </template> <script> export default { props: { user: {}, errors: '' } } </script> <style> </style>次にRails側でテーブルとモデルを作成する
以下のコマンドをターミナルで実行$ rails g model User name:string email:string password_digest:string $ rails db:migrateAPI側のコントローラークラスを以下の記述を追加
app/controllers/api/v1/users_controller.rbdef create user = User.new(user_params) if user.save render json: user, status: :created else render json: { errors: user.errors.full_messages }, status: :unprocessable_entity end end private def user_params params.permit(:name, :email, :password, :password_confirmation) endモデルクラスに以下を追加
app/models/user.rbclass User < ApplicationRecord has_secure_password endルート設定を追加
config/routes.rbresources :users, only: [:create]上記の設定を行えば、新規登録機能を作成できる
- 投稿日:2020-10-11T17:04:28+09:00
【Vue.js】computedがよく分からなかったので調べ直した
Vue.jsを使ってしばらく経ちますが
computed(算出プロパティ)とmethodsとwatchの違いを理解できていなかったので学習しなおしました
https://jp.vuejs.org/v2/guide/computed.htmlcomputed(算出プロパティ)
<div id="example"> <p>Original message: {{ message }}</p> <p>Computed reversed message: {{ reversedMessage }}</p> </div>var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { //reversedMessageプロパティを定義 reversedMessage: function () { return this.message.split('').reverse().join('') } } })・他のプロパティの値を加工した結果などを保持しておけるプロパティ
・computed: オプション内にプロパティ名を書くことでプロパティを定義することができる。
・function()内には行う処理(計算、データの操作など)を定義し、結果をreturnする
・この例ではreversedMessageプロパティはvm.messageの値を使用している(messageに依存している)
→computedは依存しているデータに変更があった時に自動的に再計算を行い、reversedMessageの値を更新する。methods
computedとmethodsの違い
・computed
データに何らかの計算処理をしたものをプロパティとして保持しておき、参照することができる
→結果をキャッシュしており、依存しているデータに変更がないときは計算・値の変更は行わない・メソッド
呼び出した時に処理を行い、その結果を返すただのメソッド
→呼ばれればそのつど処理(計算)を行うmethodsではなくcomputedを使うメリット
・結果をキャッシュしており、必要な時のみ計算処理を行うので処理が早い
・プロパティとして定義することで可読性があがるwatch(監視プロパティ)
プロパティを監視し、データに変化があった時に何らかの処理を行うことができる
(メソッドを定義しておき、実行するタイミングを決めるイメージ)・computedと同じ点
プロパティの変更に応じて処理を行うことができる・computedと違う部分
処理を行うだけでreturnはしない・どのように使い分けるのか?
多くの場合では算出プロパティを利用するほうが良いが、
非同期処理や処理を複雑な処理を行いたい時はwatchの方が適しているwatch オプションを利用することで、非同期処理( API のアクセス)の実行や、処理をどのくらいの頻度で>実行するかを制御したり、最終的な answer が取得できるまでは中間の状態にしておく、といったことが可能になっています。これらはいずれも算出プロパティでは実現できません。
- 投稿日:2020-10-11T16:12:39+09:00
Vue3の基本構文①
Vueの構文についてコードベースで簡単にまとめます。
今回は以下の三つです。
- v-bind
- 条件付きレンダリング
- v-for
v-bind
HTMLエレメントの要素とVueアプリのdataとの接続に使用します。
main.jsconst app = Vue.createApp({ data() { return { product: 'Socks', image: './assets/images/socks_green.jpg' } } })index.html<img v-bind:src="image">HTML側の
image
要素とVueアプリdataの中のimageプロパティーがリアクティブにバインディングされます。
なので、image
のパスを変更するとリアクティブにHTML側に反映されます。main.jsimage: './assets/images/socks_blue.jpg'※画像が緑色ソックス=>青色ソックスに変わる
ちなみに以下の様に、javascriptっぽく書くこともできます。
index.html<img v-bind:src="{{ image }}">v-bindは使用頻度が高いので以下のショートカットが用意されています。
index.html<img :src="image">条件付きレンダリング
index.html<p>In Stock</p> <p>Out of Stock</p>main.jsconst app = Vue.createApp({ data() { return { product: 'Socks', image: './assets/images/socks_blue.jpg', inStock: true } } })v-if
index.html<p v-if="inStock">In Stock</p> <p v-else>Out of Stock</p>
v-if
をHTML要素に加えることで条件を付け足すことができます。
この場合、VueアプリのdataのinStock
がtrueなのでHTMLで"In Stock"が表示される。ShowとHide
index.html<p v-show="inStock">In Stock</p>
v-if
の様にDOMから要素を加えたり消したりではなく、要素のvisibilityをtogglingする場合に使用します。
なので、以下の様にinStock
プロパティーをfalse
にするとmain.jsinStock: falseこの様にDOM上で要素自体は存在しますが、
display
がnone
になっています。
v-for
main.jsconst app = Vue.createApp({ data() { return { ... details: ['50% cotton', '30% wool', '20% polyester'] } } })Vueアプリのdataに
detail
配列を追加
これをリストとしてHTMLで表示するindex.html<ul> <li v-for="detail in details">{{ detail }}</li> </ul>
details
はdataにあるdetails
配列を参照し、detail
はlooping中の各currentエレメントを意味しています。各要素にkeyをつけたい場合は以下のようになります
main.jsdata() { return { ... variants: [ { id: 2234, color: 'green' }, { id: 2235, color: 'blue' } ] } }index.html<div v-for="variant in variants" :key="variant.id">{{ variant.color }}</div>※
:key
はv-bindのショートカットなのでv-bind:key
と同義
- 投稿日:2020-10-11T14:27:26+09:00
Vue+Quasarを実務で一週間触ってみて
実務で使うために学んだこと
Quasarとは
VueベースのFramework
便利な備え付けコンポーネントがいっぱい
StyleやLayoutも簡単にできる
レスポンシブデザインも簡単に実装できる
簡単なbuild process(quasar CLIを使えば脳死でビルドできる)
SPA/PWA/SSR/Mobile App/Desktop appなどを高速で始められる
MobileはCordova
DesktopはElectron
いわゆるマルチプラットフォームなアプリケーションをVueと備え付けのコンポーネントで爆速で作れるフレームワークというわけです。(しかも全て同じコードで)
お隣さんはIonic FrameworkやFramework7などキャッチアップするためにしたこと
ドキュメントを読み込む
https://quasar.dev/start/pick-quasar-flavour動画でアプリを作りながら手を動かす
Todoアプリ
https://www.youtube.com/watch?v=GV-D85D9KJQ&t=2118s
写真共有アプリ?
https://www.youtube.com/watch?v=Ud8jS3VlVHwGrid Gutter の使い方
https://quasar.dev/layout/grid/gutter
基本的に .row クラスにつける .q-col-gutter-md 等 コンポーネントに均等にpaddingで余白をつけれるindex.vue<div class="row q-col-gutter-md"></div>name属性をつけて Vue Devtoolで見たときにどのファイルかわかる様にする
scriptタグの中に書く
MyLayout.vue<script> name:"MyLayout" //Vue DevtoolでMyLayoutと表示される export default { // } </script>$qというものがQuasarで用意されていて {{ $q }} で色々なプロパティが参照できる
index.vue<template> <q-page> {{ $q }} </q-page> </template>Vueファイルでのレスポンシブでのクラスの付け替え
https://quasar.dev/style/breakpoints
index.vue<template> <div class="row" :class="{'q-mb-md' : $q.screen.lt.sm }" > </template> // コードの読み下し // スクリーン幅がスモール( 1023px ) 以下がtrueであれば、クラス'q-mb-md'を追加するcomputedプロパティを使用したスタイルの追加
index.vue<template> <span :style="testStyle">test</span> </template> <script> export default { computed: { testStyle() { return this.$q.screen.xs ? { color: 'red' } : { color: 'blue' }; } }; } </script> // コードの読み下し // スクリーン幅がxs( 599px )以下の場合 color: redを違う場合はcolor:blueを適用するよくするミス①
<span :style="testStyle">test</span> // :styleの :を忘れてスタイルが効かない :style= 正 style= 偽よくするミス②
computed: { testStyle() { return this.$q.screen.xs ? {color: 'red'} : { color: 'blue' } ; } }; // の{ color: '' }このシングルクォートが無くて スタイルが効かない {color: 'red'} 正 {color: red} 偽 // 数字の場合は良い line-height 1.5とか 文字列は''が必要 // {line-height: 1.5} 正 {color: red } 偽 }
- 投稿日:2020-10-11T14:27:26+09:00
Vue+Quasarを一週間触ってみて
実務で使うために学んだこと
Quasarとは
VueベースのFramework
便利な備え付けコンポーネントがいっぱい
StyleやLayoutも簡単にできる
レスポンシブデザインも簡単に実装できる
簡単なbuild process(quasar CLIを使えば脳死でビルドできる)
SPA/PWA/SSR/Mobile App/Desktop appなどを高速で始められる
MobileはCordova
DesktopはElectron
いわゆるマルチプラットフォームなアプリケーションをVueと備え付けのコンポーネントで爆速で作れるフレームワークというわけです。(しかも全て同じコードで)
お隣さんはIonic FrameworkやFramework7などキャッチアップするためにしたこと
ドキュメントを読み込む
https://quasar.dev/start/pick-quasar-flavour動画でアプリを作りながら手を動かす
Todoアプリ
https://www.youtube.com/watch?v=GV-D85D9KJQ&t=2118s
写真共有アプリ?
https://www.youtube.com/watch?v=Ud8jS3VlVHwGrid Gutter の使い方
https://quasar.dev/layout/grid/gutter
基本的に .row クラスにつける .q-col-gutter-md 等 コンポーネントに均等にpaddingで余白をつけれるindex.vue<div class="row q-col-gutter-md"></div>name属性をつけて Vue Devtoolで見たときにどのファイルかわかる様にする
scriptタグの中に書く
MyLayout.vue<script> name:"MyLayout" //Vue DevtoolでMyLayoutと表示される export default { // } </script>$qというものがQuasarで用意されていて {{ $q }} で色々なプロパティが参照できる
index.vue<template> <q-page> {{ $q }} </q-page> </template>Vueファイルでのレスポンシブでのクラスの付け替え
https://quasar.dev/style/breakpoints
index.vue<template> <div class="row" :class="{'q-mb-md' : $q.screen.lt.sm }" > </template> // コードの読み下し // スクリーン幅がスモール( 1023px ) 以下がtrueであれば、クラス'q-mb-md'を追加するcomputedプロパティを使用したスタイルの追加
index.vue<template> <span :style="testStyle">test</span> </template> <script> export default { computed: { testStyle() { return this.$q.screen.xs ? { color: 'red' } : { color: 'blue' }; } }; } </script> // コードの読み下し // スクリーン幅がxs( 599px )以下の場合 color: redを違う場合はcolor:blueを適用するよくするミス①
<span :style="testStyle">test</span> // :styleの :を忘れてスタイルが効かない :style= 正 style= 偽よくするミス②
computed: { testStyle() { return this.$q.screen.xs ? {color: 'red'} : { color: 'blue' } ; } }; // の{ color: '' }このシングルクォートが無くて スタイルが効かない {color: 'red'} 正 {color: red} 偽 // 数字の場合は良い line-height 1.5とか 文字列は''が必要 // {line-height: 1.5} 正 {color: red } 偽 }
- 投稿日:2020-10-11T12:00:36+09:00
Vue.jsでお手軽carousel
carouselって何?
carousel(カルーセル)はスライドショーの様に画像が自動でスライドしたり、手動でスライドさせたりとWebサイトにおいてメジャーな動きのある機能ですね。
デモサイト
こちらの機能をVue.jsで簡単にできるのでやっていきましょう!※Vue CLIで環境構築が済んでいる前提で進めていきますまだの方はこちらを参考に。
Vue.js を vue-cli を使ってシンプルにはじめてみるインストール
npm install vue-carousel
インストール後、グローバル、使用コンポーネントで記述して使える様にしていきます。
今回はプロフィールコンポーネントで使用したかったのでpurofile.vueに書いていきます。main.jsimport Vue from 'vue'; import VueCarousel from 'vue-carousel'; Vue.use(VueCarousel);profile.vueimport { Carousel, Slide } from 'vue-carousel'; export default { 省略 components: { Carousel, Slide } 省略 };実際に使ってみる
カルーセル表示したいところにオプションと一緒に書いていきます。
今回私はスライドに表示する写真数、スライドの自動、スライドが始まるまでのタイムアウト時間、スライドのスピードのみデフォルトから変えています。
その他のオプションやデフォルトはこちらこちらから確認できます。(英語)
今回は使用しませんでしたが、他にもボタン表示で手動スライドできたりするみたいです。profile.vue<template> <div> <h1 class="content-title">Profile</h1> <div class="Profile"> <div class="profile-content"> <!-- オプションはこのように書く --> <carousel :per-page="1" :autoplay="true" :loop="true" :autoplayTimeout="4000" :speed="1000"> <slide> <img src="../image/profile.jpg"> </slide> <slide> <img src="../image/profile2.jpg"> </slide> </carousel> </div> </div> </div> </template>各オプションの数値をお好みで変更してください。
終わり
BootstrapでもcarouselやってみたりしましたがVueの方が簡単かつカスタムしやすいので個人的には好きです!!
- 投稿日:2020-10-11T10:49:47+09:00
vite でビルドしたアプリケーションを github pages にデプロイすると _assets 以下がロードされない
- 投稿日:2020-10-11T06:56:06+09:00
【vue.js】ドラッグで順番を変えられるリストを作った
Vue.Draggableというライブラリを利用して実現しました
https://github.com/SortableJS/Vue.Draggable▼まずは普通に表示
【js側】
データを用意します
(TestViewという名前のコンポーネントにしました)<script> export default { name: "TestView", data: function () { return { list: [ { id: 1, name: 'リスト1' }, { id: 2, name: 'リスト2' }, { id: 3, name: 'リスト3' } ], } } } </script>【HTML側】
listをv-forを使って表示します
v-forについて: https://jp.vuejs.org/v2/guide/list.html#オブジェクトの-v-for<template> <div v-for="content in list" :key="content.id" style="margin: 10px;"> <span> {{ content.name }} </span> </div> </template>ここまででこんな感じの表示ができます(スタイルは適当に変えています)
▼並び替えできるようにします
Vue.Draggableをインストール
npmでインストールしましたnpm install --save vuedraggable【js側】
Vue.Draggableをインポート<script> //インポート部分追記 import draggable from 'vuedraggable' export default { name: "TestView", data: function () { return { list: [ { id: 1, name: 'リスト1' }, { id: 2, name: 'リスト2' }, { id: 3, name: 'リスト3' } ], } } } </script>【HTML側】
draggableタグでドラッグしたいリストを囲みます<template> <draggable v-model="list"> <div v-for="content in list" :key="content.id" style="margin: 10px;"> <span> {{ content.name }} </span> </div> </draggable> </template>