- 投稿日:2019-08-27T23:34:40+09:00
Vuetifyのテーブル(フィルター付き)で合計値を動的に算出する
概要
たとえばこんな表があるとします。
合計値と平均値がフッターに表示されています。
ここで、検索キーワードを入れて表をフィルタします。
合計値と平均値も更新されています。
解説
Vuetifyのデータテーブルのフィルタ機能は強力ですが、
(https://vuetifyjs.com/ja/components/data-tables )
更新された値に対してのアプローチは少し工夫が必要です。コンポーネントのプロパティを確認すると
filteredItemsというものがあります。フィルタされた後のテーブルデータはここに格納されるので活用します。
なお、このテーブルをJSから参照するためにはref属性を使用します。<v-data-table :headers="headers" :items="items" ref="summary" >const summary = this.$refs.summary.$children[0] summary.filteredItems.forEach((item) => { // 合計処理 })検索キーワードが反映されるたびにトリガーしてみます。
<v-data-table :headers="headers" :items="items" :search="searchTrigger" ref="summary" >data () { return { search: '', // ...省略 } }, computed: { searchTrigger: function() { this.$nextTick(function() { this.calc() }) return this.search } }, methods: { calc: function() { const summary = this.$refs.summary.$children[0] summary.filteredItems.forEach((item) => { // 合計処理 }) // ...省略こんな雰囲気で実現することができます。
以下のサンプルコードも合わせてご覧ください。サンプルコード
- 投稿日:2019-08-27T21:53:28+09:00
Vue.js+ElementUIプロジェクト
書いてあること
- Vue.jsプロジェクトでElementUIを利用した際のメモ(個人用メモのため間違っている可能性あり・・・)
- 公式サイトの各コンポーネント実装方法に習って実装
環境
- CentOS Linux release 7.6.1810 (Core)
- Node.js v10.16.0
- Npm 6.10.0
- Vue 3.9.1
- element-ui 2.11.1
下記で作成したVue.jsプロジェクトを利用する。
Vue.jsのプロジェクト作成作成したプロジェクト
↓に置いてあります。
vue-element-project↓Demo
vue-element-project準備
必要なパッケージをインストール
bash$ npm install element-ui --saveElementUI利用設定
display.cssはレスポンシブレイアウトで要素の表示・非表示切り替えを行う際に使用する。
Utility classes for hiding elementssrc/main.jsimport Vue from 'vue' import App from './App.vue' import router from './router' import axios from 'axios' +import ElementUI from 'element-ui' +import locale from 'element-ui/lib/locale/lang/ja' +import 'element-ui/lib/theme-chalk/index.css' +import 'element-ui/lib/theme-chalk/display.css' Vue.config.productionTip = false Vue.prototype.$axios = axios +Vue.use(ElementUI, { locale }) new Vue({ router, render: h => h(App), }).$mount('#app')Basic
Layout
span:Gridの列幅
gutter:列の間隔
offset列のオフセット
flex:FlexBoxによる列の配置
xs、sm、md、lg、xl:レスポンシブレイアウトで各ブレークポイントの列の間隔
Utility classes for hiding elements要素の表示・非表示を切り替えるユーティリティクラスContainer
el-container:ラッパーコンテナ。el-header、またはel-footerでネストすると、子要素は垂直に配置される
el-header:ヘッダーのコンテナ。デフォルトのheightは60px
el-aside:サイドバーのコンテナ。デフォルトのwidthは300px
el-main:メインのコンテナ
el-footer:フッターのコンテナ。デフォルトのheightは60pxColor
Button
type:ボタンの色、またはテキストボタンを指定
plain:背景白抜きボタン
round:角丸ボタン
circle:円形ボタン
disabled:無効ボタン
icon:テキストの左側のアイコン。テキストはなくてもよい
i:テキストの右側のアイコン
el-button-group:ボタングループ
loading:ローディングボタン
size:ボタンサイズ
native-type:ボタンタイプ。汎用ボタン、submitボタン、resetボタンを指定Link
type:リンクの色
disabled:無効リンク
underline:リンク文字列にホバーした際の下線有無
icon:テキスト左側のアイコン
i:テキスト右側のアイコンForm
Radio
label:v-modelで指定した変数へ格納する値
disabled:無効
el-radio-group:ラジオボタンをグループ化
el-radio-button:ボタンスタイルで表示
size:ボタンスタイルのサイズ
border:線を付けるCheckbox
label:v-modelで指定した変数へ格納する値
disabled:無効
el-checkbox-group:チェックボックスをグループ化
indeterminate:全チェック機能で利用
min:チェックの最小数
max:チェックの最大数
el-checkbox-button:ボタンスタイルで表示
size:ボタンスタイルのサイズ
border:線を付けるInput
maxlength:最大文字数
minlength:最小文字数
disabled:無効
clearable:クリア
show-password:パスワード非表示
prefix-icon:接頭アイコン
suffix-icon:末尾アイコン
rows:Textareaの行数
autosize:Textareaの自動サイズ調整。minRows、maxRowsで最小・最大行数を指定可能
prepend:input内の接頭固定表示
append:input内の接尾固定表示
size:inputのサイズ
el-autocomplete:オートコンプリートInputNumber
min:最小値
max:最大値
disabled:無効
step:増分
step-strictly:厳密な増分(直接値変更は不可)
precision:精度(小数点以下)
size:inputのサイズ
controls-position:コントロールの位置Select
disabled:無効
clearable:クリア
multiple:複数選択
collapse-tags:複数選択した際のタグ表示
el-option-group:選択肢のグループ化
filterable:フィルター
remote:リモート検索
remote-method:リモート検索処理
loading:ローディングCascader
disabled:無効
clearable:クリア
expandTrigger:hoverにすることで、マウスホバー時に下階層を自動で開く
show-all-levels:falseにすることで、最下層レベルのlabelのみ表示
multiple:複数選択
collapse-tags:複数選択した際のタグ表示
checkStrictly:任意のレベルの要素選択を許可
lazy、lazyLoad:要素を動的にローディング
filterable:フィルター
el-cascader-panel:パネル表示Switch
disabled:無効
active-color:アクティブ時の色
inactive-color:非アクティブ時の色
active-text:アクティブ時のテキスト
inactive-text:非アクティブ時のテキスト
active-value:アクティブ時の値
inactive-value:非アクティブ時の値Slider
disabled:無効
show-tooltip:ツールチップ
format-tooltip:書式設定
step:増分
show-stops:停止位置の表示
show-input:inputの表示
range:範囲選択
max:最大値
vertical:縦表示
height:高さ
marks:マーカー設定TimePicker
picker-options:オプション指定。開始時間、終了時間、増分などを指定
arrow-control:矢印選択
is-range:範囲選択
range-separator:範囲選択時のセパレータ文字
start-placeholde:範囲選択時の開始プレースホルダー
end-placeholde:範囲選択時の終了プレースホルダーDatePicker
picker-options:オプション指定。開始時間、終了時間、増分などを指定
type:日付選択する種類(日付、年、月、週など)を指定
range-separator:範囲選択時のセパレータ文字
start-placeholde:範囲選択時の開始プレースホルダー
end-placeholde:範囲選択時の終了プレースホルダー
default-value:既定値
format:画面表示フォーマット
value-format:変数格納時のフォーマット
default-time:日付選択時に変数へ格納される時刻DateTimePicker
picker-options:オプション指定。開始時間、終了時間、増分などを指定
type:日付選択する種類(日付、年、月、週など)を指定
start-placeholde:範囲選択時の開始プレースホルダー
end-placeholde:範囲選択時の終了プレースホルダー
default-time:日付選択時に変数へ格納される時刻Upload
on-success:アップロード成功時の処理
on-preview:プレビュー時の処理
on-remove:削除時の処理
before-remove:削除前の処理
on-exceed:サイズ超過時の処理
on-change:変更時の処理
multiple:複数選択可能
limit:複数選択時の上限ファイル数
file-list:リスト表示方法
show-file-list:リスト表示有無
list-type:リストタイプ
auto-upload:自動アップロード
drag:ドラッグRate
colors:レートの色
text-color:テキストの色
texts:各レベルのテキスト
show-text:テキスト表示
icon-classes:各レベルのアイコン
void-icon-class:アイコン表示
disabled読み取り専用:
show-score:スコアの表示
score-template:表示するスコアの書式ColorPicker
show-alpha:アルファ値を利用
predefine:定義済みカラーを設定
size:サイズTransfer
data:表示するリスト
filterable:フィルター
filter-placeholder:フィルターのプレースホルダー
filter-method:通常はラベルがフィルター対象となるが、独自の検索メソッドを利用可能
left-defalut-checked:左側のデフォルトチェック
right-default-checked:右側のデフォルトチェック
render-content:表示するリスト
titles:タイトル
button-texts:ボタンラベル
format:チェック個数表示文字列の書式Form
model:Formコンポーネントで利用するデータ
label:ラベル
label-width:ラベル幅
label-position:ラベルの位置
rules:バリデーションルール
status-icon:バリデーション結果のアイコン表示
autocomplete:オートコンプリートData
Table
data:データ
prop:各項目に表示するデータ
label:各項目のラベル
border:罫線
row-class-name:色分け制御
height:ヘッダー固定
fixed:カラム固定
highlight-current-row:ハイライト
sortable:ソート
filters:フィルター
type:表示タイプTag
type:タイプ
closable:閉じるボタン
disable-transitions:閉じるアニメーション(トランジション)
effect:テーマProgress
percentage:表示する値
format:書式
status:アイコン
text-inside:プログレスバー内部に値を表示
stroke-width:プログレスバーの縦幅
color:色
type:タイプPagination
layout:ページネーションのレイアウト(表示方法)
total:総データ件数
page-size:1ページあたりのデータ件数
pager-count:ページネーションを折りたたむ
background:背景色
small:小さく表示
hide-on-single-page:ページネーションが1ページの場合に表示するかBadge
value:バッチに表示する数値。文字も指定可能
type:色
max:最大値。指定した数値と+記号が表示される
is-dot:赤いドット表示Notice
Alert
type:色
title:タイトル
description:説明
effect:テーマ
closable:閉じるボタンを許容するか
close-text:閉じるボタンのテキスト
show-icon:アイコン
center:中央揃えLoading
v-loading:trueの場合、記載したタグに対してローディングを表示
element-loading-text:テキスト
element-loading-spinner:アイコン
element-loading-background:背景色Message
this.$message:メッセージ表示
type:色
showClose:閉じるアイコン
center:中央揃え
dangerouslyUseHTMLString:HTMLタグを利用MessageBox
type:メッセージ種類
confirmButtonText:OKボタンテキスト
cancelButtonText:キャンセルボタンテキスト
showCancelButton:キャンセルボタンを表示
inputPattern:入力確認用の正規表現
inputErrorMessage:入力エラー時のテキスト
dangerouslyUseHTMLString:HTMLタグを利用
distinguishCancelAndClose:キャンセル、クローズを区別
center:中央揃えNotification
title:タイトル
message:メッセージ
duration:表示する時間
type:種類
position:表示位置
offset:オフセット
dangerouslyUseHTMLString:HTMLタグを利用
showClose:閉じるアイコンを表示しないNavigation
NavMenu
default-active:デフォルト選択
mode:表示モード
background-color:背景色
text-color:文字色
active-text-color:アクティブメニューの文字色
disabled:無効
collapse:展開/閉じるTabs
label:表示テキスト
name:名前
type:表示モード
tab-position:表示位置
editable:タブ追加・削除Breadcrumb
separator:セパレータ文字
separetor-class:セパレータアイコンDropdown
split-button:スプリットボタン
type:色
disabled:無効
trigger:トリガー
command:コマンド
size:サイズSteps
active:位置
finish-status:終わった際のステータス
space:スペース
align-center:中央揃え
title:タイトル
description:説明
icon:アイコン
direction:表示モード
simple:シンプル表示Others
Dialog
visible.sync:ダイアログ表示有無
before-close:閉じるボタン、ダイアログ外の領域をクリックした際の処理
center:中央揃えTooltip
content:表示するテキスト
placement:表示位置
effect:色
disabled:無効Popover
placement:表示位置
title:タイトル
content:本文
trigger:表示方法Card
header:タイトルセクション
body-style:本文セクションのスタイル
shadow:影Carousel
height:カルーセルの高さ
trigger:表示切り替えトリガー
interval:表示切り替え間隔
indicator-position:インジケーターの表示位置
arrow:矢印表示
type:表示タイプ
direction:表示方向Collapse
accordion:アコーディオン表示Timeline
reverse:並び順
timestamp:表示する文字列
icon:アイコン
type:色
color:色
size:サイズ
placement:表示位置Divider
direction:方向
content-position:コンテンツの表示位置Calendar
range:表示範囲
first-day-of-week:週の最初の曜日Image
src:画像ソース
fit:コンテナに合わせる画像サイズ
placeholder(slot):読み込み中の表示
error(slot):読み込みエラーの表示
lazy:遅延読み込み
preview-src-list:プレビュー表示Backtop
visibility-height:表示を開始する位置
right:右からの距離
bottom:下からの距離Avatar
src:画像サイズ
size:大きさ
icon:アイコンDrawer
visible.sync:表示有無
direction:表示する方向
before-close:ドロワーを閉じる前の処理
- 投稿日:2019-08-27T19:56:34+09:00
Laravel + Blade + Vue.jsで、Vue.jsのコンポーネントの属性に渡す変数が正しくエスケープされていないとエラーが出る
環境と背景事情
- LaravelでVue.jsを使用している(セットアップはこのページを参考にしました)
- bladeテンプレート内に、直接Vue.jsのマークアップを表記している。
- 上記のbladeテンプレには、Vue.jsコンポーネントを使用しており、属性でテキストデータを渡している。
- 上記のコンポーネントで、ユーザが入力したテキストデータを表示させている。
問題
ユーザが入力データに引用符やHTMLコードを用いると、Vue.jsのページのコンパイル時にエラーが発生して、ページが表示されない。
解決策
Vue.jsコンポーネントのテキストデータを渡す属性値に、PHP関数の"json_encode"を用いてエンコードした。
エラー表示例
[Vue warn]: Error compiling template:HTMLコードをそのままコピペした場合:
avoid using JavaScript keyword as property name: "if"引用符が混じっているテキスト:
invalid expression: Invalid or unexpected token inその他:
invalid expression: Unexpected number ininvalid expression: Unexpected string in問題があったコード例
bladeテンプレートに記述されたVue.jsのマークアップ
<project-list-items :title="{{ $project->title }}" :description="{{$project->description }}" />エンコードも何もせずにそのまま値を渡している。
問題解決後のコード例
json_encodeを用いてエンコードした。
<project-list-items :title="{{ json_encode($project->title) }}" :description="{{ json_encode($project->description) }}" />
- 投稿日:2019-08-27T19:51:09+09:00
Rails & Nuxt.jsのDocker環境をalpineイメージで構築
Ruby on Rails、Nuxt.js、MySQLのDocker環境を作成します。
Rails、Nuxtのalpine環境の構築手順はそれぞれだと多くあるのですが、まとまったものがあまりない見つからなかったので、復習を兼ねてポストを作成します。準備
ディレクトリ作成
作業ディレクトリは任意です。
$ NEW_APP=rails-nuxt-app #任意のアプリ名 $ mkdir ${NEW_APP} $ cd ${NEW_APP} $ mkdir ./backend ./frontend
backendはRails用、frontendはNuxt用のディレクトリです。
まずは下記のファイルを修正していきます。. ├ backend │ ├ Dockerfile │ ├ Gemfile │ └ Gemfile.lock │ ├ frontend │ └ Dockerfile │ ├ docker-compose.yml └ .envdocker-compose.yml
.envdocker-compose.ymlで参照する環境変数を記載します。
ここではMySQLのrootパスワード、RailsおよびNuxt環境のホスト、ポート番号のみ定義します。
RailsとNuxtは、共にデフォルトのポートが3000番なので、後の利便性のためにいずれかを変えておきます。
(本記事ではNuxt側を8080に変更)MYSQL_ROOT_PASSWORD=password BACKEND_HOST=0.0.0.0 BACKEND_PORT=3000 FRONTEND_HOST=0.0.0.0 FRONTEND_PORT=8080
./docker-compose.yml.envで定義した変数を参照しています。
docker-compose.ymlのenvironment、 DockerfileのENVで同じ環境変数が定義されていた場合は、前者が使用されます。
(本記事ではDockerfile単体でもイメージ作成できるように環境変数の記載を残していますが、docker-compose.ymlに定義されていれば問題ありません)下記はDockerボリュームを作成します。
- mysqlのdatadir
- rubyのgem_home
- nodeのnode_modules
docker-compose.ymlversion: '3' services: db: image: mysql:5.7.27 restart: always volumes: - db-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} backend: build: ./backend ports: - ${BACKEND_PORT}:3000 command: /bin/sh -c "rm -f /app/tmp/pids/server.pid && bundle exec rails s -b ${BACKEND_HOST}" volumes: - ./backend:/app - backend-bundle:/usr/local/bundle environment: - HOST=${BACKEND_HOST} - PORT=${BACKEND_PORT} depends_on: - db tty: true stdin_open: true frontend: build: ./frontend ports: - ${FRONTEND_PORT}:8080 command: /bin/sh -c "yarn dev" volumes: - ./frontend:/app - frontend-node_modules:/app/node_modules environment: - HOST=${FRONTEND_HOST} - PORT=${FRONTEND_PORT} tty: true volumes: db-data: backend-bundle: frontend-node_modules:backend
Rails環境構築のためのファイルを準備します。
./backend/GemfileRailsのバージョンのみ指定しておきます。
Gemfilesource 'https://rubygems.org' gem 'rails', '5.2.3'
./backend/Gemfile.lock空ファイルをtouchしておけばOKです。
./backend/DockerfileAlpine Linuxのパッケージは最低限のものだけインストールします。
開発を進めるうちにgemのインストールで依存エラーが発生した場合には、不足パッケージを都度追加しましょう。DockerfileFROM ruby:2.6.3-alpine ENV RUNTIME_PACKAGES "mysql-client mysql-dev tzdata nodejs" ENV DEV_PACKAGES "build-base curl-dev" ENV APP_HOME /app ENV TZ Asia/Tokyo ENV HOST 0.0.0.0 ENV PORT 3000 WORKDIR ${APP_HOME} ADD Gemfile ${APP_HOME}/Gemfile ADD Gemfile.lock ${APP_HOME}/Gemfile.lock RUN apk update \ && apk upgrade \ && apk add --update --no-cache ${RUNTIME_PACKAGES} \ && apk add --update --no-cache --virtual=.build-dependencies ${DEV_PACKAGES} \ && bundle install -j4 \ && rm -rf /usr/local/bundle/cache/*.gem \ && find /usr/local/bundle/gems/ -name "*.c" -delete \ && find /usr/local/bundle/gems/ -name "*.o" -delete \ && apk del --purge .build-dependencies \ && rm -rf /var/cache/apk/* COPY . ${APP_HOME} EXPOSE ${PORT} CMD ["rails", "server", "-b", ${HOST}]frontend
./frontend/DockerfileDockerfileFROM node:12.9.0-alpine ENV APP_HOME /app ENV PATH ${APP_HOME}/node_modules/.bin:$PATH ENV TZ Asia/Tokyo ENV HOST 0.0.0.0 ENV PORT 8080 WORKDIR ${APP_HOME} ADD . ${APP_HOME} RUN apk update \ && apk upgrade \ && yarn install \ && rm -rf /var/cache/apk/* EXPOSE ${PORT} CMD ["yarn", "dev"]アプリケーション作成
Rails、Nuxt環境にプロジェクトを作成します。
docker-compose runを実行したタイミングで、それぞれのDockerイメージがbuildされ、さらにコンテナが立ち上がります。
--no-deps... docker-compose.ymlでdepends_onorlinks指定するサービスは起動しない。
--rm... 処理を終えたコンテナを自動的に削除。backend
アプリケーション作成
rails newでRailsアプリケーションを作成します。
--apiオプションでAPIモードにしていますが、不要な方は外してください。$ docker-compose run --no-deps --rm backend rails new . --force --api --database=mysql --skip-bundleDB接続のため、下記のファイルを修正します。
. └ backend ├ config │ └ database.yml ├ Gemfile └ .env
./backend/.envdocker-compose.ymlで参照している
MYSQL_ROOT_PASSWORDと同じもの設定します。MYSQL_ROOT_PASSWORD=password
./backend/Gemfile.envから環境変数を読み込むdotenv-railsというgemを追加します。
Gemfile~~省略~~ group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem "dotenv-rails" #追加 end ~~省略~~
./backend/config/database.ymlDBへのアクセスに使用するパスワードを、環境変数から取得します。
database.yml~~省略~~ default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: <%= ENV.fetch("MYSQL_ROOT_PASSWORD") { '' } %> #環境変数を参照するように修正 host: db #localhostからdocker-compose.ymlのサービス名に修正 ~~省略~~frontend
アプリケーション作成
npxでNuxtアプリケーションを作成します。
後から追加/変更できるので、このタイミングではEnterキー連打でOKです。$ docker-compose run --rm frontend npx create-nuxt-app . ~~省略~~ create-nuxt-app v2.10.0 ✨ Generating Nuxt.js project in . ? Project name #アプリ名 <Enter> ? Project description #任意 <Enter> ? Author name #任意 <Enter> ? Choose the package manager #Yarn <Enter> ? Choose UI framework #None <Enter> ? Choose custom server framework #None <Enter> ? Choose Nuxt.js modules #(Nothing) <Enter> ? Choose linting tools #(Nothing) <Enter> ? Choose test framework #None <Enter> ? Choose rendering mode #Universal (SSR) <Enter> ? Choose development tools #(Nothing) <Enter>Dockerイメージ作成
アプリケーション作成時にできたDockerボリュームは削除しておきます。
$ docker-compose down --volume # もしくは docker volume rm ボリューム名各ファイルを修正した状態で、Dockerイメージをビルドします。
$ docker-compose builddocker-compose.ymlで
buildを指定しているbackendとfrontendのイメージが作成されたことを確認します。$ docker images --format "{{.Repository}}\t{{.CreatedSince}}" ${NEW_APP}* rails-nuxt-app_frontend About a minutes ago rails-nuxt-app_backend About a minutes agoHello World
最後にDockerコンテナを起動し、Rails、NuxtアプリケーションのHelloWorldを確認します、
docker-compose.ymlで定義したサービスを
-dオプション(デタッチモード)でバックグラウンド起動します。$ docker-compose up -dプロセスが立ち上がっていることを確認します。
$ docker-compose ps Name Command State Ports --------------------------------------------------------------------------------------- rails-nuxt-app_backend_1 /bin/sh -c rm -f /app/tmp/ ... Up 0.0.0.0:3000->3000/tcp rails-nuxt-app_db_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp rails-nuxt-app_frontend_1 docker-entrypoint.sh /bin/ ... Up 0.0.0.0:8080->8080/tcp失敗している場合は
docker-compose logsなどで原因を探りましょう。backend
RailsアプリケーションのDBを作成します。
$ docker-compose exec backend rails db:create Created database 'app_development' Created database 'app_test'ブラウザで http://localhost:3000/ を開きます。
frontend
ブラウザで http://localhost:8080/ を開きます。
お疲れさまでした。
次回は GraphQL の導入について投稿したいと思います。
- 投稿日:2019-08-27T19:35:27+09:00
Vue.jsとCSSアニメーションでラーメンタイマーを作る + Firebaseで簡単公開
学びたてだけどVue.js + CSSアニメーション + 絵を組み合わせて作ってみたい!
という事でシンプルなカップラーメンのタイマーを作ってみました。基本的なVue.jsで始めたばかりの方でも比較的読み進めやすいと思います。
話題のFirebaseで無料公開もとても簡単だったので方法をまとめました。? ラーメンタイマー
・アプリURL
https://cupramen-timer.firebaseapp.com/
・GitHub - ソースコード
https://github.com/aocattleya/Ramen_Timer
(いいねやスター貰えるととても喜びます!)
アプリの内容
使用している物 説明 HTML, CSS animationプロパティを使用 Vue.js JavaScriptフレームワーク Firebase 無料枠でアプリを公開する --- --- SweetAlert アラートを簡単にデザインするライブラリ GoogleFonts フォントの変更 FireAlpaca ペイントツール(無料)
3分 or 5分のボタンをホバーするとキャラクターが左右に振り向きます。
時間を選びクリックするとカウントダウンタイマーが使える簡単な内容です。
レスポンシブデザイン(スマホ)にも対応しています。※左右の振り向きはしない
キャラクターデザイン
まず一番目立つキャラクター
自分は元々漫画家のアシスタントをしていた時期などがあり、
描いた物をアプリに組み合わせてみたかったので描き描き。
レイヤーといって何枚もの板が重なっているように描かれています。
なので例えば手を消すと下に隠れている髪が出てきます。
これによって一枚描いたら背景などが簡単に変更でき、左右反転させて手を描けば2枚完成。※猫の方が万人受けする。名前募集中!
こちらに原寸サイズ画像&レイヤーファイルを公開しています。
illustration-Original_Characters(GitHub)
? コードの解説
それぞれ分けて解説していきます。
コードは分かりやすいように関係ない部分を大幅に省略して書いてます。
・キャラクターを左右に振り向かせる
1行目、
v-bind:class=""によってclassを「右顔CSS」⇔「左顔CSS」と書き替えており、
きっかけは、それぞれの3分と5分ボタンにあるv-on:mouseover=""index.html<!-- キャラクター --> <img v-bind:class="{ right_face: isRight, left_face: isLeft }" /> <div class="pick-button"> <!-- 3分ボタン --> <input type="image" src="img/3min.png" v-on:mouseover="rotate_left" /> <!-- 5分ボタン --> <input type="image" src="img/5min.png" v-on:mouseover="rotate_right" /> </div> </div>
JavaScript側では下記のようにボタンをホバーした時に、
「true」⇔「false」で切り替わる処理を書いています。main.jsconst vm = new Vue({ el: "#app", data: { isLeft: false, isRight: true, }, methods: { rotate_left: function() { this.isLeft = true; this.isRight = false; }, rotate_right: function() { this.isLeft = false; this.isRight = true; } } });
右顔のCSSアニメーションstyle.css.right_face { border-radius: 50%; background-image: url(../img/button_right.png); animation: anime 0.4s linear 2; } @keyframes anime { 100% { transform: rotateY(360deg); } }・
border-radius: 50%で画像を丸くする。
・そしてanimationプロパティ、長さなどを設定でき@keyframesで動きを付けます。
上記は100%終了時までにY軸に360度回転としています。
・ボタン選択で画面の切り替え
ページは変わっていません。
Vue.jsで最初の画面を非表示にし、非表示になっていたタイマー画面を表示させています。
3分 or 5分ボタンを押すと
v-on:click="show = !show"によって、
<div v-show="!show">⇔<div v-show="show">と画面表示が切り替わります。index.html<!-- 3分 or 5分ボタン選択画面 --> <div v-show="!show"> <input type="image" src="img/3min.png" v-on:click="show = !show" /> <input type="image" src="img/5min.png" v-on:click="show = !show" /> </div> <!-- タイマー画面 --> <div v-show="show"> <span id="minutes">{{ minutes }}</span> <span id="middle">:</span> <span id="seconds">{{ seconds }}</span> <!-- 省略 --> </div>
・タイマーの実装
index.html<!-- 3分 or 5分ボタン --> <input type="image" src="img/3min.png" v-on:click="show = !show; threeMin()" /> <input type="image" src="img/5min.png" v-on:click="show = !show; fiveMin()" />3分 or 5分ボタンをクリックした時に、
v-on:click="threeMin()"又はv-on:click="fiveMin()"が実行され、
タイマー画面でカウントする時間を3:00 or 5:00にします。
index.html<!-- タイマー --> <div class="timer"> <span id="minutes">{{ minutes }}</span> <span id="middle">:</span> <span id="seconds">{{ seconds }}</span> </div> <div id="buttons"> <!-- スタート --> <input type="image" src="img/start.png" v-on:click="startTimer" v-if="!timer" /> <!-- ストップ --> <input type="image" src="img/stop.png" v-on:click="stopTimer" v-if="timer" /> <!-- リセット --> <input type="image" src="img/reset.png" v-on:click="resetTimer" v-if="resetButton" /> </div>タイマーのカウントは、HTMLの
{{ minutes }} : {{ seconds }}
この部分がVue.jsの処理でタイマーのように変更されていきます。
main.jsconst vm = new Vue({ el: "#app", data: { timer: null, pickTime: null, totalTime: null, resetButton: false }, methods: { // 3分 or 5分ボタン threeMin: function() { this.pickTime = 3 * 60; this.totalTime = this.pickTime; }, fiveMin: function() { this.pickTime = 5 * 60; this.totalTime = this.pickTime; }, // スタート startTimer: function() { this.timer = setInterval(() => this.countdown(), 1000); this.resetButton = true; }, // ストップ stopTimer: function() { clearInterval(this.timer); this.timer = null; this.resetButton = true; }, // リセット resetTimer: function() { this.totalTime = this.pickTime; clearInterval(this.timer); this.timer = null; this.resetButton = false; }, // 秒が一桁の場合0を追加 padTime: function(time) { return (time < 10 ? "0" : "") + time; }, // カウントダウン countdown: function() { if (this.totalTime >= 1) { this.totalTime--; } else { this.totalTime = 0; this.resetTimer(); swal("Complete!!", "", "success"); } } }, computed: { // タイマーの数値 minutes: function() { const minutes = Math.floor(this.totalTime / 60); return minutes; }, seconds: function() { const seconds = this.totalTime - this.minutes * 60; return this.padTime(seconds); } } });
computed:の部分がHTMLのタイマー{{ }}に表示され、ボタンで各methods:が働き、
スタートを押すとsetInterval()により、一秒ごとにcountdownが実行されます。
・アラートデザイン『SweetAlert』
簡単にアラートがデザイン出来るライブラリ
ブラウザからCDN経由で読み込みができます。index.html<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>main.jsswal("Complete!!", "", "success");これだけ、凄い!
このアラートはスマホでも同じデザインで表示されます。その他の使い方は下記のページが分かりやすいです。
- SweetAlertバージョン2を使ったデモ
? Firebaseで公開(無料)
Firebase - Google
最近とても話題のFirebaseで、作成したアプリを無料で公開。
データベースなど複雑に使う事も可能ですが、今回は簡単に無料で公開してみます。下記はQiita用に
testプロジェクトで進めていますが、任意の名前にしてください。1、ログイン
Firebaseのページを開いてログイン2、プロジェクトの作成
プロジェクト名を記入します。
IDの部分はURLになりますので好みのIDに書き変えましょう。Googleアナリティクスの設定を聞かれます。
今回は、使用しないで進めます。3、フォルダの設定
Desktopにプロジェクト名と同じフォルダを作成します。
中にpublicという名前でフォルダを作成して公開したいコードを入れます。
4、Node.jsのインストール
まだ入ってない方はインストールしてください。
すぐ終わります。5、firebase-toolsをインストール
npm install -g firebase-tools6、ログイン
firebase login利用状況のデータを送っても良いか聞かれたら任意でY/n
次にGoogleログイン画面が表示されるので、アカウントを選び進めます。7、デプロイ設定
cd Desktop/testプロジェクトのフォルダに移動します。
firebase init◉ Hosting: Configure and deploy Firebase Hosting sites
Hostingをスペースで選択してからEnterを押します。
※スペースで選択していなとエラーとなる。? Please select an option:
Don't set up a default projectを選択してEnter? What do you want to use as your public directory?(public)そのままEnter(デフォルトの
publicとなる)? Configure as a single-page app (rewrite all urls to /index.html)? (y/N)そのままEnter(デフォルトでN)
? File public/index.html already exists. Overwrite? (y/N)index.htmlを上書きしていいか聞いてくるのでN(そのままEnterでN)
8、公開する
firebase use --add上記でEnter
? Which project do you want to add? > test-71a0e作成したプロジェクトを選択します。
? What alias do you want to use for this project? (e.g. staging)名前は任意です。今回は
stagingとしました。firebase deployこうして完成、簡単にFirebaseでの公開も出来ました。使ってね!
・ラーメンタイマー
https://cupramen-timer.firebaseapp.com/
・ソースコード - GitHub
https://github.com/aocattleya/Ramen_Timer
終わりに
Vue.jsで何か作ってみたい、CSSアニメーションと絵も組み合わせたい!
そんな考えから作ってみたアプリでシンプルに見えて苦戦もありました。
しかし言語を学習してるだけと違い、新たな発見と理解はとても多かったです。
基本的な構文でここまで作れて達成感も大きかったのでやって凄く良かったと思います。次はさらにレベルを上げて作ってみたいですね!
最後まで読んでくれてありがとうございました。
参考
・【CSS3】@keyframes と animation 関連のまとめ
・SweetAlertバージョン2を使ったデモ
・Firebaseを用いて5分でセキュアなWebサイトを公開するリンク
GitHub
https://github.com/aocattleya
https://twitter.com/aocattleya
? Qiita
https://qiita.com/aocattleya
- 投稿日:2019-08-27T19:35:27+09:00
Vue.jsとCSSアニメーションでラーメンタイマーを作った + Firebaseで簡単公開
Vue.jsを学び始めてCSSアニメーションも触ってみたいという事で簡単なアプリを作ってみました。
基本的なVue.jsの機能で始めたばかりの方でも比較的に読み進めやすいかと思います。
話題のFirebaseでの無料公開もとても簡単なので方法をまとめました。? ラーメンタイマー
・アプリURL
https://cupramen-timer.firebaseapp.com/
・GitHub - ソースコード
https://github.com/aocattleya/Ramen_Timer
(いいねやスター貰えるととても喜びます!)
アプリの内容
使用している物 説明 HTML, CSS animationプロパティを使用 Vue.js JavaScriptフレームワーク Firebase 無料枠でアプリを公開する --- --- SweetAlert アラートを簡単にデザインするライブラリ GoogleFonts フォントの変更 FireAlpaca ペイントツール(無料)
3分 or 5分のボタンをホバーするとキャラクターが左右に振り向きます。
時間を選びクリックするとカウントダウンタイマーが使える簡単な内容です。
レスポンシブデザイン(スマホ)にも対応しています。※左右の振り向きはしない
キャラクターデザイン
まず一番目立つキャラクター
自分は元々漫画家のアシスタントをしていた時期などがあり、
描いた物をアプリに組み合わせてみたかったので描き描き。
レイヤーといって何枚もの板が重なっている感じで描かれています。
なので例えば手を消すと下に隠れている髪が出てきます。
これによって一枚描いたら背景などが簡単に変更でき、左右反転させて手を描けば2枚完成。※猫の方が万人受けする。名前募集中!
こちらに原寸サイズ画像&レイヤーファイルを公開しています。
illustration-Original_Characters(GitHub)
? コードの解説
それぞれ分けて解説していきます。
コードは分かりやすいように関係ない部分を大幅に省略して書いてます。
・キャラクターを左右に振り向かせる
1行目、
v-bind:class=""によってclassを「右顔CSS」⇔「左顔CSS」と書き替えており、
きっかけは、それぞれの3分と5分ボタンにあるv-on:mouseover=""index.html<!-- キャラクター --> <img v-bind:class="{ right_face: isRight, left_face: isLeft }" /> <div class="pick-button"> <!-- 3分ボタン --> <input type="image" src="img/3min.png" v-on:mouseover="rotate_left" /> <!-- 5分ボタン --> <input type="image" src="img/5min.png" v-on:mouseover="rotate_right" /> </div> </div>
JavaScript側では下記のようにボタンをホバーした時に、
「true」⇔「false」で切り替わる処理を書いています。main.jsconst vm = new Vue({ el: "#app", data: { isLeft: false, isRight: true, }, methods: { rotate_left: function() { this.isLeft = true; this.isRight = false; }, rotate_right: function() { this.isLeft = false; this.isRight = true; } } });
右顔のCSSアニメーションstyle.css.right_face { border-radius: 50%; background-image: url(../img/button_right.png); animation: anime 0.4s linear 2; } @keyframes anime { 100% { transform: rotateY(360deg); } }・
border-radius: 50%で画像を丸くする。
・そしてanimationプロパティ、長さなどを設定でき@keyframesで動きを付けます。
上記は100%終了時までにY軸に360度回転としています。
・ボタン選択で画面の切り替え
ページは変わっていません。
Vue.jsで最初の画面を非表示にし、非表示になっていたタイマー画面を表示させています。
3分 or 5分ボタンを押すと
v-on:click="show = !show"によって、
<div v-show="!show">⇔<div v-show="show">と画面表示が切り替わります。index.html<!-- 3分 or 5分ボタン選択画面 --> <div v-show="!show"> <input type="image" src="img/3min.png" v-on:click="show = !show" /> <input type="image" src="img/5min.png" v-on:click="show = !show" /> </div> <!-- タイマー画面 --> <div v-show="show"> <span id="minutes">{{ minutes }}</span> <span id="middle">:</span> <span id="seconds">{{ seconds }}</span> <!-- 省略 --> </div>
・タイマーの実装
index.html<!-- 3分 or 5分ボタン --> <input type="image" src="img/3min.png" v-on:click="show = !show; threeMin()" /> <input type="image" src="img/5min.png" v-on:click="show = !show; fiveMin()" />3分 or 5分ボタンをクリックした時に、
v-on:click="threeMin()"又はv-on:click="fiveMin()"が実行され、
タイマー画面でカウントする時間を3:00 or 5:00にします。
index.html<!-- タイマー --> <div class="timer"> <span id="minutes">{{ minutes }}</span> <span id="middle">:</span> <span id="seconds">{{ seconds }}</span> </div> <div id="buttons"> <!-- スタート --> <input type="image" src="img/start.png" v-on:click="startTimer" v-if="!timer" /> <!-- ストップ --> <input type="image" src="img/stop.png" v-on:click="stopTimer" v-if="timer" /> <!-- リセット --> <input type="image" src="img/reset.png" v-on:click="resetTimer" v-if="resetButton" /> </div>タイマーのカウントは、HTMLの
{{ minutes }} : {{ seconds }}
この部分がVue.jsの処理でタイマーのように変更されていきます。
main.jsconst vm = new Vue({ el: "#app", data: { timer: null, pickTime: null, totalTime: null, resetButton: false }, methods: { // 3分 or 5分ボタン threeMin: function() { this.pickTime = 3 * 60; this.totalTime = this.pickTime; }, fiveMin: function() { this.pickTime = 5 * 60; this.totalTime = this.pickTime; }, // スタート startTimer: function() { this.timer = setInterval(() => this.countdown(), 1000); this.resetButton = true; }, // ストップ stopTimer: function() { clearInterval(this.timer); this.timer = null; this.resetButton = true; }, // リセット resetTimer: function() { this.totalTime = this.pickTime; clearInterval(this.timer); this.timer = null; this.resetButton = false; }, // 秒が一桁の場合0を追加 padTime: function(time) { return (time < 10 ? "0" : "") + time; }, // カウントダウン countdown: function() { if (this.totalTime >= 1) { this.totalTime--; } else { this.totalTime = 0; this.resetTimer(); swal("Complete!!", "", "success"); } } }, computed: { // タイマーの数値 minutes: function() { const minutes = Math.floor(this.totalTime / 60); return minutes; }, seconds: function() { const seconds = this.totalTime - this.minutes * 60; return this.padTime(seconds); } } });
computed:の部分がHTMLのタイマー{{ }}に表示され、ボタンで各methods:が働き、
スタートを押すとsetInterval()により、一秒ごとにcountdownが実行されます。
・アラートデザイン『SweetAlert』
簡単にアラートがデザイン出来るライブラリ
ブラウザからCDN経由で読み込みができます。index.html<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>main.jsswal("Complete!!", "", "success");これだけ、凄い!
このアラートはスマホでも同じデザインで表示されます。その他の使い方は下記のページが分かりやすいです。
- SweetAlertバージョン2を使ったデモ
? Firebaseで公開(無料)
Firebase - Google
最近とても話題のFirebaseで、作成したアプリを無料で公開。
データベースなど複雑に使う事も可能ですが、今回は簡単に無料で公開してみます。下記はQiita用に
testプロジェクトで進めていますが、任意の名前にしてください。1、ログイン
Firebaseのページを開いてログイン2、プロジェクトの作成
プロジェクト名を記入します。
IDの部分はURLになりますので好みのIDに書き変えましょう。Googleアナリティクスの設定を聞かれます。
今回は、使用しないで進めます。3、フォルダの設定
Desktopにプロジェクト名と同じフォルダを作成します。
中にpublicという名前でフォルダを作成して公開したいコードを入れます。
4、Node.jsのインストール
まだ入ってない方はインストールしてください。
すぐ終わります。5、firebase-toolsをインストール
npm install -g firebase-tools6、ログイン
firebase login利用状況のデータを送っても良いか聞かれたら任意でY/n
次にGoogleログイン画面が表示されるので、アカウントを選び進めます。6、デプロイ設定
cd Desktop/testプロジェクトのフォルダに移動します。
firebase init◉ Hosting: Configure and deploy Firebase Hosting sites
Hostingをスペースで選択してからEnterを押します。
※スペースで選択していなとエラーとなる。? Please select an option:
Don't set up a default projectを選択してEnter? What do you want to use as your public directory?(public)そのままEnter(デフォルトの
publicとなる)? Configure as a single-page app (rewrite all urls to /index.html)? (y/N)そのままEnter(デフォルトでN)
? File public/index.html already exists. Overwrite? (y/N)index.htmlを上書きしていいか聞いてくるのでN(そのままEnterでN)
・公開する
firebase use --add上記でEnter
? Which project do you want to add? > test-71a0e作成したプロジェクトを選択します。
? What alias do you want to use for this project? (e.g. staging)名前は任意です。今回は
stagingとしました。firebase deployこうして完成、簡単にFirebaseでの公開も出来ました。使ってね!
・ラーメンタイマー
https://cupramen-timer.firebaseapp.com/
・ソースコード - GitHub
https://github.com/aocattleya/Ramen_Timer
終わりに
まだVue.js学びたてだけど何か作ってみたい
CSSアニメーションも使って絵も描いて組み合わせたい!そんな考えから簡単に作ってみたアプリでシンプルに見えて苦戦もありました。
しかし言語を学習してるだけと違い、新たな発見と理解はとても多かったです。
基本的な構文でここまで作れて達成感も大きかったので凄くやって良かったと思います。次はさらにレベルを上げて作ってみたいですね!
最後まで読んでくれてありがとうございました。
参考
・【CSS3】@keyframes と animation 関連のまとめ
・SweetAlertバージョン2を使ったデモ
・Firebaseを用いて5分でセキュアなWebサイトを公開するリンク
GitHub
https://github.com/aocattleya
https://twitter.com/aocattleya
? Qiita
https://qiita.com/aocattleya
- 投稿日:2019-08-27T18:25:02+09:00
Vue.jsのvue.config.jsを使って環境変数を別けるやり方
developmentとproductionで分けたかったので自分用にメモです
STEP1
こんな感じででpackage.jsonのコマンドにmodeを追加する。
npm run pとやるとデフォルトで--mode productionとなります。STEP2
プロジェクトの直下に
.env.development
.env.production
といったファイルを作る。STEP3
中身を書く。
この時命名のルールがあり
VUE_APP_hogehogehogeとしなければならない。(でないとundefinedとなってしまいます。)STEP4
npm run xxxx でもう一度立ち上げなおす。
ちなみに話は全然変わるけどSourceマップの出し分けはこうする
module.exports = { productionSourceMap: process.env.NODE_ENV === 'production'? false :true, } // この時の process.env.NODE_ENV は package.jsonのコマンドの --mode xxxxxx を自動的に読み込んでくれる。
- 投稿日:2019-08-27T11:50:18+09:00
vue.js テキストエリア伸ばす
テキストエリアを文字数に応じて自動で伸ばす。
ちゃんとコンポーネントも読み出す。今回は element ui を使う。
一般的なテキストエリアとは違うので注意。top.vue<el-form-item label="無料占いの内容" prop="message"> <TextareaResizeComponent v-model="form.message" placeholder="ここにサンプル" name="message" ></TextareaResizeComponent> <!--<el-input type="textarea" v-model="form.message" :rows=5></el-input>--> </el-form-item> ・・・略 <script> import TextareaResizeComponent from "./TextareaResizeComponent"; export default { components: {TextareaResizeComponent}, data() { form: { message:'' }, </script>テキストエリアリサイズコンポーネント
TextareaResizeComponent.vue<template> <el-input :name="name" :value="value" :placeholder="placeholder" :rows="rows" type="textarea" @input="updateValue" ></el-input> </template> <script> export default { name: "TextareaResizeComponent", props: { value: { type: String, require: true }, name: { type: String, require: true }, placeholder: { type: String, require: false }, cols: { type: Number, require: false } }, computed: { rows: function() { var num = this.value.split('\n').length; return (num > 10) ? num : 10; } }, methods: { updateValue: function(e) { //普通のテキストエリアと違うので注意 this.$emit("input", e); } } }; </script>
- 投稿日:2019-08-27T09:57:24+09:00
次世代キーボード Tap Strap を買ったので使い方を練習するサイトを作った
先日、何かの拍子に Tap Strap というキーボードを知りました。
メリケンサックのように指にはめるタイプのキーボードです。キーボードを指にはめて、ピアノを引くときのように決められた組み合わせで指を軽くタップすると、文字が打てるというものです。
このキーボード、片手だけで文字や数字を打ち込めるのでとても便利なのですが、指の使い方を覚えるのが大変です。
アルファベットの指の使い方はこんな感じ。
oがタップする指、xがタップしない指です。{ a: 'oxxxx', b: 'xoxxo', c: 'oxooo', d: 'oxoxx', e: 'xoxxx', f: 'ooxox', g: 'oxoox', h: 'xoooo', i: 'xxoxx', j: 'oooxo', k: 'oxxox', l: 'xxoox', m: 'xoxox', n: 'ooxxx', o: 'xxxox', p: 'ooxxo', q: 'xooxo', r: 'oooox', s: 'xxxoo', t: 'xooxx', u: 'xxxxo', v: 'ooxoo', w: 'oxoxo', x: 'xoxoo', y: 'oxxxo', z: 'xxoxo'//, bs: 'xooox', enter: 'oxxoo' }なかなか複雑です。。。
公式でもその問題は認識しているらしく、Tap Academyという練習アプリがリリースされています。
が。初めて使う人にとっては難易度が高い。。ということで、自分で作ってみました。
見た目は残念な感じですが、一応ちゃんと動きます。レポジトリ
https://github.com/gorogoroyasu/tap-strap-practice
作ったサイト
https://gorogoroyasu.github.io/tap-strap-practice/single/見た目
間違えたとき
3回間違えたらヒントを出す!
機能としては、上述した程度のものしかありません。
今の所、
1. Question を出す。
2. 正解だったら次の問題へ。間違いだったら、何と何を間違えたのかを出す
3. 3回以上間違えたらhintと称した答えを出す
という感じです。あと、割とえげつないのが、問題が無限ループしていること。
この辺は、ちょこちょこいい感じに直していこうと思います。Vue.js
殆ど使ったことはないですが、使ってみました。
難しかったのは、 form にフォーカスを当てるところでした。
ドキュメントに書いてたんですけどね。。
https://jp.vuejs.org/v2/guide/custom-directive.htmldirectives: { focus: { inserted: function (el) { el.focus() } } },そもそも ディレクティブ という機能を知らなかったので勉強になりました。
あと、body タグにid を振って
new Vue({ el: '#body', data: obj })という風にしようとしていたのですが、だめだよって怒られました。
苦肉の策で、<body> <div id='body'> </div> </body>という構成にして、逃げました。
たぶん、そもそもの使い方が違うんだと思います。
時間を見つけて正しい書き方に修正しようと思います。
あと、見た目がだいぶ悪いので、それもなんとかしようと思います。最後に
$200 と決して安くはないですが、もし購入される方がいらっしゃったら、このクーポンを使っていただけると。
10% off になるらしいです。I bought an interesting device. Use this code to get yours $10 off. /
— はまのや⊿ (@gorogoroyasu) August 11, 2019
Get $10 off when you order a Tap. Use coupon: REFYNFCACAREG at checkout to redeem offer https://t.co/uSlJrxjfbqEnjoy Tap Strap!
- 投稿日:2019-08-27T00:51:07+09:00
propsとdataの違い、propsについて
TL;DR
他の使い方もあるだろうけど、とりあえず大体以下じゃね?って解釈
- props
- 親コンポーネントから渡されるであろう値を自コンポーネントに定義しておくやつ
- data
- storeから取得されるデータの形など(を定義しておこう)
はじめに
vueの例は単一ファイルコンポーネントで記入します
また、propsとdataの比較記事かと思いきやほぼpropsの事しか話していません。
dataについては多分別記事で書くよ
多分propsについて
コンポーネントの基本 #プロパティを使用した子コンポーネントへのデータの受け渡し
親コンポーネントから子コンポーネントに値を渡す際に使用されるのがpropsです。
親コンポーネント
<Content title='`ほげ`' />子コンポーネント
<template> <div>{{ title }}</div> </template> export default { name: 'Content', props: ['title'] }注意1. propsの形式
上ではわかりやすさのためにただの文字列として渡しましたが、本当は以下の様にどの様な値が来るかまで書いておく方が好ましいです。
(Props should at least define its types)子コンポーネント
export default { name: 'Content', props: { title: { type: String, required: true } } }注意2. propsをHTMLの内容に渡す時と属性に渡す時
HTMLの内容に渡す時
<template> <div>{{ title }}</div> </template>子コンポーネント側で先ほどの様に{{}}波括弧を2つ書いたもの(”Mustache” 構文(二重中括弧))でくくればOK
HTMLの属性に渡す時
<template> <div :class="title">ここはベタ書き</div> </template>子コンポーネント側でv-bindを使用することで渡されたprops要素が入り込む様になっている
注意3. 親コンポーネントでの渡し方について
ベタ書きの時(あんまないと思うけど)
<Content title='`ほげ`' />親コンポーネント側でバッククオートで囲いながらベタ書きすればOK(当たり前のことを言っている人)
文字列として判断させたいため、バッククオートで囲うdataとかから取得する場合
v-forと交えながら書きます(コンポーネントに渡す時data使うなら大体v-for使うだろという仮定)
<template> ... <Content v-for="item in items" :key="item.id" :id="item.id" :content="item.content" :user-id="item.userId" /> </template> export default { data: function() { items: [ { id: 1, content: 'ぴよぴよ', userId: 3 }, { id: 2, content: 'わんわん', userId: 4 }, ] } }親コンポーネント側でこの様な記述をします。注意点は以下。
- :keyを絶対に入れなきゃいいけない(リストレンダリング #状態の維持)
- バッククオートはいらない(文字列じゃないから)
- user-idと渡しているものは子コンポーネント側ではuserIdとなってくれる(プロパティ #プロパティの形式)
dataについて
そのコンポーネントで使用するデータ(子コンポーネントに渡すものも含む)を定義しておく場所
多分大体storeとかから取得したデータが入ってる場所と考えるべき?(computedなどと併用して)注意点1. コンポーネントでのdataは関数にする
コンポーネントじゃなかったらオブジェクトでよかったですよね
Vue インスタンス #データとメソッド
最後に
mapStateを使ってstoreからデータを取得してほにゃらららへんはちょっとまだ勉強中なので、理解したら記事を書きます

























