- 投稿日:2020-06-26T21:40:42+09:00
コロナ禍を乗り切る!店内の人数をリアルタイムで分析するアプリ「Atsumaritai」
Atsumaritai の目的
https://atsumaritai.web.app/#/
ここから下に記載していることは、アプリの「使い方」ページに書いてあることをほぼコピペしているので、若干、説明調です。ご勘弁を。
本アプリは、スマホのカメラに写っている人の数をリアルタイムで分析することが可能です。そして、分析の結果をリアルタイムで公開することも可能です。
以下、本アプリの利用想定例です。
飲食店経営者のAさんは本アプリを使用して、店内の人数をリアルタイムで分析します。そして、その結果を自社HPで公開します。
Aさんの店によく行くBさんは、来店する前に店のHPを見て、店内のリアルタイムの人数を把握します。混んでいないことを確認して来店します。コロナ禍により、密を避けた行動が重要です。
店やジムのオーナーは、本アプリによって店内の人数をリアルタイムで公開することによって、
顧客は人が少ない時間を見計らって来店することができます。現時点(2020/06/23)では、本アプリの利用による料金の発生はありません。
必要なもの
WiFiに接続されている、あるいはSIMカードの入ったインターネットに接続可能なスマホ1台が必要です。前に使っていたが、今は使っていないスマホが手元にあればお使いください。
使い方
- 人数を分析したい方向にスマホを向ける
- 「スタート」を押して計測を開始
- 複数台のスマホで計測する場合は、同じアカウントでログインした状態で、「スタート」を押して計測を開始
- 埋め込みコード(このページ下部に記載)を自社HPに貼り付け、リアルタイムの人数を公開する
- 分析を終了するには「ストップ」を押す
本アプリの分析によって、顔や体などの個人が特定可能な写真の取得(サーバーへのアップロード)は行っておりません。本アプリによる分析結果である人数のみを取得しています。
また、本アプリの分析結果である人数は、あくまでも概算値としてご使用ください。
以下に当てはまる条件下では分析の精度が落ちる可能性があります。
- 暗い場所
- 人同士が重なっている
- 体の一部が隠れている
- 早い動作をしている
以下は、本アプリの制限事項です。
- 1台のカメラで計測可能な最大人数は30人
- 1台のカメラで計測可能な距離の目安は 20m 以内程度
- 複数台のスマホで計測する場合は、カメラに写っている範囲が重ならないようにする
自社サイトに分析結果を掲載する方法
本アプリでの分析結果を任意のサイトに埋め込むことが可能です。
以下のコードを、本アプリでの計測結果を表示したいサイトのbody
部分に埋め込んでください。<span id="covid"></span>以下のコードをサイトの
body
の直後に埋め込みます。このコードはログイン後にユーザー毎に生成されます。<script src="https://covid-3igou5xrgq-an.a.run.app/covid.js?uid=abcdefg123456789"></script>埋め込みコードをHPのデザインに合わせてカスタマイズ
css で埋め込むHPのデザインに合わせてカスタマイズしてください。下記は、冒頭に貼っているHPのキャプチャに埋め込んでいるコードです。
<div class="covid-div"> <p>現在店内に<span id="covid"></span>人います。</p> </div><style type="text/css"> #covid { color: indigo; } .covid-div { padding-top: 15px; margin-left: auto; margin-right: auto; width: 8em; text-align: center; background-color: rgba(255, 135, 30, 0.3); color: black; border-radius: 25px 25px; } </style>問い合わせ
問い合わせは以下までお願い致します。改善要望など何でもOKです。また、実際に使ってくれる店のオーナーの方、大募集しています。もし、使ってもいいよっていう方がいらっしゃれば、試験的な要素が強いので、HPの埋め込みなども積極的にお手伝いします!!!
まとめ
ピンときている方も多いと思いますが、サービス名は「サウナイキタイ」さんからインスパイアされています。開発者たちがサウナが好きすぎる、かつ、「サウナイキタイ」さんも好きなので、リスペクトの思いを込めたのと、コロナ禍が終わってまた皆で集まれる日を願い、Atsumaritai(集まりたい)にしました。
https://sauna-ikitai.com/
- 投稿日:2020-06-26T20:14:59+09:00
IndexedDB + Dexie.js で CRUDの作成、Vue CLI版
概要
IndexedDB で、Dexie.js ライブラリを使用した
CRUD の作成となります。
vue-router と組み合わせて、ほぼサーバレス的な構成にできるか検討してみました。・ブラウザ内の、LocalStorageと似ているイメージで
データは、他のPCから利用できない為。
オフライン機能で、何か作る場合は。良さそうでした・開発の面では、通常DBサービス起動も不要で
Vue-cli サービスのみで。開発できるので準備は楽でした
構成
Vue CLI
dexie : 3.0.1
vue: 2.6.11
vue-router参考
https://developer.mozilla.org/ja/docs/Web/API/IndexedDB_API
https://qiita.com/yamayamasan/items/a4297e724b86f4a00fd2
vuex 追加
npm install --save dexiepackage.json
https://github.com/kuc-arc-f/vue_spa3b_1crud/blob/master/package.json
実装など
・db定義
db-name, store ,db-version
storeは、テーブルみたいな扱いのようですvar db = new Dexie("friend_database"); db.version(1).stores({ friends: 'name,shoeSize' });・書く、読み込み
db.friends.put({name: "Nicolas", shoeSize: 8}).then (function(){ return db.friends.get('Nicolas'); }).then(function (friend) { alert ("Nicolas has shoe size " + friend.shoeSize); }).catch(function(error) { alert ("Ooops: " + error); });CRUD の参考
・create
https://github.com/kuc-arc-f/vue_spa3b_1crud/blob/master/src/components/DexieTasks/new.vue・index
https://github.com/kuc-arc-f/vue_spa3b_1crud/blob/master/src/components/DexieTasks/Index.vue・show
https://github.com/kuc-arc-f/vue_spa3b_1crud/blob/master/src/components/DexieTasks/show.vue・edit
https://github.com/kuc-arc-f/vue_spa3b_1crud/blob/master/src/components/DexieTasks/edit.vue
- 投稿日:2020-06-26T20:11:11+09:00
【Vue】学習開始4週目で覚える内容
4週目で学ぶべきこと
- フック関数
- カスタムディレクティブ
- フィルター
- ミックスイン
- Vue Router
フック関数
- フック関数:プログラムの中に
独自の処理を割りこませる
ために用意されている仕組み。
関数名 詳細 bind 初めて対象のhtmlタグに紐づいた時に、呼ばれる inserted カスタムディレクティブと紐づいた要素が親Nodeに挿入された際に呼ばれる update コンポーネント内でデータ更新が行われたタイミングで呼ばれる
子コンポーネント更新される前componentUpdated コンポーネント内でデータ更新が行われたタイミングで呼ばれる
子コンポーネント更新された後unbind htmlタグとの紐付けが解除された時点で呼ばれる カスタムディレクティブ
- 引数は
el, binding, vnode, oldVnode
。 ※基本はel, binding
を使う- フック関数の中で、
bind, update
は頻出のため、function関数
で省略可能el
はhtmlタグ
のことを指す。main.js//カスタムディレクティブ定義方法① Vue.directive("sample", { bind(el, binding) { el.style.color = 'red'; } }); //カスタムディレクティブ定義方法② Vue.directive("sample", function(el, binding) { el.style.border = 'red'; });◆ binding.value
App.vue<template> <!-- "v-sample"は、カスタムディレクティブ --> <p v-sample="red">Home</p> </template>main.jsVue.directive("sample", function(el, binding) { //v-sample="red"の値を、binding.valueで受け取る el.style.color = binding.value; });◆ 引数:arg
App.vue<template> <!-- "v-sample:solid"で、引数を指定する --> <p v-sample:solid="red">Home</p> </template>main.jsVue.directive("sample", function(el, binding) { //"v-sample:solid"の引数を"binding.arg"を用いて取得する el.style.samplestyle = binding.arg; });フィルター
Vue.filter
で、フィルターを作成し、パイプ
を使って適用するmain.js//フィルター名:"UpperCase" input値を"大文字"に変換する Vue.filter("UpperCase", function(value) { return value.toUpperCase(); });App.vue<template> <!-- "Vue.filter"で定義した"UpperCase"を挿入する --> <h1>{{ answer | UpperCase }}</h1> </template> <script> export default { data() { return { //属性値:answer 初期値:"hello world!" answer: "hello world!" } } }; </script>ミックスイン
export const
を用いてミックスイン
を定義する- ミックスインを定義したファイルを
import
,export
を使って反映させるsample.js//ミックスイン名:sampleを定義する export const sample = { data() { return { //属性値:answer 初期値:"hello world!" answer: "hello world!" } } };App.vue<template> <p>{{answer}}</p> </template> <script> //ミックスインを定義したファイル名をインポート import { sample } from "@/sample"; export default { //ミックスインで定義した内容をエクスポートし、反映させる mixins: [sample] }; </script>Vue Router
◆ router.js
router.js//vue-routerをインポートする import Vue from "vue"; import Router from "vue-router"; import Home from "./views/Home.vue"; //Router(プラグイン)を適用する Vue.use(Router); //new Routerによって、パスルーティングを指定 export default new Router({ routes: [ { //path, componentを指定 path: "/", component: Home } ] })◆ main.js
main.js//vue-routerを追加する import router from "./router" new Vue({ //routerを追加 router: router, render: h => h(App) }).$mount("#app");◆ App.vue
App.vue<template> <!-- "router-view"を使用することで、設定したルーティングを適用する --> <router-view></router-view> </template>同シリーズ
参考文献
- 投稿日:2020-06-26T19:55:23+09:00
【Vue.js 】 単一ファイルコンポーネント
はじめに
開発規模が大きければ大きいほど、ソースコードも煩雑になっていく。そのため、機能ごとにファイルを切り分け、
モジュール化
することで保守性や再利用性を高めていく。モジュール・・・機能ごとにクラスや関数を1つのファイルにまとめたもの
単一ファイルコンポーネントとは
単一ファイルコンポーネントとは、Vue独自のフォーマットでコンポーネントの定義方法の1つ。アプリケーションのコンポーネント構築に特化したモジュール管理を行うことができる。
Vueのコンポーネント(モジュール)を単独のファイル(拡張子が.vue
となる)として作成する機能。この単一ファイルコンポーネントは<template>
<script>
<style>
の3つのブロックで構成される。component.vue<template> <!-- テンプレートブロック --> </template> <script> // scriptブロック </script> <style> // styleブロック </style>ビルド
単一ファイルコンポーネントはVue独自のものなので、そのままブラウザに反映させても動作しない。ブラウザが解釈できるようにファイルを
ビルド(変換)
してあげる必要がある。
Vue CLI
を利用することで、単一ファイルコンポーネントを使用するためのビルド環境を楽に構築することができる。
※Vue CLIを使用するにはNode.jsのダウンロードが必要になる。→ Vue CLI 公式ドキュメント
→ Node.js 公式サイトtemplate
templateタグ内にはHTMLでテンプレートを記述していく。
ルート要素が1つ
になるように記述していく。sample.vue<template> <div> <h1>タイトル</h1> <p>テキストテキストテキスト</p> </div> </template>script
scriptタグ内にはjavascriptを記述していく。(設定次第でtypescriptも使用可能)
Vueのtemplateオプション以外のオプションオブジェクトをここに記述することができる。
コンポーネントを必要な場所でimport
(読み込み)できるようにexport
しておく。sample.vue<script> export default { // オプションオブジェクトを記述 } </script>style
styleタグ内にはコンポーネントのCSSを記述していく。(設定次第でsassなどのスタイル言語も使用可能)
スタイルにスコープをつけて記述することもできる。
→ スコープ付きCSSについてはこちらsample.vue<style> // ここにCSSを記述していく </style>
- 投稿日:2020-06-26T17:23:53+09:00
GitHub Pages に Vue.js を Hosting する
GitHub Pages は静的ページや SPA を無料でサクッと公開したい時に便利ですね。
でも、dist/ ではなく docs/ に成果物を配置する必要があります。やり方
プロジェクト直下に vue.config.js を作成します。
vue.config.jsmodule.exports = { outputDir: './docs', }ビルドすると docs/ 以下にビルドしてくれます。
$ yarn buildあとは master に
$ git commit
して$ git push
すれば反映されるはずです。
- 投稿日:2020-06-26T17:03:40+09:00
【Nuxt.js】Nuxt文法編:v-slot(中級)
分割代入
簡単にいうと別の場所で
別の変数名をきめれて
値を代入できること
MDN分割代入というより見た方が早いですね?
親で子の値を使えちゃいます!❓どんな時に使うか
まとまったdataを子で管理したい時に使います!Text.vue<template> <div class="title title-page"> <slot v-bind:user="user"> {{ user.lastName }} </slot> </div> </template> <script> export default { data () { return { user: { firstName: 'first', lastName: 'last', }, } }, } </script>index.vue<template> <div class="page"> <Text> <template #default="sample"> {{ sample.user.firstName }} </template> </Text> </div> </template> <script> import Text from '~/components/Text.vue' export default { components: { Text, }, data () { return { } }, } </script>動的なスロット名
まずは動的引数を理解しましょう?
https://jp.vuejs.org/v2/guide/syntax.html#動的引数【解説/index.vue】
・ リンク
これと全く同じです❗️
リンクLink.vue<template> <a :[attributeName]="url"> リンク </a> </template> <script> export default { data () { return { attributeName: "href", url: "/" } }, } </script>index.vue<template> <div class="page"> <Link /> </div> </template> <script> import Link from '~/components/Link.vue' export default { components: { Link, }, } </script>これをslotで…
できるのですが、
簡単な方法があります!笑v-bind="$attrs"
これを使います!【解説】
属性自体を親から渡したい時
v-bind="$attrs"を使います?
今回の場合はaタグの
href属性ごと渡してます。Link.vue<template> <a v-bind="$attrs">リンク</a> </template> <script> export default { } </script>index.vue<template> <div class="page"> <Link href="/" /> </div> </template> <script> import Link from '~/components/Link.vue' export default { components: { Link, }, } </script>まとめ
置き換えのできる3つをまとめました!
slot:テキスト
props:それ以外、クラス付与などに便利
v-bind="$attrs":属性自体
- 投稿日:2020-06-26T16:56:31+09:00
Vue.js+WordPressでつくったサイトがGoogleにインデックスされるまでがんばった話
GoogleはJavaScriptを実行後にインデックスしてくれるそうですね。クローラーのレンダリングエンジンはChromeの最新バージョンと大体同じで、SPA化したサイトでもちゃんと読み取ってくれるらしい。
それならば、と思い切って全面的にVue.jsを導入。WordPressでREST APIを吐き出し、フロントでAPIを叩いてVue.jsで表示、みたいなことをしてみました。IE11にも対応したのでChromeだったら最悪41ぐらいなら余裕だろ、と思ってサイトを公開しました。
ところがSearch Consoleでインデックス登録をリクエストしたところ
エラーが発生しました
問題が解消しない場合は、数時間後にもう一度お試しくださいというなんのヒントも得られないエラーが発生。何回やってもダメ。公開URLのテストをやってもそのテスト自体が同じエラーで全く進みません。そして当然インデックスもされていない。
「JavaScriptで生成されたものがインデックスされるのは時間がかかる」という情報は事前に得ていたので、きっとそれ関連のエラーなんだろう、sitemap.xmlも登録済みだし時間が解決するだろう、としばらく放置したものの、1日経っても5日経っても10日経っても状況は変わりません。
というわけでお客さんから苦情が来る前に何とかしてみました。
解決までの道のり
Search Consoleの「公開URLをテスト」を押しまくってみる
今回発生しているエラーとはエラーメッセージが違うけど、こちらの記事によると、「公開URLをテストでエラーが出てもひたすらボタンをクリックし続けるとあるタイミングでインデックス登録をリクエストする画面が出て来る」ということだったので、ひたすらポチポチ。
すると何のタイミングか全くわからないんだけど、唐突にテストに成功。そしてそのままインデックス登録もリクエスト。これで解決!と思いきや...
ソフト404になってしまいインデックスされない
翌日Search Consoleを確認してみると、
送信されたURLはソフト404エラーのようです
という理由でインデックスされていませんでした。ソフト404...つまりGoogleのクローラー的に「あるって言ってるけど実質このページは無いに等しいよね〜〜〜」と認識されている。
いやいやちゃんと画像と文章がふんだんにあるサイトですよ。
貴方が理解できるというJavaScriptで吐き出してますよ...あれ?つまりJavaScriptが実行されてない?クローラー側が何を見ているのかちゃんと理解する必要がありそう。ということで前日ポチポチしまくっていた「公開URLをテスト」を再びポチポチ。これでクローラー側で取得しているHTMLがどんなものか見ることができる。
そこでわかったのが、APIが「その他のエラー」という謎のエラーで読み込まれていないということ。おかげでサイトのコンテンツ部分が全く表示されていなかった。そりゃインデックスされないよ...。
「その他のエラー」について調べてみると、読み込みに時間がかかりすぎのために発生しているようだ。タイミングの問題だろうか?と思って何回かテストしてみても全くダメ。普通にサイトにアクセスする分にはスマホで見てもほぼ一瞬で表示されてるしこれ以上どうしたら...。
ダイナミックレンダリングをしてみる
頭を悩ませつつ色々調べているうちに行き着いたのが、ダイナミックレンダリング。
「普通のユーザーが見るときはJavaScriptで表示するけど、クローラーが見るときはプリレンダリングしたコンテンツを見せるよ!」というやつ。Google側もクローラーのレンダリングが完璧ではないとわかっているが故にこういうのを勧めているみたい。そして今回のサイトの裏側ではWordPressが動いている。これは案外楽にできるのでは?というわけでこんな感じにしてみた。bot判定の関数はこちらの記事のものを流用。
functions.phpfunction is_bot() { $bots = array( "googlebot", "bingbot", "Y!J", ); $ua = $_SERVER['HTTP_USER_AGENT']; foreach( $bots as $bot ) { if (stripos( $ua, $bot ) !== false) { return true; } } return false; }index.php<?php if( is_bot() ) { get_template_part( 'bot' ); } else { echo '<div id="app"></div>'; } ?>そしてis_botでtrueになったときしか読まれないbot.phpを用意し、そこにコンテンツを表示するための記載をすれば完成。
試しにSearch Consoleで公開URLをテストしてみると、無事意図したHTMLが表示された!しかも一発で!そのままインデックス登録をリクエストし、翌日には無事インデックスされているのを確認できました。
というわけでクローラーの性能が上がるまではしばらくこのままでいくことになりそうです。サイトの構造によってはJavaScriptだけでゴリゴリやっていくにはSEO的な観点でいくとまだまだ厳しいのかもしれませんね。
- 投稿日:2020-06-26T14:44:27+09:00
nuxt+Typescriptで「Property 'component' does not exist on type 'RouteConfig'」のエラーを直す
nuxtで普通にTypescriptのプロジェクトを作成すると,いきなりエラー出てびっくりした.
エラーメッセージはこんな感じ
・・・ ・・・ Property 'component' does not exist on type 'RouteConfig'. 12 | chunkName?: string 13 | chunkNames?: Record<string, string> > 14 | component?: RouteConfig['component'] | string | ^ 15 | } 16 | 17 | export interface NuxtConfigurationRouter extends RouterOptions { ・・・ ・・・調べてみると,すでに解決済みっぽい
Githubのissueにこんなものがあった.
vue-router breaks nuxt/types #7502
解決方法としては,
tsconfig.json
の中にある@nuxt/types
をちょっとだけ書き換える変更後
・・・ "types": [ "@types/node", "@nuxt/types@0.7.9+" ] ・・・これだけ.
誰かの参考になれば
- 投稿日:2020-06-26T10:56:25+09:00
CSSのみでアコーディオンを実現!detailsとsummaryについて
jsを駆使してアコーディオンを作るたびに思います。
「毎回めんどくさい…もっと秒でやりたい…」
そんな悩みを解決してくれる要素について記事にしました。使用方法
See the Pen HowToUseDetails&Summary by shake (@mgmgshake) on CodePen.
とっても簡単ですよね!
jsいらずで、HTMLのみでアコーディオンが実装できます♪
また、スタイルを上書きできるので自分好みのアコーディオンにすることもできます。対応するブラウザ
便利なdetail&summaryですが、対応するブラウザは以下のようになっております。
引用元:https://developer.mozilla.org/ja/docs/Web/HTML/Element/details…まぁ、いつも通りですね!
chrome,Firefox,safariでは普通に動くが、癖があります。(後述)
IE, Edgeはpolyfillを入れることにより使用可能になります。使用したpolyfill
details-element-polyfillを使用しました。
結構種類が豊富であり、4個ほどpolyfillを試したのですがまともに動作したのが2つだけでした…。
→シンプルなHTML構造ではないと使えない可能性あり?ブラウザごとのクセ
デフォルトでついているアイコンを削除する必要があります。
そのアイコンが、ブラウザによって扱いが異なります。
ブラウザ 状態 削除方法 chorome details-markerという特殊な擬似要素 summary::-webkit-details-marker { display: none; } safari 上と同じ 上と同じ firefox list-itemなのでlist-style扱い list-style none あるいはlist-style-image設定 IE,Edge 擬似要素(before) ::before content '' ※IE, Edgeはpolyfillにより異なる
firefoxのみ
無駄にlist-styleのため、summaryにdisplay: blockをかけるとその瞬間にアイコンが消えます。ちょっと不便。
少し面倒くさいですが、list-styleを消してしまって擬似要素で共通のアイコンを設定したが早いです。Vue.jsとの共存
条件によってアコーディオンの初期状態を制御したいとき、
detailsにはopenという独自の属性があるので、そちらをv-bindします<details v-bind:open="closeOption ? false : 'open' "> <summary>まぐろ</summary> ビチビチ </details>closeOptionがtrue→open=falseになる
html// 閉じられる(普通のアコーディオン) <details> <summary>まぐろ</summary> ビチビチ </details>false→open=openになる
html// 最初から開かれる <details open="open"> <summary>まぐろ</summary> ビチビチ </details>扱いにくい点
開いたら開きっぱなしにしたいときや、ユーザの状態によってアコーディオンそのものを無くしたいときなどがあると思います。
例えば、アンケートページでの任意項目はアコーディオンにして隠して置いて、ユーザが開いたら出しっぱなしにしたい時などです。
(あくまで例なので、details&summaryじゃなくてv-if使えば?というご意見はなしで…!)summaryにv-if効かない問題
html// 最初から開かれる <details open="open"> <summary v-if="false">まぐろ</summary> ビチビチ </details>
↑openDetail=falseのとき、summaryは消えずに「詳細」という内容に置き換わるだけv-ifでsummaryを消すと、勝手にどこかでsummaryが生成されてしまいます
CSSをあてることもできません
→どうやらsummaryのDOMがないと無理やりどこかで付け加える仕様のようですdetailsがopenのときに、summaryをdisplay noneにする記述を書けば解決することができます。
details[open] summary display none所感
まだまだ制約が多いので、デザインやアニメーションなどを凝りたい時は従来のアコーディオンの生成方法で良い気がしますが、
時間がなくてちゃちゃっと実装したい時にはいいかもしれません。新しめのhtmlタグってなかなか触れる機会がなくて困ります…。
- 投稿日:2020-06-26T10:29:27+09:00
初めてのLaravel+Vue.js
わたしの100のリスト
Laravelや、Vueを勉強中です。
それらのアウトプットを考えていたところ、家族から「シンプルなやることリストが欲しい!」という要望をもらったので、シンプルなToDoアプリを作成しました。その時の制作日誌として、学びと反省点をまとめます。
今後学ぶ人たちのヒントになればと思います。公開URL
https://wishlist100.herokuapp.com背景、目的
市場には多くのToDoアプリがあるが、多くは短期的なToDoをこなすことを目的としている。
人生では長期的な目標を成し遂げることがとても重要であり、そのような人生でやりたいことに焦点を当てたToDoアプリ「私の100のリスト」を作成した。
類似アプリとの差別化
すでに本アプリのような長期的な目標、夢をリスト化するアプリはあるが、リストを複数作れたり、いくつも追加できたりして本当に重要なものが明確になりにくい。
そこで、本アプリではリストに登録できる項目は100個までとした。
また、やりたいことと、すでにやったことを別々に表示して、やりたいことに集中できるように、またやったことは歴史として振り返られるようにした。
スペック
言語
- PHP 7.3
- JavaScript
フレームワーク
- Laravel 5.8.38
- Vue.js 2.5.17
サーバ
- heroku
開発環境
- MacBook Air
- Homestead
- VSCode
機能一覧
- ユーザー登録
- アカウント編集
- 退会
- ログイン
- ログアウト
- やりたいこと一覧表示
- やったこと一覧表示
- カテゴリ別表示
- やりたいこと作成
- やりたいこと編集
- やりたいこと削除
- 達成、未達成の切り替え
機能詳細
- ユーザー登録
- ユーザー名、Email、パスワードによりユーザーを登録する。
- アカウント編集
- ユーザー設定から、ユーザー名、Email、パスワードを変更する。
- 退会
- ユーザー設定から、退会ボタンの押下によりアラートを出し、OKであれば退会する。
- 退会処理後は、トップページへ遷移する。
- ログイン
- ログイン画面でEmailとパスワードを入力しログインボタンの押下によりログインする。
- ログアウト
- ログアウトボタンの押下によりログアウトする。
- やりたいこと一覧表示
- やりたいことのリストを表示する。
- 各項目には、カテゴリアイコン、内容、達成ボタン、登録日時を表示する。
- 達成ボタンを押すと一覧から除外され、やったことリストに移動する。
- やったことリスト
- 達成したことをリストで表示する
- 各項目には、カテゴリアイコン、内容、達成日時を表示する。
- やりたいこと作成
- 入力エリアにやりたいことを入力、カテゴリ一覧からアイコンを選択、登録ボタンの押下により、一覧へ追加する。
- やりたいことが空で登録された場合、エラーを表示する。
- やりたいことは30文字以内で入力する。
- やりたいこと編集
- やりたいことを押下により、やりたいこと、カテゴリを編集できる。
- 変更ボタンの押下により、編集を終了し一覧を更新する。
- やりたいこと削除
- やりたいことを押下により、削除ボタンを表示する。
- 削除ボタンの押下により、削除確認のアラートを出す。OKであれば一覧から削除する。
- 達成、未達成の切り替え
- 各やりたいことの達成ボタンを押下により、やったこと一覧へ移動する。
- やったこと一覧において、Undoボタンの押下により、やりたいこと一覧へ移動する。
DB設計
- Usersテーブル・・・LaravelのAuthで作成されたテーブルをそのまま採用。
- id, name, email, email_verified_at, password, remember_token
- Wishesテーブル
- id, user_id
- Itemsテーブル
- id, list_id, category_id, text, done_flg
- Categoriesテーブル
- id, name
Users:Wishes = 1:1
Wishes:Items = 1:多
Items:Categories = 1:1躓いた点、学び
1. bladeテンプレートでいくかVue.jsのコンポーネントでいくか悩んで手戻り発生
リストの表示、アイテムの追加、切り替え、削除などは、ページ遷移なしでSPA風に作った。
ただ、どこからどこまでシングルページのアプリとするか、できるところだけやってみるか、当初からどうするか迷っていた。
まずはbladeテンプレートで作ってみようという考えで作って、「モーダルで操作するならページ遷移しない方がよくない?」と、途中から方針変更。
その結果いろいろ作り直し。
最終的なコードももっとスマートな構成があるかも。結論:方針をしっかり決めておくこと
結局、方針がしっかり定まっていなかったから。
モーダル使うなら使うでしっかり決めて、ページ遷移するところ、しないところしっかり決めること。
2. 本番環境で見ることは大事
herokuにアップして公開したが、ローカルではわからない、スマホで触ってみないと気づかない不具合が結構あり。
やりたいことの追加ボタンを押すと入力用のモーダルウインドウを表示するが、いざ入力しようとするとスマホの予測変換が被って入力範囲が見れない・・・。
モーダルの実装に問題があると思うが、これは開発環境じゃ見つけられなかった。
(ちなみに、入力順序を入れ替えて対応しているだけで、まだ根本解決できてません・・・)結論:現地・現物・現場
三現主義は何にしても重要。
制作時間
ざっくりとした制作時間。
Laravelとvueの実装部分は、この作業はフロント側だなと感じたものを自己流に分けているだけで、何かを拠り所にしているわけではありません。当初の見積もりに比べて、下記の原因で増加。
- UIの部分で時間がかかった
- 上記で挙げたbladeとvueの方針の部分でいろいろ悩んだ
- Homesteadの環境構築も初めてで時間取られた
工程 見積もり (h) 実質 (h) 機能洗い出し 1 1.5 画面設計 3 3 DB設計 0.5 0.5 モック作成 6 11.5 環境構築 0.5 2 フロント側実装 20 21 サーバー側実装 10 15.5 テスト、デプロイ 5 3 合計 46 56 まとめ
荒削りではありますが、LaravelとVue.jsを使って、一通りのCRUD処理を使ったアプリを作成することができました。
- 投稿日:2020-06-26T08:53:37+09:00
【Vue.js】テンプレート構文のあれこれ【基本だけ】
忘備録アウトプット。間違っていたらごめんなさい
テンプレート制御ディレクティブ
v-once
初回だけテキスタバインディングを行う時に使う。似たようなものに、単方向のv-bind,双方向のv-modelがある。
v-pre
要素と子要素のコンパイルをスキップするときに使う。
- XSS対策
- マスタッシュ構文をそのまま出力
などに使用される。
v-html
サーバーサイドから取得したhtmlタグを出力する時に使う。
v-cloak
チラツキ防止などに使われる。インスタンスのコンパイルが終わるまで非表示にしたい場合など。(非表示自体はcss等で制御。)
v-text
マスタッシュ構文を使わなくても、vue.js内部にあるデータ(変数)などを表示することができる。
バインディング式
マスタッシュタグ内部のテキストのこと。{{ココ}}
JavaScript式
マスタッシュ構文内には、数列,変数などの処理を含んだ単一式を入れることができる。
フィルタ
vue.jsでは式の終わりにフィルタを追加できる。vueインスタンスのオプションとして、filtersとして定義(ローカルフィルタ)。下記のように使用できる。ちなみに、フィルタは複数使える。
- ローカルフィルタ
- グローバルフィルタ
の二つが存在する。
{{ 式 | フィルタ }}の形で使用できる。
- 投稿日:2020-06-26T06:25:01+09:00
Uncaught TypeError: fs.existsSync is not a functionのエラー解決
状況
Windowsアップデートついでにnode.jsとかモジュールをアップデートしたらelectronでエラーが出るようになった。
Uncaught TypeError: fs.existsSync is not a function'環境
- windows 10 Pro Insider Preview 2004 (20150.1000)
- node v14.4.0
- Electron 9.0.4
- Vue.js 2.6.11
- Vuex 3.4.0
- vuetify 2.2.11
原因
ipcRendererが原因のもよう。
レンダラープロセスがノードモジュールにアクセスしようとして失敗しているみたい。解決方法
vue.config.jsファイルに下記を追記したら動いてくれた。
module.exports = { transpileDependencies: [ 'vuetify' ], pluginOptions: { electronBuilder: { nodeIntegration: true } } }これでレンダラープロセスがノードモジュールにアクセスできるようになりエラーが回避できる。
ただし脆弱性になりうるので、公開するアプリなどでは注意が必要とのこと。