- 投稿日:2020-09-11T20:26:05+09:00
Atomic DesignとNuxt
はじめに
Nuxtでポートフォリオを作っているとかなりコードがとっ散らかっていたり、コンポーネントをうまく活用できていない気がしてきました。そこで他の人のリポジトリを見てみると、Componentディレクトリの中になにやら「Atoms」やら「Organisms」というフォルダがあり、その中に大量のファイルがしまわれ、pagesで描画される形をみかけ、「なんじゃ、こりゃ」となったので調べてみると「Atomic Design」なるもののよう。調べたことをまとめてみました。
この記事の対象
・Nuxtでのアプリ開発をしたい or している人
Atomic Designとは?
Atomic Designは、Brad Frost氏が考案したデザイン設計手法の一つです。Atomic Designは、少し調べれば幾つもの良質な記事が見つかりますし、氏の公式サイトには実に詳細な説明があります。が、一度ここでもまとめてみます。
5つの段階
Atomic Designは5つの異なる段階が連携することから成るデザイン設計です。その5つは
- Atoms(原子)
- Molecules(分子)
- Organisms(生物)
- Templates(テンプレート)
- Pages(ページ)
です。
この5つの段階を詳しく見ていきます。
Atoms(原子)
Atomic Designにおける最小単位です。この段階には、フォームラベル、ボタンなどのこれ以上分解できない基本的なHTML要素が含まれます。
Molecules(分子)
この段階では、AtomとAtomを組み合わせて、一つの機能を持つMoleculesという要素になります。例えば、入力フォームと検索ボタンを組み合わせて、検索用のフォームとすることができます。
Organisms(生物)
Moleculesが、Atomを2つ以上組み合わせて出来上がるように、OrganismsはMoleculeとMoleculeを組み合わせることで出来上がります。例えば、サイトのヘッダーは代表的なOrganismsの例です。ヘッダーは検索フォームやロゴ、各ページへ飛ぶナビゲーションから成り立ちます。
Templates(テンプレート)
テンプレートは、コンポーネントをレイアウトに配置し、具体的なサイトのデザインを形作ります。つまり、ページの骨格であり、ここにイメージや文章を挿入することで、ようやく最終段階、Pages(ページ)となります。
Pages(ページ)
テンプレートに画像や文章を流し込むことで最終的に出来上がるもの、それがPagesです。実際にユーザーが目にするもので、コンテンツの動的な性質を反映します。動的な性質というのは、例えば、同じTemplatesであっても、管理者ユーザーと一般ユーザーが表示が異なる場合がある、などのことです。
ディレクトリ構造
Componentsrc └── components └── atoms └── Btn.vue └── Logo.vue └── molecules └── Form.vue └── organisms └──Header.vue └── templates └── pagesNuxtのディレクトリ構造は次のようなものになります。
メリット
Atomic Designを取り入れることにより、どのようなメリットがあるでしょうか?それは次のような点です。
変更に強い
Atomic Designは、ページ全体の変更に対しても、各ボタンのような小さな変更に対しても柔軟に対応することができます。それは、Atomic Designの各段階が分離されている面もあり、必要な部分では絡み合っているからです。
あらゆるインタフェースに適用できる
作者のBrad Frost氏はウェブデザイナーであり、Atomic Designはウェブからコンセプトを得て生み出されましたが、このデザイン設計手法はウェブだけではなくあらゆるインタフェースに対して適用できる手法です。アトミックな設計手法は、Microsoft Word、Keynote、Photoshop、銀行のATMなどなど、公式サイトではInstagramを例にあげて説明もされています。
終わりに
Nuxtらしいコードやディレクトリの使い方をするにはどうしたら良いのかと探っているうちにAtomic Designをしれたのは幸運でした。Atomic Designという名前は作者の高校時代の化学授業から着想を得て命名されたもので、そのためか公式サイトではたびたび化学と結びつけて説明されています。公式のドキュメントも面白おかしく書かれていて読みやすく、Atomic Designについて、ここで説明した概要以外にも「では、どうすれば実現できるのか?」という部分までしっかり書かれています。時間の都合上まとめれなかったのが残念ですが..。
ここまで読んで頂きありがとうございました。ポートフォリオを作る中で、モヤモヤした部分が解消されたので、折角なので文字に起こした次第です。では、また!
- 投稿日:2020-09-11T19:28:11+09:00
Vue.jsでHeadタグ内のタイトルとメタタグを設定する
課題
SPAでもページごとにタイトルやメタタグを設定したい。
SPAだし、メタタグはいらないけど、ページタイトルは変更したいかなぁって感じ。Nuxt.jsは、title設定があるけど、同じような感じでVueでも設定したい。
TL;DR
vue-head
Headプロパティでタイトルを含めて、Headに設定できることを操作できる感じ。
934スターあるし、プロジェクトにスポンサーもついているし鉄板ぽいhttps://github.com/ktquez/vue-head
vue-page-title
タイトル変更に特化した感じ。
Nuxt.jsのように、titleプロパティを設定して使えたり、Vue-routerのメタタグにTitleを設定することで反映される。
107スターなので、少しマニアックっぽい。https://github.com/vinicius73/vue-page-title
追記
githubで検索していたら、
vue-headful
というのもあった。https://github.com/troxler/vue-headful
vue-head
と機能は同じだけど、記述の仕方がコンポーネントとして記述するので、少し違和感が。。。。ただし、219スターなので、それなりに人気があるのかな?
参考文献
- vue.jsでheadの要素を設定する時はvue-headが便利!
- Vue-headの紹介記事
- 【Vue.js】titleタグやmetaタグ(description)を書き換える方法【vue-rouetr】
- 手法をまとめてくださっている。
- vue.js router を 使い 動的に title や meta タグを変更
- vue-page-titleで実装されている方法と似ている。アイデア元が一緒かも?
- Vue + vue-router で動的にページタイトルを変更する方法
- vue-page-titleで実装されている方法と似ている。アイデア元が一緒かも?
- Updating Page Title & Metadata with Vue.js & vue-router
- Vue-routerのナビゲーションのフックを使って操作する方法
- 投稿日:2020-09-11T18:36:15+09:00
[VeeValidate]入力中にバリデータを動かさないようにする
Vue.jsでバリデータを書く時に VeeValidateを活用しています。
VeeValidateの発動タイミングを操作する上でハマった場面がありましたので備忘録として残します。
おそらくもっといい方法があると思うので教えていただきたいです!!要件
要件は
- ユーザーが書き込みを行なっている間はエラーメッセージを表示しない
- 送信ボタンが押された時だけエラーメッセージを表示する
というものです。上記のgifですと、まだユーザーが記入を続けている(focus)されている間にエラーメッセージが表示されています。
こちらを要件通りに実装し直す必要がありました。
元コード
form.vue<template> <div class="wrapper"> <h3>form</h3> <div> <validation-provider name="name" rules="required" v-slot="{ errors }"> <div> <label> 名前 <input type="text" v-model="name" /> <span class="error">{{ errors[0] }}</span> </label> </div> </validation-provider> <validation-provider name="email" rules="required" v-slot="{ errors }"> <div> <label> メールアドレス <input type="text" v-model="email" /> <span class="error">{{ errors[0] }}</span> </label> </div> </validation-provider> </div> <button @click="submit">送信</button> </div> </template> <script> import { ValidationProvider, extend} from 'vee-validate'; import { required } from 'vee-validate/dist/rules'; extend('required', required); export default { components: { ValidationProvider, }, data() { return { name: '', email: '' } }, methods: { submit() { alert('送信に成功しました'); } } } </script> <style scoped> .wrapper { margin-left: 50px; margin-top: 50px; } .error { color: red; } </style>とりあえずフォーム送信時に動くようにしてみる
handleSubmitを使って
送信ボタン
を押すとバリデータが動くようにしてみました。form.vue<template> <div class="wrapper"> <h3>form</h3> <validation-observer v-slot="{ handleSubmit }"> <div> <validation-provider name="name" rules="required" v-slot="{ errors }"> <div> <label> 名前 <input type="text" v-model="name" /> <span class="error">{{ errors[0] }}</span> </label> </div> </validation-provider> <validation-provider name="email" rules="required" v-slot="{ errors }"> <div> <label> メールアドレス <input type="text" v-model="email" /> <span class="error">{{ errors[0] }}</span> </label> </div> </validation-provider> </div> <button @click="handleSubmit(submit)">送信</button> </validation-observer> </div> </template> <script> import { ValidationProvider, ValidationObserver, extend} from 'vee-validate'; import { required } from 'vee-validate/dist/rules'; extend('required', required); export default { components: { ValidationProvider, ValidationObserver }, data() { return { name: '', email: '' } }, methods: { submit() { alert('送信に成功しました'); } } } </script> <style scoped> .wrapper { margin-left: 50px; margin-top: 50px; } .error { color: red; } </style>確かに送信ボタンを押した時にバリデータが動いてします。
しかし、ユーザーが書き込みを行なっている間はエラーメッセージを表示しない
に対応ができていません。eventsを使ってみる
イベントの無効化やこちらを参考にやってみたが変わらない...
一応実装コード
form.vue<template> <div class="wrapper"> <h3>form</h3> <validation-observer v-slot="{ handleSubmit }"> <div> <validation-provider name="name" rules="required" :events="[]" v-slot="{ errors }"> <div> <label> 名前 <input type="text" v-model="name" /> <span class="error">{{ errors[0] }}</span> </label> </div> </validation-provider> <validation-provider name="email" rules="required" v-slot="{ errors }"> <div> <label> メールアドレス <input type="text" v-model="email" /> <span class="error">{{ errors[0] }}</span> </label> </div> </validation-provider> </div> <button @click="handleSubmit(submit)">送信</button> </validation-observer> </div> </template> <script> import { ValidationProvider, ValidationObserver, extend} from 'vee-validate'; import { required } from 'vee-validate/dist/rules'; extend('required', required); export default { components: { ValidationProvider, ValidationObserver }, data() { return { name: '', email: '' } }, methods: { submit() { alert('送信に成功しました'); } } } </script> <style scoped> .wrapper { margin-left: 50px; margin-top: 50px; } .error { color: red; } </style>力技で対応
focusしているときはErrorを表示させないように
v-show
で制御しました。<template> <div class="wrapper"> <h3>form</h3> <validation-observer v-slot="{ handleSubmit }"> <div> <validation-provider name="name" rules="required" v-slot="{ errors }"> <div> <label> 名前 <input type="text" v-model="name" @focus="showNameError = false" /> <span v-show="showNameError" class="error">{{ errors[0] }}</span> </label> </div> </validation-provider> <validation-provider name="email" rules="required" v-slot="{ errors }"> <div> <label> メールアドレス <input type="text" v-model="email" @focus="showEmailError = false" /> <span v-show="showEmailError" class="error">{{ errors[0] }}</span> </label> </div> </validation-provider> </div> <button @click="beforeHandleSubmit(handleSubmit(submit))">送信</button> </validation-observer> </div> </template> <script> import { ValidationProvider, ValidationObserver, extend} from 'vee-validate'; import { required } from 'vee-validate/dist/rules'; extend('required', required); export default { components: { ValidationProvider, ValidationObserver }, data() { return { name: '', email: '', showNameError: false, showEmailError: false, } }, methods: { submit() { alert('送信に成功しました'); }, beforeHandleSubmit(func) { this.showNameError = true; this.showEmailError = true; func().then; }, } } </script> <style scoped> .wrapper { margin-left: 50px; margin-top: 50px; } .error { color: red; } </style>一応要件は満たせましたが、
コードとしても煩雑になりますし、微妙な感じですね。。。。もっといい方法がないか探してみたいと思います!!
- 投稿日:2020-09-11T18:22:50+09:00
【技術選定】React.js vs Vue.jsを真剣に評価してみた
目次
1. 対象読者
2. 目的
3. 技術選定の考え方
4. 評価基準
5. 結論
6. 比較評価
7. テックリード/エンジニア募集中!1. 対象読者
React.jsとVue.jsどちらを採用するか?
を悩んでいるフロントエンドのアーキテクトや開発者向けです。2. 目的
適切な技術選定の手助けとなれればと思います。
3. 技術選定の考え方
技術は要件を満たすための手段です。
そのため、技術選定では、求められる要件をまず明確にするべきです。
そして、要件を最も満たす技術を採用するべきです。4. 評価基準
上記の考え方に基づき、よくある要件ごとにReact.js vs Vue.jsを比較評価しました。
- 多角的&客観的に評価するよう心掛けました。
- 主観的な評価の場合、個人見解である旨を明記しました。
【よくある要件をどう網羅したか】
要件は、機能要件/非機能要件に分けられます。
- 機能要件は、多種多様なので網羅困難です。よくありそうな要件(個人見解)のみにしました。
- 非機能要件はIPAの非機能要求グレードを参考に網羅しました。
5. 結論
- 可用性を細かく気にする場合、Vue.jsの方が未解決バグ数は少ないです。(可用性の詳細)
- テーブルの行入れ替えが多いシステムの場合、Vue.jsを選択した方が良いです。(性能の詳細)
- 海外の開発者が必要な場合、React.jsを選択した方が「やや良い」です。(開発者確保の詳細)
- 学習コストを重視する場合、React.jsを選択した方が良いです。(学習コストの詳細)
- それ以外の場合、どちらを選択しても良いです。
【比較表】
評価項目 React Vue 可用性 ○※1 ○ 保守性 ○ ○ セキュリティ ○ ○ 性能 ○※2 ○※2 開発者の確保しやすさ ○ ○ 学習コスト ○ △ 優れたUIの提供しやすさ ○ ○ 開発者が楽しい ○※3 ○※3 ※1 ただし、未解決バグ数がReact.jsの方が多いです。(可用性の詳細)
※2 大きな問題はありませんが、それぞれに得意/不得意があります。(性能の詳細)
※3 個人見解です。上記結論に至った詳細は、以下の通りです。
6. 比較評価
6.1 可用性
安定して継続的に本番稼動できる品質か?という観点で評価しました。
【結論】
引き分けです。未解決バグ数を気にされる場合は、Vue.jsの勝利です。
【理由】
どちらも本番運用実績が十分にある&十分な頻度で改修されているからです。
未解決バグ数はReact.jsの方が数字的には多いです。
個人見解としては気にするほどの差異ではありませんが、気にされる場合はVue.jsの勝利です。
詳細は以下の通りです。【本番運用実績】
どちらも十分な実績があります。
- React.js:Facebook,Uber,Tesla等
- Vue.js:Google, Apple, Nintendo, Gitlab等
【未解決バグ数】
React.jsの方がやや多いです。
GitのIssuesの「bug」タグの数を見ると以下です。(2020/09時点)※本来ならバグ率で比較したかったですが、規模が分からないので断念しました。
※バグ毎の重要度も異なりますので、バグ数はあくまでも参考値という扱いですね。【改修頻度】
どちらもすごい頻度で改修されています。
GitのReleasesから2019年のリリース回数を数えると以下です。6.2 保守性
【結論】
引き分けです。
【理由】
どちらもコンポーネント単位で開発できるため、保守性を確保しやすいからです。
もちろん技術選定以前に、保守性を確保した設計ができていることが大事です。6.3 セキュリティ
【結論】
引き分けです。
【理由】
以下の通り、セキュリティ対策内容に差異が無いためです。
主にフロントエンド側のセキュリティ対策を対象に調査しました。
どちらもXSS対策が組み込まれています。
具体的には以下の通りです。6.3.1 XSS(クロスサイトスクリプティング)
【XSSとは】
Webアプリに罠リンク等を表示できてしまう脆弱性のことです。
悪意のあるユーザが悪意のあるスクリプトやHTMLを入力したとき、
対策されていないWebアプリだと、罠リンク等が表示されてしまいます。罠リンクをクリックしたユーザは、例えばログインセッション情報を盗まれ、不正ログイン(なりすまし)されてしまったり、様々な被害を受けます。
詳細は、「3分でわかるXSSとCSRFの違い」が分かりやすいと思います。
【React.jsのXSS対策】
対策されています。自動でサニタイズ(エスケープ)してくれます。
公式 | JSX はインジェクション攻撃を防ぐ
デフォルトでは、React DOM は JSX に埋め込まれた値をレンダリングされる前にエスケープします。このため、自分のアプリケーションで明示的に書かれたものではないあらゆるコードは、注入できないことが保証されます。レンダーの前に全てが文字列に変換されます。これは XSS (cross-site-scripting) 攻撃の防止に役立ちます。
dangerouslySetInnerHTML
を使用する場合はサニタイズされませんので、脆弱性につながるリスクがあります。スクリプトに該当する文字列をサニタイズする等の対策が必要です。公式 | dangerouslySetInnerHTML
dangerouslySetInnerHTML は、ブラウザ DOM における innerHTML の React での代替です。一般に、コードから HTML を設定することは、誤ってあなたのユーザをクロスサイトスクリプティング (XSS) 攻撃に晒してしまいやすいため、危険です。※GoogleデベロッパーエキスパートでAuth0アンバサダー/エキスパートであるPhilippe De Ryck氏がReact.jsのXSS対策の記事を書いており、参考になります。
Preventing XSS in React※サニタイズとは、ユーザ入力値に含まれるHTML/JavaScript特殊文字をエスケープすることで、HTML/JavaScriptとして解釈されないようにすることです。
【Vue.jsのXSS対策】
対策されています。自動でサニタイズ(エスケープ)してくれます。
公式 | セキュリティ
テンプレートを使用する場合も、描画関数を使用する場合も、コンテンツは自動的にエスケープ処理されます。ただし、
v-html
やdomPropsInnerHTML
を使用する場合はサニタイズされませんので、脆弱性につながるリスクがあります。スクリプトに該当する文字列をサニタイズする等の対策が必要です。SSR(サーバサイドレンダリング)に乗せると、脆弱性につながる場合があります。こちらのサイトが参考になります。
6.3.2 XSS以外
【評価】
React.jsとVue.jsどちらも対策の仕組みはありません。
基本的にフロントエンドではなくバックエンドやミドルウェアで対策するものだからでしょう。【補足】
とはいえ例えば、CSRF対策のトークンをリクエストヘッダに埋め込む等の実装は必要ですね。
サーバで発行したCSRFトークンを、リクエスト毎にヘッダに設定するイメージです。
React.js or Vue.js問わず、Axios等で実装すると思いますが、
Vue.jsならこの記事、React.jsならこの記事が、参考になるかもしれません。6.4 性能
【結論】
引き分けです。
【理由】
一部で得意/不得意の差があるものの、処理時間/メモリ使用量ともに互角です。
詳細は以下の通りです。【処理時間】
ベンチマークサイトによると、それぞれに得意/不得意があります。
※react-v16.4.1、vue-v2.5.16の「keyed」を比較しました。
- React.jsは、テーブルの行入れ替えがVue.jsよりも遅いです。
- Vue.jsは、テーブル行の部分更新がReact.jsよりも遅いです。
- それ以外の処理時間は、どちらも互角です。
以下は、ベンチマークサイトの結果から作成した表です。
【メモリ使用量】
ベンチマークサイトによると、どちらも互角です。
※react-v16.4.1、vue-v2.5.16の「keyed」を比較しました。6.5 開発者の確保しやすさ
【結論】
国内は引き分け、海外は僅差でReact.jsの勝利です。
【理由】
どちらも人気(≒開発者が多い)だからです。
Googleトレンドでは海外だとReact.jsの方が多いです。
具体的には、以下の通りです。【人気度】
React.jsとVue.jsともに、人気度/要望度がトップです。
【GitのStar数】
どちらも同等の人気があります。
【Googleトレンド】
React.jsとVue.jsのGoogleトレンドは、国内は引き分け、海外はReact.jsの勝利です。
※国内はこちら↓
※海外はこちら↓
6.6 学習コスト
【結論】
定量評価だとReact.jsの勝利、定性評価だとVue.jsの勝利(個人見解)です。
客観的に見れば、定量評価を優先してReact.jsの勝利です。【理由】
定量評価だと、Vue.jsの方が覚える量が物理的に多いからです。
具体的には以下の通りです。6.6.1 定量評価:React.jsの勝利
【評価】
JSX記法より、Vue.js構文の方が覚える量が物理的に多いです。
それ以外のstateやRouter等の学習量は、React.jsとVue.jsでほぼ差異はありません。
詳細は以下の通りです。【React.jsで学習が必要なこと】
主に以下の学習が必要です。
- JSX記法
- state/Redux
- Router/hook等
【Vue.jsで学習が必要なこと】
主に以下の学習が必要です。
- Vue.js構文(各種ディレクティブ/computed/watch/method等)
- state/Vuex
- Router等
6.6.2 定性評価:Vue.jsの勝利(個人見解)
【評価】
Vue.jsの方が学習しやすいです。個人見解です。
【理由】
個人見解ですが、見慣れないJSX記法より、HTMLっぽく読めるVue.jsの方が、抵抗感無く学習できたからです。
※慣れてしまった今はJSX記法への抵抗感は無いですが、当初は抵抗感があったという意味です。6.7 優れたUIの提供しやすさ
【結論】
引き分けです。
【理由】
以下の通り、「優れたUI」を実装するコストに差異が無いためです。
【優れたUIの定義】
この記事では、ユーザーが考えずに操作できるUIを「優れたUI」と定義します。
※参考:Steve Krug著「Don't Make Me Think」優れたUIの具体例は以下です。
・どれがクリックできる要素か?が明確であること。
・説明がシンプル&明確であること。(自己満足な宣伝文句が無い)【評価観点】
まず、設計工程で「優れたUI」が設計されている必要があります。
その前提で、React.jsとVue.jsのどちらが実装コストが少ないか?で評価します。【評価】
実装コストに差異は無いでしょう。
- UIフレームワークで実現できるUIデザインの場合
- React.jsなら「Material-UI」等、Vue.jsなら「Vuetify」等で実装できます。
- 上記で実現できない凝ったUIデザインの場合
- React.js or Vue.jsに関わらず、UIフレームワークのカスタマイズや独自CSSの実装が必要です。
6.8 開発者が楽しい
開発者のモチベーションは大事ですね。
【結論】
引き分けです。
【理由】
開発者の主観で決まりますので引き分けです。
個人見解としては、どちらも楽しいです。7. テックリード/エンジニア募集中!
株式会社ビジョン・コンサルティングでは、アーキテクトや開発者を募集しています!
世界をより便利にすることに情熱を燃やし、新規事業部で新サービスを一緒に開発しませんか?
詳細はこちら!
- 投稿日:2020-09-11T18:22:50+09:00
React.js vs Vue.jsを真剣に評価してみたら、巷の評価とは違う結果になった
目次
1. 対象読者
2. 目的
3. 技術選定の考え方
4. 評価基準
5. 結論 | 比較表
6. 比較評価
7. テックリード/エンジニア募集中!1. 対象読者
React.jsとVue.jsどちらを採用するか?
を悩んでいるフロントエンドのアーキテクトや開発者向けです。2. 目的
適切な技術選定の手助けとなれればと思います。
3. 技術選定の考え方
技術は要件を満たすための手段です。
そのため、技術選定では、求められる要件をまず明確にするべきです。
そして、要件を最も満たす技術を採用するべきです。4. 評価基準
上記の考え方に基づき、よくある要件ごとにReact.js vs Vue.jsを比較評価しました。
- 多角的&客観的に評価するよう心掛けました。
- 主観的な評価の場合、個人見解である旨を明記しました。
【よくある要件をどう網羅したか】
要件は、機能要件/非機能要件に分けられます。
- 機能要件は、多種多様なので網羅困難です。よくありそうな要件(個人見解)のみにしました。
- 非機能要件はIPAの非機能要求グレードを参考に網羅しました。
5. 結論 | 比較表
- 可用性を細かく気にする場合、Vue.jsの方が未解決バグ数は少ないです。(可用性の詳細)
- テーブルの行入れ替えが多いシステムの場合、Vue.jsを選択した方が良いです。(性能の詳細)
- 海外の開発者が必要な場合、React.jsを選択した方が「やや良い」です。(開発者確保の詳細)
- 学習コストを重視する場合、React.jsを選択した方が良いです。(学習コストの詳細)
- それ以外の場合、どちらを選択しても良いです。
【比較表】
評価項目 React Vue 可用性 ○※1 ○ 保守性 ○ ○ セキュリティ ○ ○ 性能 ○※2 ○※2 開発者の確保しやすさ ○ ○ 学習コスト ○ △ 優れたUIの提供しやすさ ○ ○ 開発者が楽しい ○※3 ○※3 ※1 ただし、未解決バグ数がReact.jsの方が多いです。(可用性の詳細)
※2 大きな問題はありませんが、それぞれに得意/不得意があります。(性能の詳細)
※3 個人見解です。上記結論に至った詳細は、以下の通りです。
6. 比較評価
6.1 可用性
安定して継続的に本番稼動できる品質か?という観点で評価しました。
【結論】
引き分けです。未解決バグ数を気にされる場合は、Vue.jsの勝利です。
【理由】
どちらも本番運用実績が十分にある&十分な頻度で改修されているからです。
未解決バグ数はReact.jsの方が数字的には多いです。
個人見解としては気にするほどの差異ではありませんが、気にされる場合はVue.jsの勝利です。
詳細は以下の通りです。【本番運用実績】
どちらも十分な実績があります。
- React.js:Facebook,Uber,Tesla等
- Vue.js:Google, Apple, Nintendo, Gitlab等
【未解決バグ数】
React.jsの方がやや多いです。
GitのIssuesの「bug」タグの数を見ると以下です。(2020/09時点)※本来ならバグ率で比較したかったですが、規模が分からないので断念しました。
※バグ毎の重要度も異なりますので、バグ数はあくまでも参考値という扱いですね。【改修頻度】
どちらもすごい頻度で改修されています。
GitのReleasesから2019年のリリース回数を数えると以下です。6.2 保守性
【結論】
引き分けです。
【理由】
どちらもコンポーネント単位で開発できるため、保守性を確保しやすいからです。
もちろん技術選定以前に、保守性を確保した設計ができていることが大事です。6.3 セキュリティ
【結論】
引き分けです。
【理由】
以下の通り、セキュリティ対策内容に差異が無いためです。
主にフロントエンド側のセキュリティ対策を対象に調査しました。
どちらもXSS対策が組み込まれています。
具体的には以下の通りです。6.3.1 XSS(クロスサイトスクリプティング)
【XSSとは】
Webアプリに罠リンク等を表示できてしまう脆弱性のことです。
悪意のあるユーザが悪意のあるスクリプトやHTMLを入力したとき、
対策されていないWebアプリだと、罠リンク等が表示されてしまいます。罠リンクをクリックしたユーザは、例えばログインセッション情報を盗まれ、不正ログイン(なりすまし)されてしまったり、様々な被害を受けます。
詳細は、「3分でわかるXSSとCSRFの違い」が分かりやすいと思います。
【React.jsのXSS対策】
対策されています。自動でサニタイズ(エスケープ)してくれます。
公式 | JSX はインジェクション攻撃を防ぐ
デフォルトでは、React DOM は JSX に埋め込まれた値をレンダリングされる前にエスケープします。このため、自分のアプリケーションで明示的に書かれたものではないあらゆるコードは、注入できないことが保証されます。レンダーの前に全てが文字列に変換されます。これは XSS (cross-site-scripting) 攻撃の防止に役立ちます。
dangerouslySetInnerHTML
を使用する場合はサニタイズされませんので、脆弱性につながるリスクがあります。スクリプトに該当する文字列をサニタイズする等の対策が必要です。公式 | dangerouslySetInnerHTML
dangerouslySetInnerHTML は、ブラウザ DOM における innerHTML の React での代替です。一般に、コードから HTML を設定することは、誤ってあなたのユーザをクロスサイトスクリプティング (XSS) 攻撃に晒してしまいやすいため、危険です。※GoogleデベロッパーエキスパートでAuth0アンバサダー/エキスパートであるPhilippe De Ryck氏がReact.jsのXSS対策の記事を書いており、参考になります。
Preventing XSS in React※サニタイズとは、ユーザ入力値に含まれるHTML/JavaScript特殊文字をエスケープすることで、HTML/JavaScriptとして解釈されないようにすることです。
【Vue.jsのXSS対策】
対策されています。自動でサニタイズ(エスケープ)してくれます。
公式 | セキュリティ
テンプレートを使用する場合も、描画関数を使用する場合も、コンテンツは自動的にエスケープ処理されます。ただし、
v-html
やdomPropsInnerHTML
を使用する場合はサニタイズされませんので、脆弱性につながるリスクがあります。スクリプトに該当する文字列をサニタイズする等の対策が必要です。SSR(サーバサイドレンダリング)に乗せると、脆弱性につながる場合があります。こちらのサイトが参考になります。
6.3.2 XSS以外
【評価】
React.jsとVue.jsどちらも対策の仕組みはありません。
基本的にフロントエンドではなくバックエンドやミドルウェアで対策するものだからでしょう。【補足】
とはいえ例えば、CSRF対策のトークンをリクエストヘッダに埋め込む等の実装は必要ですね。
サーバで発行したCSRFトークンを、リクエスト毎にヘッダに設定するイメージです。
React.js or Vue.js問わず、Axios等で実装すると思いますが、
Vue.jsならこの記事、React.jsならこの記事が、参考になるかもしれません。6.4 性能
【結論】
引き分けです。
【理由】
一部で得意/不得意の差があるものの、処理時間/メモリ使用量ともに互角です。
詳細は以下の通りです。【処理時間】
ベンチマークサイトによると、それぞれに得意/不得意があります。
※react-v16.4.1、vue-v2.5.16の「keyed」を比較しました。
- React.jsは、テーブルの行入れ替えがVue.jsよりも遅いです。
- Vue.jsは、テーブル行の部分更新がReact.jsよりも遅いです。
- それ以外の処理時間は、どちらも互角です。
以下は、ベンチマークサイトの結果から作成した表です。
【メモリ使用量】
ベンチマークサイトによると、どちらも互角です。
※react-v16.4.1、vue-v2.5.16の「keyed」を比較しました。6.5 開発者の確保しやすさ
【結論】
国内は引き分け、海外は僅差でReact.jsの勝利です。
【理由】
どちらも人気(≒開発者が多い)だからです。
Googleトレンドでは海外だとReact.jsの方が多いです。
具体的には、以下の通りです。【人気度】
React.jsとVue.jsともに、人気度/要望度がトップです。
【GitのStar数】
どちらも同等の人気があります。
【Googleトレンド】
React.jsとVue.jsのGoogleトレンドは、国内は引き分け、海外はReact.jsの勝利です。
※国内はこちら↓
※海外はこちら↓
6.6 学習コスト
【結論】
定量評価だとReact.jsの勝利、定性評価だとVue.jsの勝利(個人見解)です。
客観的に見れば、定量評価を優先してReact.jsの勝利です。【理由】
定量評価だと、Vue.jsの方が覚える量が物理的に多いからです。
具体的には以下の通りです。6.6.1 定量評価:React.jsの勝利
【評価】
JSX記法より、Vue.js構文の方が覚える量が物理的に多いです。
それ以外のstateやRouter等の学習量は、React.jsとVue.jsでほぼ差異はありません。
詳細は以下の通りです。【React.jsで学習が必要なこと】
主に以下の学習が必要です。
- JSX記法
- state/Redux
- Router/hook等
【Vue.jsで学習が必要なこと】
主に以下の学習が必要です。
- Vue.js構文(各種ディレクティブ/computed/watch/method等)
- state/Vuex
- Router等
6.6.2 定性評価:Vue.jsの勝利(個人見解)
【評価】
Vue.jsの方が学習しやすいです。個人見解です。
【理由】
個人見解ですが、見慣れないJSX記法より、HTMLっぽく読めるVue.jsの方が、抵抗感無く学習できたからです。
※慣れてしまった今はJSX記法への抵抗感は無いですが、当初は抵抗感があったという意味です。6.7 優れたUIの提供しやすさ
【結論】
引き分けです。
【理由】
以下の通り、「優れたUI」を実装するコストに差異が無いためです。
【優れたUIの定義】
この記事では、ユーザーが考えずに操作できるUIを「優れたUI」と定義します。
※参考:Steve Krug著「Don't Make Me Think」優れたUIの具体例は以下です。
・どれがクリックできる要素か?が明確であること。
・説明がシンプル&明確であること。(自己満足な宣伝文句が無い)【評価観点】
まず、設計工程で「優れたUI」が設計されている必要があります。
その前提で、React.jsとVue.jsのどちらが実装コストが少ないか?で評価します。【評価】
実装コストに差異は無いでしょう。
- UIフレームワークで実現できるUIデザインの場合
- React.jsなら「Material-UI」等、Vue.jsなら「Vuetify」等で実装できます。
- 上記で実現できない凝ったUIデザインの場合
- React.js or Vue.jsに関わらず、UIフレームワークのカスタマイズや独自CSSの実装が必要です。
6.8 開発者が楽しい
開発者のモチベーションは大事ですね。
【結論】
引き分けです。
【理由】
開発者の主観で決まりますので引き分けです。
個人見解としては、どちらも楽しいです。7. テックリード/エンジニア募集中!
株式会社ビジョン・コンサルティングでは、アーキテクトや開発者を募集しています!
世界をより便利にすることに情熱を燃やし、新規事業部で新サービスを一緒に開発しませんか?
詳細はこちら!
- 投稿日:2020-09-11T17:28:34+09:00
【Vue.js】何気なく使っているthisとかcontextとかって結局なんなの??
オブジェクト 指すもの 使う場面 this Vueインスタンス 現Vueインスタンスを指定する時 context ・Vueインスタンス生成前のインスタンス・Storeインスタンス ・まだVueインスタンスが作られる前にVueインスタンスを使いたい時。・Storeメソッドを使いたい時。 thisオブジェクト
data
Vueインスタンスを指す
data () { return { email: '' } }, methods: { into () { this.email = 'foo@bar.com' } }Vueメソッド
Vueインスタンスを指す
methods: { async login () { const res = await this.$axios.$get('/login') } }contextオブジェクト
asyncData
仮のVueインスタンスを指す
async asyncData(context) { const posts = await context.$axios.$get('/posts') return { posts } },
{ posts }
とは{ posts: posts }
の略async asyncData (context) { const res = await context.$axios.$get('/posts/' + context.params.id) return { post: res.data } }Vuexのstoreメソッド
Storeインスタンスを指す
export const actions = { async login (context) { await context.commit('switchLogin') }) }
- 投稿日:2020-09-11T16:52:39+09:00
[nuxt].sync(propSync)を使って簡単に親子間コンポーネントで通信する
親から子コンポーネントに propsを使って値を送信し、子から親へ emitを使って変更を通知するような実装ってよくありますよね!
この時に受け渡す値の数だけ
props
とemit
が増えて行くので、やりたいことの割にコードが煩雑になってどうにかならないかという悩みを .sync演算子を使って解決しましたのでその備忘録として残します。また、 普段はnuxtにvue-property-decoratorを使って実装している場合についても記載します。
実行環境
vue: ^2.6.12
propsとemitを使ったやり方
親からpropsを使って値を子に渡し、子は値の変更を watchして
emit
を使い親に値を渡しています。parent.vue<template> <div class="container"> <h1>親コンポーネント</h1> <child :name="name" :email="email" @name-change="setName" @email-change="setEmail" /> <button @click="submit">送信</button> </div> </template> <script> import Child from '../components/Child'; const initName = '桃太郎' const initEmail = 'momotaro@test.test' export default { components: { Child }, data() { return { name: initName, email: initEmail, } }, methods: { submit() { alert(`name: ${this.name}, email: ${this.email}`) }, setName(val) { this.name = val; }, setEmail(val) { this.email = val; } } } </script>Child.vue<template> <div class="child-container"> <h2>子コンポーネント</h2> <div class="form"> <label> 名前 <input type="text" v-model="nameValue" /> </label> <label> メールアドレス <input type="text" v-model="emailValue" /> </label> </div> </div> </template> <script> export default { props: { name: { type: String, default: '' }, email: { type: String, default: '' } }, data() { return { nameValue: this.name, emailValue: this.email, } }, watch: { nameValue: function(val) { this.$emit('name-change', val); }, emailValue: function(val) { this.$emit('email-change', val); } } } </script>ただ親子で値を共有したいだけなのに、
親data()
、props
、子data()
とバケツリレーを行うことでやっと達成できました。
やっていることは簡単なのにコードが煩雑です。
このやり方でフォームの値がどんどん増えて行くと、大変なことになります。。。.sync演算子を使った場合
.sync演算子を使うことによって、
parent.vue
で$emitで受け取った値を更新する methodが必要なくなります。
また、Child.vue
でinput
イベントでemit
を使い通信を行うようにしました。parent.vue<template> <div class="container"> <h1>親コンポーネント</h1> <child :name.sync="name" :email.sync="email" /> <button @click="submit">送信</button> </div> </template> <script> import Child from '../../components/sync/Child'; const initName = '桃太郎' const initEmail = 'momotaro@test.test' export default { components: { Child }, data() { return { name: initName, email: initEmail, } }, methods: { submit() { alert(`name: ${this.name}, email: ${this.email}`) }, } } </script>Child.vue<template> <div class="child-container"> <h2>子コンポーネント</h2> <div class="form"> <label> 名前 <input type="text" :value="name" @input="$emit('update:name', $event.target.value)" /> </label> <label> メールアドレス <input type="text" :value="email" @input="$emit('update:email', $event.target.value)" /> </label> </div> </div> </template> <script> export default { props: { name: { type: String, default: '' }, email: { type: String, default: '' } }, } </script>スッキリしましたね!
同じ値が入っているpropertyや同じ動作を行うmethodを減らすことができました。vue-property-decoratorでpropSyncを使った場合
vue-property-decoratorでも
.sync
演算子が使えますので備忘録として残します。実行環境
nuxt: ^2.14.0
vue-property-decorater: ^9.0.0parent.vue<template> <div> <h1>親コンポーネント</h1> <child :nameValue.sync="name" :emailValue.sync="email" /> <button @click="submit"> 送信 </button> </div> </template> <script lang="ts"> import {Vue, Component} from 'vue-property-decorator'; import Child from '../components/child.vue'; const initName = '桃太郎' const initEmail = 'momotaro@test.test' @Component({ components: { Child } }) export default class Parent extends Vue { name: string = initName; email: string = initEmail; submit(): void { alert(`name: ${this.name}, email: ${this.email}`); } } </script>Child.vue<template> <div> <h2>子コンポーネント</h2> <div> <label> 名前 <input type="text" v-model="name" /> </label> <label> メールアドレス <input type="text" v-model="email" /> </label> </div> </div> </template> <script lang="ts"> import {Vue, Component, PropSync} from 'vue-property-decorator'; @Component export default class Child extends Vue { @PropSync('nameValue', { type: String }) name!: string @PropSync('emailValue', { type: String }) email!: string } </script>
Child.vue
にemit
を書くこともなくなるのでスッキリしますね!
- 投稿日:2020-09-11T16:34:58+09:00
Vue.jsでTypeScriptを始めよう(はじめかた)
はじめに
おはようございます。こんにちは。こんばんは。
Watatakuです。
今回はVue.jsからはじめるTypescriptと言うことでVue.jsにTypeScriptを導入して同時にTypeScriptにも触れていこうじゃないかと思います。
*
この記事は、JavaScriptからTypeScriptにそろそろ移行したい方向けに書いています。JavaScript自体がちょっとあやふやでも他のオブジェクト指向系の言語の経験があれば理解できるように書いていきます。TypeScriptとは
まずはTypeScriptはなんぞや?と言う話です。
TypeScriptは、JavaScriptの代替となるべくマイクロソフトによって開発されたオープンソースのプログラミング言語です。
その特徴は、大規模なアプリケーションの開発に耐えるように、(C++やJavaなどの)クラスベースのオブジェクト指向プログラムの機能や、変数への静的な型の指定などを取り込んで、設計されています。それはJavaScriptの標準仕様であるECMAScript2015以降の新機能を先取りした形にもなっています。「型定義できるJavaScript」。
インストール
※
Node.js
,vue-cli
はインストール済みとして進めていきます。$ vue create プロジェクト名ここからぽちぽちしていきます。
まずは、インストール方法を「デフォルト」か「手動」か選択するよう確認されます。
Vue CLI v3.4.0 ? Please pick a preset: default (babel, eslint) > Manually select featuresここでは「マニュアル」を選択します。
Manually select featuresを選んで Enter を押します。
※デフォルトを選択するとデフォルトなプロジェクトができます。←いやそのままw次にプロジェクトに必要な機能を選択します。
下記の*がついた機能をインストールします。スペースキーでトグルしてください。? Check the features needed for your project: >(*) Babel (*) TypeScript ( ) Progressive Web App (PWA) Support (*) Router (*) Vuex (*) CSS Pre-processors (*) Linter / Formatter (*) Unit Testing ( ) E2E Testing選択したら Enter キーを押します。
? Use class-style component syntax? (Y/n)
クラススタイルでの記述によってコンポーネントを作成するので、「Use class-style component syntax?」はYesを選択します。
router のヒストリーモード
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)
ヒストリーモードを使用するので Y キーを入力して Enter を押します。
CSS プリプロセッサ
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys) Sass/SCSS (with dart-sass) Sass/SCSS (with node-sass) Less > StylusStylusを選択した状態で Enter を押します。
ESLint
? Pick a linter / formatter config: (Use arrow keys) > ESLint with error prevention only ESLint + Airbnb config ESLint + Standard config ESLint + Prettierエラー防止のみのESLint with error prevention onlyを選択して Enter を押します。
Lint 実行タイミング
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection) >(*) Lint on save ( ) Lint and fix on commit保存時に Lint を実行するためLint on saveのみチェックを入れて Enter を押します。
単体テスト
? Pick a unit testing solution: (Use arrow keys) > Mocha + Chai JestユニットテストはMocha + Chaiを選択して Enter を押します。
設定ファイル
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys) > In dedicated config files In package.json設定ファイルは個別に管理するのでIn dedicated config filesを選択して Enter を押します。
プリセットの保存
? Save this as a preset for future projects? (y/N)
次回のインストールのためにこの設定を保存しておきます。y キーを入力して Enter キーを押します。
? Save preset as: example
ここではプリセット名をexampleと入力します。
Enter でインストールを開始します。
※インストール選択画面で今回選択しなかったのもを選択するとここでは出てこなかった質問も出ますが全てEnter
で問題ないと思います。インストールが完了すれば起動してみましょう。
起動
> cd プロジェクト名 > npm run serve
localhost:8080
にアクセスし、このwelcomeページが出てきたら成功です。お疲れ様でした。
TIPS
以前、Vue.jsについての基礎(インストール)の方で
vueプロジェクト作成コマンドで$ vue init webpack プロジェクト名
でプロジェクトを作れと紹介しましたが、
今回の$ vue create プロジェクト名
の方が推奨らしいです。
因みに両者の違いはと言いますと特には大して変わらないです。
ただ、vue initはvue-cliの2.0系から使えますが、vue createはvue-cliの3.0系からしか使えないと言う点です。
個人的にvue initよりvue createで作った方が初めからVue-routerやVuexなどを選択すれば自動的にインストールされるのでおすすめです。以上。
最後に
解説が浅いところとか、間違い等があると思いますのでその時はアドバイス等お願いします。
次回以降にTypescriptの書き方であったりVueファイルの中でのTypescriptの使い方をやっていきましょう。最後まで読んでいただきありがとうございました。
Twitterやってます。良ければチェックして見てください。
- 投稿日:2020-09-11T13:08:46+09:00
railsにVue.jsを導入しようとしたらエラーがでた物語
環境
・Ruby 2.6.6
・Rails 6.0.3.2
・Docker/docker-composeやったこと
https://qiita.com/Moo_Moo_Farm/items/afacfe4349af6a106253
参考URLを見ながらVue.jsを導入しようとすると、以下のエラーが発生。% docker-compose run web rails new . --force --no-deps --database=mysql --skip-test --webpack=vue create README.md create Rakefile create .ruby-version #~~~~~~~~~なんやらなんやら。。。~~~~~~~~~~~~~~~ Webpacker successfully installed ? ? rails webpacker:install:vue error Couldn't find an integrity file error Found 1 errors. ======================================== Your Yarn packages are out of date! Please run `yarn install --check-files` to update. ======================================== To disable this check, please change `check_yarn_integrity` to `false` in your webpacker config file (config/webpacker.yml). yarn check v1.22.5 info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.「無事に
Webpacker successfully installed
が出たしやったー!」と思ったら、なんやらエラーが出ている。。。解決方法
Please run yarn install --check-files to update.
と言っているので、その通りに実行% docker-compose run web rails new . --force --no-deps --database=mysql --skip-test --webpack=vue Webpacker successfully installed ? ? rails webpacker:install:vue Copying vue loader to config/webpack/loaders create config/webpack/loaders/vue.js Adding vue loader plugin to config/webpack/environment.js insert config/webpack/environment.js insert config/webpack/environment.js Adding vue loader to config/webpack/environment.js insert config/webpack/environment.js insert config/webpack/environment.js Updating webpack paths to include .vue file extension insert config/webpacker.yml Copying the example entry file to /vue_app/app/javascript/packs create app/javascript/packs/hello_vue.js Copying Vue app file to /vue_app/app/javascript/packs create app/javascript/app.vue Installing all Vue dependencies run yarn add vue vue-loader vue-template-compiler from "." #~~~~~~~~~なんやらなんやら。。。~~~~~~~~~~~~~~~ Webpacker now supports Vue.js ?無事に成功。
yarn install --check-files
の役目は何?https://classic.yarnpkg.com/ja/docs/cli/install/
yarnで入ってるパッケージが古いのよ!って怒られてるからアップデートでもしてるのかしら?と思ったけど、参考URLには以下のように説明されている。node_modules に既にインストールされたファイルが削除されていないことを確認します。
う〜ん、根本的になぜ解決できたのかよく分からん。
- 投稿日:2020-09-11T12:53:43+09:00
ParcelでVuetify環境
きっかけ
- Vue CLI のインストール
- Vue UI のインストール
- Nuxt のインストール
- Webpack のインストール
(※後々考えたら多分「の」は「環境での」っていうことなんだろうなぁって思う)
って書いててVue CLI入れないと環境つくれないのかなぁって思ってたのですが、Parcelで試してみたらあっさりできたので記事にして残します。
Parcel
Parcelの設定はクイックスタート
npm install parcel-bundler --save-dev
をするぐらいVuetify
Parcelが勝手にインストールなどしてくれるので不要
ファイル内容
index.html<html> <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@5.x/css/materialdesignicons.min.css" rel="stylesheet"> <title>Parcel - Vue</title> </head> <body> <div id="app"></div> <script src="./index.js"></script> </body> </html>index.jsimport Vue from 'vue'; import vuetify from './plugins/vuetify' import App from './components/App.vue'; new Vue({ vuetify, render: createElement => createElement(App) }).$mount('#app');components/app.vue<template> <alert></alert> </template> <script lang="ts"> import Vue from "vue"; import Alert from './Alert.vue'; export default Vue.extend({ components: { Alert, }, }); </script> <style lang="scss" scoped> .container { color: green; } </style>components/Alert.vue<template> <v-app id="inspire"> <div> <v-alert type="success"> I'm a success alert. </v-alert> <v-alert type="info"> I'm an info alert. </v-alert> <v-alert type="warning"> I'm a warning alert. </v-alert> <v-alert type="error"> I'm an error alert. </v-alert> </div> <v-card class="mx-auto" max-width="344" outlined > <v-list-item three-line> <v-list-item-content> <div class="overline mb-4">OVERLINE</div> <v-list-item-title class="headline mb-1">Headline 5</v-list-item-title> <v-list-item-subtitle>Greyhound divisely hello coldly fonwderfully</v-list-item-subtitle> </v-list-item-content> <v-list-item-avatar tile size="80" color="grey" ></v-list-item-avatar> </v-list-item> <v-card-actions> <v-btn text>Button</v-btn> <v-btn text>Button</v-btn> </v-card-actions> </v-card> </v-app> </template>plugins/vuetify.jsimport Vue from 'vue'; import Vuetify from 'vuetify'; import 'vuetify/dist/vuetify.min.css'; Vue.use(Vuetify); const opts = {}; export default new Vuetify(opts);結果
- 投稿日:2020-09-11T10:20:54+09:00
Vue.js ウォッチャの使い方が分かった気がする
この記事について
Vue.jsを必死に学んでる初心者ですので、間違えがあればぜひ教えていただけるととても嬉しいです!!
ウォッチャとは?
データの変更を監視してくれる機能のこと。
データが変更されたときに実行したいハンドラを登録しておけば、Vueが自動的にデータの変化を検知してハンドラを実行してくれる。
大事なのがデータが変更されたときに呼び出されること!!!!どんなコードを書くのか
以下のようなコードであれば、ブラウザで削除ボタンを押していくと、
onDeleteItem
メソッドの処理が行われる。
そしてウォッチャで指定しているデータが0になれば、messageを変えるようにしている。qiita.js#書式 #watch: {監視したいデータ名(プロパティ): 関数} var vm = new Vue({ el: '#app', data: { message: '', stock : 10 }, methods: { onDeleteItem: function() { this.stock -= 1 } }, watch: { stock: function(newStock, oldStock) { if(newStock == 0) { this.message = "売り切れ" } } } })qiita.html<body> <div id="app"> <template v-if="stock >= 1"> <button v-on:click="onDeleteItem">削除</button> <span> 残り{{stock}}</span> </template> {{message}} </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script> <script src="main.js"></script> </body>なんとなく算出プロパティでもできそうやけど。。。
算出プロパティの役目として加工したデータを返すことにあるんやけど、なんでわざわざウォッチャがあるのか。
それは返したいデータがアプリの外側にある場合、ハンドラの処理が終わるまでデータが表示されないのでユーザーにとてtは不便になる。そこで、ウォッチャがリアルタイムにデータを監視しているので非同期通信を使ってユーザーエクスペリエンスを高めてくれる。まとめ
ユーザーの操作によって、高い頻度で処理が発生するようなところで使ったらええんやな