20210728のvue.jsに関する記事は5件です。

vue.jsの使い方の基礎(v-〇〇の使い方)

久々にvueを触ったらわからな過ぎて「も~!」って言いすぎて牛になりました。 完全初心者としてリセットし、公式ドキュメント読みながらふ~んへ~と手を動かしていましたが復習と自分用教科書として書いていきます。アウトプットするとより一層覚えますよね。 書き方どうやってやんだっけってとかとか参考にしてくれる方がいたら超嬉しいです。 基本的に[公式ドキュメント]やっていることは同じですのでそちらを見たほうが早いかもしれませんが。。。 環境どうやって作んねんというひとは環境構築の記事を以前書いたのでもしよかったら参考にしてください。 ドキュメントに沿って進めていきます(仕事終わりに少しずつ勉強しているので随時更新です) この記事ではファイル名をsample.vueとしていますが、プロジェクト作成時のApp.vueの内容を変えれば同様の動きになります。 間違いや認識違いを発見した方はコメントなどで教えていただけると嬉しいです! 宣言的レンダリング【{{ hoge }}】 Vue.js のコアは、単純なテンプレート構文を使って宣言的にデータを DOM に描画することを可能にするシステムです dataに入れた情報を表示してくれます。DBとってきた情報をdataにセットすれば動的に変えたりできるわけですね。 例えば関数でやんやしてmessageの内容を変更したら、messageが変わった時点で表示も自動で変わります。 以下のサンプルでは画面に「Hello!!vue.js:)」と表示されます。 sample.vue <template> <div id="app"> <p>{{ message }}</p> </div> </template> <script> export default { data() { return { message: "Hello!!vue.js:)" } }, } </script> 条件分岐【v-if】 条件一致の場合はこの文言を表示したいときに便利な書き方。 以下のサンプルでは画面に、「Hello!!vue.js:)」と「resultがtrue」が表示されます。 data内のresultをfalseにすると「resultがtrue」は表示されません。 sample.vue <template> <div id="app"> <p>{{ message }}</p> <p v-if="result">resultがtrue</p> </div> </template> <script> export default { data() { return { message: "Hello!!vue.js:)", result: true } }, } </script> ループ【v-for】 アイテムのリストを配列内のデータを使って表示することができます めっちゃ便利やん。。。例えば、従業員一覧を出すときに面倒な関数を書かなくても、データをJSON型ではいてセットすればOKってことです。(認識違ってたらすみません) 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p v-for="color in colors" v-bind:key="color.name">{{ color.name }}</p> </div> </template> <script> export default { data() { return { result: true, colors:[ {name: 'red'}, {name: 'blue'}, {name: 'yellow'} ] } }, } </script> 実行結果 keyがないとエラーになる 最初以下のように書いていたらエラーが出た sample.vue <template> <div id="app"> <p v-for="color in colors">{{ color.name }}</p> </div> </template> <script> export default { data() { return { result: true, colors:[ {name: 'red'}, {name: 'blue'}, {name: 'yellow'} ] } }, } </script> エラー内容 error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key key属性が必要ってもう少し後のほうのドキュメントに書いてありました。なるほど~ ユーザー入力の制御【v-on】 v-on ディレクティブを使ってイベントリスナを加え、Vue インスタンスのメソッドを呼び出すことができます イベントリスナを加えるの楽になりそうですね。 以下サンプルです。ボタンをクリックしたら、表示される文字が「こんにちは」から「ボタンを押しました」に代わります。 宣言的レンダリングでも説明しましたが、messageが変わった時点で表示も自動で変わります。DOMをやってくれるのはとっても助かりますね。 sample.vue <template> <div id="app"> <p>{{ message }}</p> <button v-on:click="changeText()">ボタン</button> </div> </template> <script> export default { data() { return { result: true, message: "こんにちは" } }, methods:{ changeText(){ this.message = "ボタンを押しました" } } } </script> 補足 以下のように書いても同じ挙動になります sample.vue <button v-on:click="changeText()">ボタン</button> | | V <button @click="changeText()">ボタン</button> 双方向バインディング【v-model】 vueがもつ情報(以下サンプルだとmessage)とアプリケーション状態(以下サンプルだと入力のフィールド)のバインディング(結びつけ)ができます。 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p>{{ message }}</p> <input type="text" v-model="message"/> </div> </template> <script> export default { data() { return { message: "こんにちは" } } } </script> 実行結果 入力フィールドと、表示の文言が連動しています。 フィールドの内容をかえると文言も変わります。 コンポーネント化※作成中 コンポーネントシステムは Vue.js におけるもうひとつの重要な抽象概念です。「小さく、自己完結的で、(多くの場合)再利用可能なコンポーネント」を組み合わせることで、大規模アプリケーションを構築することが可能になります。 vueの強いところですね。 例えば、webページに共通のヘッダーフッターをすべてのページに出すとき、すべてのファイルにHTML分ちまちま書いたりしたくないですよね。このヘッダーフッターを再利用できるパーツにしちゃおう!という感じです。 ※コンポーネントについては長くなりそうなので別の記事にまとめようかと思います。時間あるときに作成するのでできたらリンク載せておきます(いつになるかな。。。) v-onceディレクティブ データ変更時の更新はおこなわず、一度だけ展開することができます 何度も書いてますが{{ hoge }}を利用した場合、データが変われば表示も変わりますよね。この表示を1回したらあとは変えないぞ!というときに使います。画面表示時に最初のバインディングが行われて、それ以降は静的になります。 v-onの時に使用したコードにv-onceを追加してみます。 sample.vue <template> <div id="app"> <p v-once>{{ message }}</p> ----ここにv-onceを追加 <button @click="changeText()">ボタン</button> </div> </template> <script> export default { data() { return { result: true, message: "こんにちは" } }, methods:{ changeText(){ this.message = "ボタンを押しました" } } } </script> 実行してボタンを押しても、「こんにちは」のまま変わらなくなりました。 生のHTMLを出力【v-html】 dataに生のHTML文をセットして表示させることができます。 そのまま{{ }}を使用すると、プレーンなテキストとして扱われるので、v-htmlを使用する必要があります。 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p>{{ sampleHtml }}</p> <p v-html="sampleHtml"></p> </div> </template> <script> export default { data() { return { sampleHtml: '<span style="color:red">HTML文です</span>' } } } </script> 補足 この p のコンテンツは sampleHtml プロパティの値に置き換えられ、プレーンな HTML として解釈されます。Vue は、文字列ベースのテンプレートエンジンではないので、v-html をテンプレート部品を構成して使用できないことに注意しましょう。代わりに、 UI の再利用や組み合わせのための基礎として、コンポーネントを利用することが好ましいです v-htmlを使用する場面があまり思い浮かばないのですが、何度も使用するためdata化するならコンポーネントで作ったほうがいいよってことみたいです。 XSS 脆弱性を容易に引き起こすので、ウェブサイトで動的に任意のHTMLを描画することは、非常に危険です。信頼できるコンテンツにだけ HTML 展開を利用してください。ユーザーから提供されたコンテンツに対しては決して使用してはいけません。 こんな記載もありました。たしかにウェブで展開すると、悪い人がサイトに飛ぶはずのボタンをウイルス流すボタンに変えちゃったり、、、しかも見た目は変わらない、、、みたいなことありそうですね。よっぽどのことがない限り使わないほうがいいのかしら。 続きはまた明日。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue.jsの使い方の基礎

久々にvueを触ったらわからな過ぎて「も~!」って言いすぎて牛になりました。 完全初心者としてリセットし、公式ドキュメント読みながらふ~んへ~と手を動かしていましたが復習と自分用教科書として書いていきます。アウトプットするとより一層覚えますよね。 書き方どうやってやんだっけってときに参考にしてくれる方がいたら超嬉しいです。 基本的に[公式ドキュメント]やっていることは同じですのでそちらを見たほうが早いかもしれませんが。。。 環境どうやって作んねんというひとは環境構築の記事を以前書いたのでもしよかったら参考にしてください。 ドキュメントに沿って進めていきます(仕事終わりや合間に少しずつ勉強しているので随時更新です) この記事ではファイル名をsample.vueとしていますが、プロジェクト作成時のApp.vueの内容を変えれば同様の動きになります。 コードの間違いや、私の説明で認識違い、もっとこう書いたほうがいいよ~などなどありましたらコメントで教えていただけると嬉しいです! 宣言的レンダリング【{{ hoge }}】 Vue.js のコアは、単純なテンプレート構文を使って宣言的にデータを DOM に描画することを可能にするシステムです dataに入れた情報を表示してくれます。DBとってきた情報をdataにセットすれば動的に変えたりできるわけですね。 例えば関数でやんやしてmessageの内容を変更したら、messageが変わった時点で表示も自動で変わります。 以下のサンプルでは画面に「Hello!!vue.js:)」と表示されます。 sample.vue <template> <div id="app"> <p>{{ message }}</p> </div> </template> <script> export default { data() { return { message: "Hello!!vue.js:)" } }, } </script> JavaScript 式の使用 実際には Vue.js は全てのデータバインディング内部で JavaScript 式を完全にサポートします: {{ }}内にJavaScriptの式を書くことができます。 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p>{{ message }}</p> <p>{{ number + 1 }}</p> <p>{{ result ? 'YES' : 'NO' }}</p> <p>{{ message.split('').reverse().join('') }}</p> </div> </template> <script> export default { data() { return { message: "Hello!!vue.js:)", number: 1, result: true } }, } </script> 実行結果 注意点1 これらの式は、Vue インスタンスが所有するデータスコープ内で JavaScript として評価されます。制限として、それぞれのバインディングは、単一の式だけ含むことができるというものです 単一式は使えるけど以下のような式は使えないようです。 {{ var a = 1 }} {{ if (ok) { return message } }} 注意点2 テンプレート式はサンドボックスで、Math や Date といった ホワイトリストにあるグローバルオブジェクト だけにアクセスできます。テンプレート式内でユーザーが定義したグローバルオブジェクトにアクセスしようとしてはいけません。 条件分岐【v-if】 条件一致の場合はこの文言を表示したいときに便利な書き方。 以下のサンプルでは画面に、「Hello!!vue.js:)」と「resultがtrue」が表示されます。 data内のresultをfalseにすると「resultがtrue」は表示されません。 sample.vue <template> <div id="app"> <p>{{ message }}</p> <p v-if="result">resultがtrue</p> </div> </template> <script> export default { data() { return { message: "Hello!!vue.js:)", result: true } }, } </script> ループ【v-for】 アイテムのリストを配列内のデータを使って表示することができます めっちゃ便利やん。。。例えば、従業員一覧とか何かを一覧で出すときに面倒な関数を書かなくても、データをJSONではいてセットすればOKってことです。(認識違ってたらすみません) 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p v-for="color in colors" v-bind:key="color.name">{{ color.name }}</p> </div> </template> <script> export default { data() { return { result: true, colors:[ {name: 'red'}, {name: 'blue'}, {name: 'yellow'} ] } }, } </script> 実行結果 keyがないとエラーになる 最初以下のように書いていたらエラーが出た sample.vue <template> <div id="app"> <p v-for="color in colors">{{ color.name }}</p> </div> </template> <script> export default { data() { return { result: true, colors:[ {name: 'red'}, {name: 'blue'}, {name: 'yellow'} ] } }, } </script> エラー内容 error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key key属性が必要ってもう少し後のほうのドキュメントに書いてありました。なるほど~ ユーザー入力の制御【v-on】 v-on ディレクティブを使ってイベントリスナを加え、Vue インスタンスのメソッドを呼び出すことができます イベントリスナを加えるの楽になりそうですね。 以下サンプルです。ボタンをクリックしたら、表示される文字が「こんにちは」から「ボタンを押しました」に代わります。 宣言的レンダリングでも説明しましたが、messageが変わった時点で表示も自動で変わります。DOMをやってくれるのはとっても助かりますね。 sample.vue <template> <div id="app"> <p>{{ message }}</p> <button v-on:click="changeText()">ボタン</button> </div> </template> <script> export default { data() { return { result: true, message: "こんにちは" } }, methods:{ changeText(){ this.message = "ボタンを押しました" } } } </script> 動的引数 バージョン 2.6.0 から、角括弧で囲むことで JavaScript 式をディレクティブの引数に使うこともできます よくわからないので公式を参考に書いてみた。 以下サンプルです。先ほどのコードと同じくボタンをクリックしたら、表示される文字が「こんにちは」から「ボタンを押しました」に代わります。 sample.vue <template> <div id="app"> <p>{{ message }}</p> <button v-on:[event]="changeText()">ボタン</button> </div> </template> <script> export default { data() { return { message: "こんにちは", event: "click" } }, methods:{ changeText(){ this.message = "ボタンを押しました" } } } </script> v-on:click="changeText()"では、クリックされたらchangeText()のメソッドを呼んでねという書き方。 今回のv-on:[event]では、なんかしらのイベントが起こったらchangeText()のメソッドを呼んでね。なんのイベントかはdataのeventを参照してね。という書き方。 のちのちコードを変えたりする可能性も加味して使い分けるのがよさそうですね。その使い分けが難しいんだけどね。 省略記法 sample.vue <!-- 完全な構文 --> <button v-on:click="changeText()">ボタン</button> <!-- 省略記法 --> <button @click="changeText()">ボタン</button> <!-- 動的引数の省略記法 (2.6.0 以降) --> <button @[event]="changeText()">ボタン</button> 双方向バインディング【v-model】 vueがもつ情報(以下サンプルだとmessage)とアプリケーション状態(以下サンプルだと入力のフィールド)のバインディング(結びつけ)ができます。 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p>{{ message }}</p> <input type="text" v-model="message"/> </div> </template> <script> export default { data() { return { message: "こんにちは" } } } </script> 実行結果 入力フィールドと、表示の文言が連動しています。 フィールドの内容をかえると文言も変わります。 コンポーネント化※作成中 コンポーネントシステムは Vue.js におけるもうひとつの重要な抽象概念です。「小さく、自己完結的で、(多くの場合)再利用可能なコンポーネント」を組み合わせることで、大規模アプリケーションを構築することが可能になります。 vueの強いところですね。 例えば、webページに共通のヘッダーフッターをすべてのページに出すとき、すべてのファイルにHTML分ちまちま書いたりしたくないですよね。このヘッダーフッターを再利用できるパーツにしちゃおう!という感じです。 ※コンポーネントについては長くなりそうなので別の記事にまとめようかと思います。時間あるときに作成するのでできたらリンク載せておきます(いつになるかな。。。) v-onceディレクティブ データ変更時の更新はおこなわず、一度だけ展開することができます 何度も書いてますが{{ hoge }}を利用した場合、データが変われば表示も変わりますよね。この表示を1回したらあとは変えないぞ!というときに使います。画面表示時に最初のバインディングが行われて、それ以降は静的になります。 v-onの時に使用したコードにv-onceを追加してみます。 sample.vue <template> <div id="app"> <p v-once>{{ message }}</p> ----ここにv-onceを追加 <button @click="changeText()">ボタン</button> </div> </template> <script> export default { data() { return { result: true, message: "こんにちは" } }, methods:{ changeText(){ this.message = "ボタンを押しました" } } } </script> 実行してボタンを押しても、「こんにちは」のまま変わらなくなりました。 生のHTMLを出力【v-html】 dataに生のHTML文をセットして表示させることができます。 そのまま{{ }}を使用すると、プレーンなテキストとして扱われるので、v-htmlを使用する必要があります。 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p>{{ sampleHtml }}</p> <p v-html="sampleHtml"></p> </div> </template> <script> export default { data() { return { sampleHtml: '<span style="color:red">HTML文です</span>' } } } </script> 補足 この p のコンテンツは sampleHtml プロパティの値に置き換えられ、プレーンな HTML として解釈されます。Vue は、文字列ベースのテンプレートエンジンではないので、v-html をテンプレート部品を構成して使用できないことに注意しましょう。代わりに、 UI の再利用や組み合わせのための基礎として、コンポーネントを利用することが好ましいです v-htmlを使用する場面があまり思い浮かばないのですが、何度も使用するためdata化するならコンポーネントで作ったほうがいいよってことみたいです。 XSS 脆弱性を容易に引き起こすので、ウェブサイトで動的に任意のHTMLを描画することは、非常に危険です。信頼できるコンテンツにだけ HTML 展開を利用してください。ユーザーから提供されたコンテンツに対しては決して使用してはいけません。 こんな記載もありました。たしかにウェブで展開すると、悪い人がサイトに飛ぶはずのボタンをウイルス流すボタンに変えちゃったり、、、しかも見た目は変わらない、、、みたいなことがありうるのかな?よっぽどのことがない限り使わないほうがいい気がします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue.jsの使い方の基礎#1

久々にvueを触ったらわからな過ぎて「も~!」って言いすぎて牛になりました。 完全初心者としてリセットし、公式ドキュメント読みながらふ~んへ~と手を動かしていましたが復習と自分用教科書として書いていきます。アウトプットするとより一層覚えますよね。 書き方どうやってやんだっけってときに参考にしてくれる方がいたら超嬉しいです。 基本的に[公式ドキュメント]やっていることは同じですのでそちらを見たほうが早いかもしれませんが。。。 環境どうやって作んねんというひとは環境構築の記事を以前書いたのでもしよかったら参考にしてください。 ドキュメントに沿って進めていきます(はじめに~テンプレート構文まで) この記事ではファイル名をsample.vueとしていますが、プロジェクト作成時のApp.vueの内容を変えれば同様の動きになります。 コードの間違いや、私の説明で認識違い、もっとこう書いたほうがいいよ~などなどありましたらコメントで教えていただけると嬉しいです! 宣言的レンダリング【{{ hoge }}】 Vue.js のコアは、単純なテンプレート構文を使って宣言的にデータを DOM に描画することを可能にするシステムです dataに入れた情報を表示してくれます。DBとってきた情報をdataにセットすれば動的に変えたりできるわけですね。 例えば関数でやんやしてmessageの内容を変更したら、messageが変わった時点で表示も自動で変わります。 以下のサンプルでは画面に「Hello!!vue.js:)」と表示されます。 sample.vue <template> <div id="app"> <p>{{ message }}</p> </div> </template> <script> export default { data() { return { message: "Hello!!vue.js:)" } }, } </script> JavaScript 式の使用 実際には Vue.js は全てのデータバインディング内部で JavaScript 式を完全にサポートします: {{ }}内にJavaScriptの式を書くことができます。 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p>{{ message }}</p> <p>{{ number + 1 }}</p> <p>{{ result ? 'YES' : 'NO' }}</p> <p>{{ message.split('').reverse().join('') }}</p> </div> </template> <script> export default { data() { return { message: "Hello!!vue.js:)", number: 1, result: true } }, } </script> 実行結果 注意点1 これらの式は、Vue インスタンスが所有するデータスコープ内で JavaScript として評価されます。制限として、それぞれのバインディングは、単一の式だけ含むことができるというものです 単一式は使えるけど以下のような式は使えないようです。 {{ var a = 1 }} {{ if (ok) { return message } }} 注意点2 テンプレート式はサンドボックスで、Math や Date といった ホワイトリストにあるグローバルオブジェクト だけにアクセスできます。テンプレート式内でユーザーが定義したグローバルオブジェクトにアクセスしようとしてはいけません。 条件分岐【v-if】 条件一致の場合はこの文言を表示したいときに便利な書き方。 以下のサンプルでは画面に、「Hello!!vue.js:)」と「resultがtrue」が表示されます。 data内のresultをfalseにすると「resultがtrue」は表示されません。 sample.vue <template> <div id="app"> <p>{{ message }}</p> <p v-if="result">resultがtrue</p> </div> </template> <script> export default { data() { return { message: "Hello!!vue.js:)", result: true } }, } </script> ループ【v-for】 アイテムのリストを配列内のデータを使って表示することができます めっちゃ便利やん。。。例えば、従業員一覧とかを一覧で出すときに面倒な関数を書かなくても、データをJSONではいてセットすればOKってことです。(認識違ってたらすみません) 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p v-for="color in colors" v-bind:key="color.name">{{ color.name }}</p> </div> </template> <script> export default { data() { return { result: true, colors:[ {name: 'red'}, {name: 'blue'}, {name: 'yellow'} ] } }, } </script> 実行結果 keyがないとエラーになる 最初以下のように書いていたらエラーが出た sample.vue <template> <div id="app"> <p v-for="color in colors">{{ color.name }}</p> </div> </template> <script> export default { data() { return { result: true, colors:[ {name: 'red'}, {name: 'blue'}, {name: 'yellow'} ] } }, } </script> エラー内容 error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key key属性が必要ってもう少し後のほうのドキュメントに書いてありました。なるほど~ ユーザー入力の制御【v-on】 v-on ディレクティブを使ってイベントリスナを加え、Vue インスタンスのメソッドを呼び出すことができます イベントリスナを加えるの楽になりそうですね。 以下サンプルです。ボタンをクリックしたら、表示される文字が「こんにちは」から「ボタンを押しました」に代わります。 宣言的レンダリングでも説明しましたが、messageが変わった時点で表示も自動で変わります。DOMをやってくれるのはとっても助かりますね。 sample.vue <template> <div id="app"> <p>{{ message }}</p> <button v-on:click="changeText()">ボタン</button> </div> </template> <script> export default { data() { return { result: true, message: "こんにちは" } }, methods:{ changeText(){ this.message = "ボタンを押しました" } } } </script> 動的引数 バージョン 2.6.0 から、角括弧で囲むことで JavaScript 式をディレクティブの引数に使うこともできます よくわからないので公式を参考に書いてみた。 以下サンプルです。先ほどのコードと同じくボタンをクリックしたら、表示される文字が「こんにちは」から「ボタンを押しました」に代わります。 sample.vue <template> <div id="app"> <p>{{ message }}</p> <button v-on:[event]="changeText()">ボタン</button> </div> </template> <script> export default { data() { return { message: "こんにちは", event: "click" } }, methods:{ changeText(){ this.message = "ボタンを押しました" } } } </script> v-on:click="changeText()"では、クリックされたらchangeText()のメソッドを呼んでねという書き方。 今回のv-on:[event]="changeText()"では、なんかしらのイベントが起こったらchangeText()のメソッドを呼んでね。なんのイベントかはdataのeventを参照してねという書き方。 のちのちコードを変えたりする可能性も加味して使い分けるのがよさそうですね。その使い分けが難しいんだけどね。 省略記法 以下のように省略して書くことができます。 便利だけど複数人で開発するときは記法のルールを決めたほうがコードが美しくなりそう。 sample.vue <!-- 完全な構文 --> <button v-on:click="changeText()">ボタン</button> <!-- 省略記法 --> <button @click="changeText()">ボタン</button> <!-- 動的引数の省略記法 (2.6.0 以降) --> <button @[event]="changeText()">ボタン</button> 超余談ですが、すべて独学なのでコードがあまり綺麗くなかったんですが、リーダブルコードという本を読んだらほ~!ってなりました。劇的改善!とまではいかないけど書き方を考えるようになりました。ありがとうオライリー。 双方向バインディング【v-model】 vueがもつ情報(以下サンプルだとmessage)とアプリケーション状態(以下サンプルだと入力のフィールド)のバインディング(結びつけ)ができます。 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p>{{ message }}</p> <input type="text" v-model="message"/> </div> </template> <script> export default { data() { return { message: "こんにちは" } } } </script> 実行結果 入力フィールドと、表示の文言が連動しています。 フィールドの内容をかえると文言も変わります。 コンポーネント化※作成中 コンポーネントシステムは Vue.js におけるもうひとつの重要な抽象概念です。「小さく、自己完結的で、(多くの場合)再利用可能なコンポーネント」を組み合わせることで、大規模アプリケーションを構築することが可能になります。 vueの強いところですね。 例えば、webページに共通のヘッダーフッターをすべてのページに出すとき、すべてのファイルにHTML分ちまちま書いたりしたくないですよね。このヘッダーフッターを再利用できるパーツにしちゃおう!という感じです。 ※コンポーネントについては長くなりそうなので別の記事にまとめようかと思います。時間あるときに作成するのでできたらリンク載せておきます(いつになるかな。。。) v-onceディレクティブ データ変更時の更新はおこなわず、一度だけ展開することができます 何度も書いてますが{{ hoge }}を利用した場合、データが変われば表示も変わりますよね。この表示を1回したらあとは変えないぞ!というときに使います。画面表示時に最初のバインディングが行われて、それ以降は静的になります。 v-onの時に使用したコードにv-onceを追加してみます。 sample.vue <template> <div id="app"> <p v-once>{{ message }}</p> ----ここにv-onceを追加 <button @click="changeText()">ボタン</button> </div> </template> <script> export default { data() { return { result: true, message: "こんにちは" } }, methods:{ changeText(){ this.message = "ボタンを押しました" } } } </script> 実行してボタンを押しても、「こんにちは」のまま変わらなくなりました。 生のHTMLを出力【v-html】 dataに生のHTML文をセットして表示させることができます。 そのまま{{ }}を使用すると、プレーンなテキストとして扱われるので、v-htmlを使用する必要があります。 以下サンプルと実行結果 sample.vue <template> <div id="app"> <p>{{ sampleHtml }}</p> <p v-html="sampleHtml"></p> </div> </template> <script> export default { data() { return { sampleHtml: '<span style="color:red">HTML文です</span>' } } } </script> 補足 この p のコンテンツは sampleHtml プロパティの値に置き換えられ、プレーンな HTML として解釈されます。Vue は、文字列ベースのテンプレートエンジンではないので、v-html をテンプレート部品を構成して使用できないことに注意しましょう。代わりに、 UI の再利用や組み合わせのための基礎として、コンポーネントを利用することが好ましいです v-htmlを使用する場面があまり思い浮かばないのですが、何度も使用するためdata化するならコンポーネントで作ったほうがいいよってことみたいです。 XSS 脆弱性を容易に引き起こすので、ウェブサイトで動的に任意のHTMLを描画することは、非常に危険です。信頼できるコンテンツにだけ HTML 展開を利用してください。ユーザーから提供されたコンテンツに対しては決して使用してはいけません。 こんな記載もありました。たしかにウェブで展開すると、悪い人がサイトに飛ぶはずのボタンをウイルス流すボタンに変えちゃったり、、、しかも見た目は変わらない、、、みたいなことがありうるのかな?よっぽどのことがない限り使わないほうがいい気がします。 ドキュメントすべて1つの記事でまとめると書くのも読むのも大変なので、つづきはまた別の記事で書ければと思います。 読んでくれてありがとうございます!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue3 + Vite に Tailwind CLI を使って、Tailwind CSS を導入してみた

虎の穴ラボの古賀です。 Tailwind CSS v2.2.0 で、 Tailwind CLI が新しく導入されました。 その CLI ツールを使って、Vue3 + Vite の環境に Tailwind CSS (JIT モード) を導入する部分をご紹介しようと思います。 Vue3 に、爆速の Tailwind CSS を導入したいと考えている方の参考になれば、、、と思います。 環境 macOS Big Sur Node.js v14.15.1 利用したライブラリの紹介 Tailwind CSS とは ユーティリティ・ファーストの低レベルな CSS ライブラリです。 Bootstrap や Vuetify、ElementUI の様に決まった UI ではなく オリジナルの UI を爆速で作れます。 設定ファイルを変更することで、 Tailwind CSS のほぼ全てをカスタマイズできます。 Tailwind CLI とは Tailwind CSS v2.2.0 から新たに追加されたツールです。 Tailwind CLI のビルド機能を利用することで、 プロジェクトに Tailwind.css をインストールして設定しなくても Tailwind.css をビルドして利用できます。 また、今までの postcss コマンドよりパフォーマンスが最適化された JIT モードを利用できます。 前提条件 Tailwind CSS は v2.2.0 以降が必要です。 注意事項 vite には postcss が組み込まれています。 postcss.config.js に tailwindcss が 含まれている場合、 vite の postcss も tailwindcss をビルドしてしまい、2 重ビルドになるため注意!してください。 1. Vue3 + Vite のインストール $ npm init @vitejs/app sample-application ✔ *Select a framework:* › vue ✔ *Select a variant:* › vue $ cd sample-application $ npm install 2. Tailwind CSS のインストール $ npm install -D tailwindcss@latest postcss@latest autoprefixer@latest 3. npm-run-all のインストール $ npm install -D npm-run-all 4. Tailwind CSS に必要なファイルを作成し、修正する 4-1. tailwind.config.js を作成します $ npx tailwindcss init 4-2. tailwind.config.js のモードとパージの設定を変更します tailwind.config.js + mode: 'jit', - purge: [], + purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], 4-3. Taiwind CSS をカスタマイズするための tailwind.css を新しく作成します src/assets/css/tailwind.css @tailwind base; @tailwind components; @tailwind utilities; 4-4. Tailwind CLI で生成した tailwind.dist.css を読み込む import を追加します src/main.js + import "./tailwind.dist.css"; 4-5. Tailwind CLI を実行する scripts に書き換えます npm-run-all を利用して、 dev: で始まる全ての scripts を並列で実行します。 package.json "scripts": { "dev": "npm-run-all --parallel dev:*", "dev:server": "vite", "dev:css": "tailwindcss -i src/assets/css/tailwind.css -o src/tailwind.dist.css -w", "build": "tailwindcss -i src/assets/css/tailwind.css -o src/tailwind.dist.css && vite build", "build:prod": "NODE_ENV=production npx tailwindcss -i src/ assets/css/tailwind.css -o src/tailwind.dist.css --minify && vite build", "serve": "vite preview", "clean": "npx clear-npx-cache" }, clean コマンドは、npx コマンドの cache 削除用です。 古いバージョンの Tailwind CSS が実行されてしまい、エラーになる場合に実行してください。 4-6. Tailwind CSS の動作を確認する Vue に書き換えます HelloWorld.vue の class を書き換えます。 src/components/HelloWorld.vue <template> <h1 class="bg-red-400">{{ msg }}</h1> <p class="bg-[#1da1f1]"> <a href="https://vitejs.dev/guide/features.html" target="_blank"> Vite Documentation </a> | <a href="https://v3.vuejs.org/" target="_blank">Vue 3 Documentation</a> </p> <button type="button" class="bg-yellow-500" @click="state.count++"> count is: {{ state.count }} </button> <p> Edit <code>components/HelloWorld.vue</code> to test hot module replacement. </p> </template> <script setup> import { defineProps, reactive } from "vue"; defineProps({ msg: String, }); const state = reactive({ count: 0 }); </script> <style scoped> a { color: #42b983; } </style> 4-7. dev サーバを起動します 爆速(1〜2 秒ほど)で、dev サーバが立ち上がります。 $ npm run dev # http://localhost:3000/ # Ctrl + C で停止 4-8. 動作を確認します 下記のように、Hello World の画面が表示されば、OK です。 5. 既存の Vue3 + Vite プロジェクトに Tailwind CLI を組み込むとき 下記のコマンドで、tailwindcss や vite をアップデートしてください。 # 既存のvue3を対応するとき $ npm update tailwindcss # v2.2.2以降へ $ npm update vite # v2.3.8以降へ その後、手順の 3 から、実行してください。 すでにファイルを作成したり、修正している箇所は読み飛ばしてください。 まとめ Tailwind CLI を利用して、新しく Vue3 のプロジェクトを作成してみました。 驚くほど、爆速で開発環境が立ち上がり、とても快適に開発が可能なので、ぜひ、一度、お試しください ? 最後まで読んでいただき、ありがとうございました。 参考文献
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NativeScript-Vueのコンポネート親子関係(props、$emit)【コピペできるコード付き】

注意 本記事の公開日は2021年となっておりますが、コードや記事のベースを書いたのは2020年です。 (コードはすぐ用意できたのに、記事の方は書いたりやめたり、なんやかんやで一年以上かかってしまった理由で) もったいないので供養の意味を兼ねて投稿しました。 そのため、記述は Vue 2.x と NativeScript 6.x を前提にしています。 最新バージョンでは通用しない可能性があります。 はじめに NativeScript-VueはVue.jsとほぼ変わらないでコンポネートを扱うことができます。 しかしながら公式にその記述がない1し、使おうとしてパニックになり使えないまま諦めてしまう2こともあったので、 「NativeScript-Vueでも同じ使い方できるから安心して」と誰かに教えてもらいたかったため、執筆しました。 内容は大したことなくて、Vue.jsに慣れている方ならすでに分かっていると思います。 繰り返しますが、本記事はあくまで、 「NativeScript-VueもVue.jsと同じ使い方できる」のを伝いたいだけです。 対象読者は、以下のどちらに当てはまる方になると思います。 コンポネートや親子関係の概念が分かっている Vue.jsでのprops、$emitは分かるが、NativeScript-Vueはどんな感じかを見たい コンポネートや親子関係はよく分かってないけど、概念を読むより、コピペして実際に動かしてみたい 今回は実装重視なので、概念のことは一切触れません。 コードは全公開します。 ⇨ コード全文 とりあえず画面 起動画面 非常にシンプルです。 ヘッダーに「Home」、画面上部にタイトルの「Title」と、下部に 一列のボタン「First」「Second」「Third」があります ボタンタップ タイトルの文字がタップされたボタンのテキストに変わります。 今回のファイル構造 app ├── app.css ├── app.js └── components ├── ParentPage.vue └── elements └── ButtonOfChangingTitle.vue ParentPageが唯一のページで、 elementsのディレクトリの下にはButtonOfChangingTitleという子コンポネートがあります。 流れ的には、ページ(親)からボタン(子)へ文字列を渡します。 ボタンは親からの文字列を表示します。 タップされた時に、受け取った文字列を親に返して、親がそれを自身(ページ)のタイトルにします。 ちょっとバカバカしい設計になっています。 同じデータが一周回ってますからね。 そこは大目に見ていただければ助かります。 事前準備 以上のファイル構造を用意できたら、二つのVueファイルに以下のように書き換えてください。 (実際に動かさない方はここをスキップしてください) ParentPage.vue <template> <Page> <ActionBar title="Home" /> <Label text="Title" row="0" class="title" /> <GridLayout rows="*, auto"> <!-- この後書き換えるよ --> </GridLayout> </Page> </template> <script> export default { // 後に追加 }; </script> <style scoped> .title { font-size: 40; horizontal-align: center; } </style> ButtonOfChangingTitle.vue <template> <!-- この後書き換えるよ --> </template> <script> export default { // 後に追加 }; </script> <style scoped> .custom-button { background-color: #1a1f54; color: #FFF; margin: 20; } </style> Vueファイルのフォーマット、cssクラスと最小限のHTMLを定義しました。 この後のコードを適切な場所を入れると同じ動きになります。 最後には全体コードを置いてあるので、不安のある方を照らし合わせながらお進みください。 親から子のデータ渡し(props) propsは親が子コンポーネントへのデータの受け渡しに使われます。 propsを通じて、 親からボタンに表示する文字列(=後に返してくる文字列)を渡します。 子コンポネート まず、子コンポネートButtonOfChangingTitleでpropsの設定をします。 JavaScript ButtonOfChangingTitle.vue <script> export default { props: { text: String }, }; </script> props:{}の中で、受け取りたいデータのプロパティ名を指定します。 propsのプロパティの定義についてはVue.js公式で詳しく紹介されています。 今回はtextというString型を受け取ります。 HTML ButtonOfChangingTitle.vue <template> <Button :text="text" class="custom-button" /> </template> ボタンの文字列に、propsで受け取るtextにバインディングします。 その結果、ボタンには親が指定した文字列が表示されます。 見やすくためにcss classを入れました。挙動には影響がありません。 親コンポネート 子コンポネートが用意できたので、今度を親コンポネートの方を実装します。 JavaScript ParentPage.vue <script> // 使いたいコンポネートをまずimport import ButtonCT from "./elements/ButtonOfChangingTitle"; export default { // そしてコンポネートとして登録する components: { ButtonCT }, data() { return { title: "Title" }; }, }; </script> さて、ここは一旦データ渡しから離れて、コンポネートの登録をします。 まず、スクリプトをimportします。絶対パスも相対パスも使えます。 そして、componentsの中に入れて、登録します。 そうすると、HTML部分で通常のコンポネートと同じ使い方ができます。 下のdata()には、タイトルにバインディングするためのtitleを定義します。 デフォルトの値は"Title"です。 HTML ParentPage.vue <!-- タイトル表示 --> <Label :text="title" row="0" class="title" /> まず、<Label />のtext="Title"を:text="title"に書き換えてください。 :を付けたことによって、文字列の"Title"ではなく、動的に変数のtitleを表示することに変わります。 この変数titleは、ついさっきdata()に設定したtitleのことです。 ParentPage.vue <GridLayout row="1" columns="*, *, *"> <!-- 子コンポーネントを読み込む --> <ButtonCT text="First" col="0" /> <ButtonCT text="Second" col="1" /> <ButtonCT text="Third" col="2" /> </GridLayout> 次に、<!-- この後書き換えるよ -->の部分をこのように書き換えてください。 JavaScript部分でButtonCTを定義したので、HTMLで<ButtonCT />が使えるようになりました。 プロパティtextで表示する文字列(=後に返してくる文字列)を指定します。 このtextが子コンポネートのpropsで定義したtextと紐付けます。 (GridLayoutとcolはUI表示用。挙動に影響ありません) 子から親のデータ渡し($emit) 今度はボタンがタップされた時に、 親に自身の文字列(=propsで受け取った文字列)を渡して、親が表示しているタイトルを変更させます。 $emitを使うことによって、子が親のメソッドを呼ぶことが可能になり、その際引数にデータを渡すこともできます。 親コンポネート 今度は親コンポネートの方から実装していきます。 JavaScript ParentPage.vue <script> export default { // componentsを省略 // data()を省略 methods: { changeText(result) { this.title = result; } } }; </script> methods:{}を追加し、中にchangeTextメソッドを作成します。 引数のresultを変数titleに代入するメソッドです。 (titleは先ほど作成したdata()の中で定義されています) HTML ParentPage.vue <GridLayout row="1" columns="*, *, *"> <ButtonCT text="First" @changeText="changeText" col="0" /> <ButtonCT text="Second" @changeText="changeText" col="1" /> <ButtonCT text="Third" @changeText="changeText" col="2" /> </GridLayout> 先ほど作成した<ButtonCT />に@changeText="changeText"を追加します。 changeTextに統一しましたが、別に同じ名前じゃなくても問題ありません。 前半の@changeTextは子コンポーネント内に使う名前で、後半の"changeText"は親コンポーネント内に使う名前です。 子コンポーネント<ButtonCT />にchangeTextメソッドを渡したことによって、 子コンポーネントから呼べるようになります。 子コンポネート 親コンポーネントの準備が終わったので、いよいよ子コンポネートで呼んでみます。 JavaScript ButtonOfChangingTitle.vue <script> export default { // propsを省略 methods: { changeText() { this.$emit("changeText", this.text); } } }; </script> methods:{}を追加し、親コンポーネントと同様、中にchangeTextメソッドを作成します。 これは親コンポーネントのchangeTextメソッドを実行するためのメソッドです。 this.$emit()の第一引数に呼ぶ関数、第二引数に親に渡す文字列(今回の場合はpropsで定義したtext)を設定します。 完成形 全部合わせるとこんな感じになります。 ParentPage.vue <template> <Page> <ActionBar title="Home" /> <GridLayout rows="*, auto"> <Label :text="title" row="0" class="title" /> <GridLayout row="1" columns="*, *, *"> <ButtonCT text="First" @changeText="changeText" col="0" /> <ButtonCT text="Second" @changeText="changeText" col="1" /> <ButtonCT text="Third" @changeText="changeText" col="2" /> </GridLayout> </GridLayout> </Page> </template> <script> import ButtonCT from "./elements/ButtonOfChangingTitle"; export default { components: { ButtonCT }, data() { return { title: "Title" }; }, methods: { changeText(result) { this.title = result; } } }; </script> <style scoped> .title { font-size: 40; horizontal-align: center; } </style> ButtonOfChangingTitle.vue <template> <Button :text="text" @tap="changeText" class="custom-button" /> </template> <script> export default { props: { text: String }, methods: { changeText() { this.$emit("changeText", this.text); } } }; </script> <style scoped> .custom-button { background-color: #1a1f54; color: #FFF; margin: 20; } </style> さいごに $refsについて言及していませんでしたが、NativeScriptでの使い方もまた一緒です。 参考資料 emit https://forum.vuejs.org/t/passing-data-back-to-parent/1201 prop(Typescript) https://www.nativescript.org/blog/nativescript-vue-with-class-components $navigateToで画面遷移時のprops渡しならありますが。 ↩ 今考えてみれば、パニックによる凡ミスだと思います。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む