Vue.jsで組み込みおよびカスタムディレクティブを使用する方法
著者は、 Write for DOnations プログラムの一環として、 Open Sourcing MentalIllnessを選択して寄付を受け取りました。
序章
フロントエンドフレームワークとして、Vue.jsはReactとAngularの混合物と考えることができます。 VueはReactのprop主導のアプローチを採用していますが、Angularによって普及したディレクティブも使用しています。 このコンテキストでは、ディレクティブは、開発者がHTMLテンプレート内で使用できるコードまたはロジックの再利用可能なチャンクです。 これらを使用すると、要素を条件付きでレンダリングしたり、イベントを要素に接続したり、Vueコードに依存する動的属性を作成したりするなど、さまざまな方法でHTMLを操作できます。
このチュートリアルでは、v-if
、v-show
、v-on
、v-bind
、[ X136X] 、およびv-html
。 これらの最初のセクションでは、チュートリアルで、VueシングルファイルコンポーネントプレイグラウンドなどのオンラインVueプレイグラウンドで実行できる例を紹介します。 これに加えて、新しいVueプロジェクトを作成して、追加機能のためにHTML要素に追加できるカスタムディレクティブを試してみます。
前提条件
- このチュートリアルの最初のセクションでは、 VueシングルファイルコンポーネントプレイグラウンドなどのオンラインVueプレイグラウンドを使用して、ブラウザでフォローできます。
- カスタムディレクティブの作成セクションでプロジェクトを作成するには、コンピューターにNode.jsバージョン
10.6.0
以降がインストールされている必要があります。 これをmacOSまたはUbuntu18.04にインストールするには、macOSで Node.jsをインストールしてローカル開発環境を作成する方法、またはNode.jsをインストールする方法のPPAを使用してインストールするセクションの手順に従います。 Ubuntu18.04で。 - また、マシンにVueCLIがインストールされている必要があります。
- 最後に、このチュートリアルは、JavaScript、HTML、およびCSSの知識を前提としています。これは、 HTMLを使用してWebサイトを構築する方法シリーズ、 CSSを使用してWebサイトを構築する方法シリーズ、およびJavaScriptでコーディングする方法。
v-if
、v-else
、およびv-else-if
ディレクティブの使用
Vue.jsには、開発者がフレームワーク内で作業するときに一般的に使用するいくつかのディレクティブがあらかじめパッケージ化されています。 v-if
、v-show
、v-on
、v-model
、v-bind
、v-html
などのディレクティブがすべて提供されますすぐに使えるあなたのために。 これらの提供されるディレクティブはすべて、v-
で始まります。
v-if
、v-else
、およびv-else-if
ディレクティブを使用すると、条件付きでレンダリングされたHTML要素を作成でき、JavaScriptの if、else if、else条件と同様に機能します。 。 JavaScriptのようにHTMLまたはコードを返す代わりに、Vueはそのコードブロックを条件付きでレンダリングします。
Vueディレクティブを適用するには、Vue単一ファイルコンポーネントのtemplate
セクションのHTML要素に追加します。 たとえば、v-if
ディレクティブを段落要素に追加する場合は、次の構文を使用します。
<p v-if="condition"></p>
この場合、強調表示されたcondition
は、段落要素がレンダリングされるかどうかを決定するブール式のプレースホルダーです。
v-if
ディレクティブが実際の状況でどのように機能するかを説明するために、ユーザーウェルカムページ用に次のコードを作成します。
<template> <p v-if="user.firstName && user.lastName"> Welcome, {{ user.firstName }} {{ user.lastName }}! </p> <p v-else-if="user.username"> Welcome, {{ user.username }}! </p> <div v-else> <button>Login</button> <button>Create Account</button> </div> </template> <script setup> const user = { firstName: 'Sammy', lastName: 'Shark', username: 'sammyDO' } </script>
このコードには、2つの<p>
タグと2つのボタンを持つ<div>
タグを含む、多数のHTML要素があります。 ただし、このコードがブラウザーで実行されると、trueと評価される条件に応じて、これらのコードのチャンクの1つだけがレンダリングされます。 false条件のHTMLは、DOM(Document Object Model)ではレンダリングされません。
現在のように、firstName
とlastName
の両方が<script>
タグに値を持っているため、式user.firstName && user.lastName
はtrue
と評価されます。ブラウザが段落をレンダリングします。 これは、ブラウザで次の画像のようになります。
firstName
またはlastName
のいずれかが定義されていない場合、条件はfalse
と評価され、Vueはv-else-if
ディレクティブに移動します。 このディレクティブはuser.username
式に付加されているため、これがtrue
と評価されると、付加された段落要素がレンダリングされます。 これを試すには、<script>
タグのfirstName
を削除します。
... <script setup> const user = { lastName: 'Shark', username: 'sammyDO' } </script>
条件user.firstName && user.lastName
はfalse
と評価されますが、user.username
はtrue
と評価されるため、代わりにユーザー名がレンダリングされます。 これを次の画像に示します。
最後に、すべての条件がfalse
と評価された場合、制御はv-else
ディレクティブに渡されます。このディレクティブは、ログインまたはアカウントを作成するための2つのボタンをレンダリングします。 これを試すには、script
要素のusername
データを削除します。
... <script setup> const user = { lastName: 'Shark', } </script>
これで、ブラウザに表示されるデフォルトのボタンが見つかります。
v-else-if
またはv-else
ディレクティブの直前に、v-if
ディレクティブを持つ要素が必要であることに注意してください。 そうしないと動作しません。
例として、次のコードスニペットは無効と見なされ、ブラウザのコンソールでエラーが発生します。
<template> <p v-if="user.firstName && user.lastName"> Welcome, {{ user.firstName }} {{ user.lastName }}! </p> <p v-else-if="user.username"> Welcome, {{ user.username }}! </p> <h1>Some Title</h1> <div v-else> <button>Login</button> <button>Create Account</button> </div> </template> <script setup> const user = { firstName: 'Sammy', lastName: 'Shark', username: 'sammyDO' } </script>
v-else-if
ディレクティブのある段落の後の<h1>
要素にはディレクティブがないため、このコードはレンダリングに失敗し、次の構文エラーが発生します。
OutputSyntaxError: v-else/v-else-if has no adjacent v-if.
このv-if
の要約をカバーしたので、HTML要素を条件付きで表示する別の方法であるv-show
ディレクティブを試すことができます。
v-show
ディレクティブの使用
v-if
関連のディレクティブの他に、条件に基づいてHTML要素を表示するために使用できる別のディレクティブがあります。 そのディレクティブはv-show
です。 v-if
に似ていますが、else-if
とelse
に対応するものがなく、要素が条件付きでレンダリングされるのではなく、条件付きで表示される点が異なります。
前のセクションと同様の状況に対処する次のコードを見てください。
<template> <div v-show="!userIsLoggedIn"> <button>Login</button> <button>Create Account</button> </div> <div v-show="userIsLoggedIn"> <p>Welcome!</p> </div> </template> <script setup> const userIsLoggedIn = true </script>
このコードでは、条件式とともにv-show
を2つの<div>
にアタッチしています。 v-show
は、引用符で囲まれた条件が満たされた場合に、添付されたHTMLを表示します。 この例では、userIsLoggedIn
はtrue
と評価されるため、ブラウザは[X103X]とWelcome!
段落を表示します。
次に、userIsLoggedIn
の値をfalse
に変更します。
... <script setup> const userIsLoggedIn = false </script>
ログインボタンが再び表示されます。
v-if
とv-show
の違いを強調する価値があります。 v-if
は条件付きでHTMLをレンダリングします。 条件式がfalse
と評価された場合、DOMにはそれがまったく含まれません。 一方、v-show
は、常にDOMでHTMLをレンダリングします。 ただし、要素はdisplay: none
CSS スタイルで非表示になるため、ブラウザには表示されません。
条件付きのv-if
およびv-show
ディレクティブがカバーされているので、v-on
ディレクティブに移動して、イベントをHTML要素に関連付けることができます。
v-on
ディレクティブの使用
v-on
ディレクティブは、特定のイベントで関数を実行します。 これは、カスタムイベント、またはclick
、hover
、mouseenter
などの標準のJavaScriptイベントにすることができます。 v-on
ディレクティブを使用する場合は、コロン(:
)の後にイベントタイプと実行する関数を指定する必要があります。 コンポーネントの関数名は、引用符の間にあります。
この例として、次の強調表示されたコードを調べます。
<template> <button v-on:click="handleClick">Click Me</button> </template> <script setup> function handleClick() { alert('You clicked the button!') } </script>
この例では、ユーザーがディレクティブがアタッチされている<button>
要素をクリックすると、コンポーネント関数handleClick
が実行されます。 このコードを実行してボタンをクリックすると、ボタンをクリックしました!というアラートが表示されます。
v-on
ディレクティブを使用するイベントでは、イベント修飾子をイベント自体にチェーンすることもできます。 これらのイベント修飾子は、イベントの実行方法を変更でき、通常はJavaScriptの複数行を必要とする機能を作成する際の時間を節約できます。 Vueが提供するいくつかの修飾子は次のとおりです。
once
:イベントが1回だけ発生するように制限します。self
:イベントは、イベントターゲットがディレクティブを保持する要素と同じである場合にのみトリガーされます。prevent
:イベントの発生を停止します。stop
:イベントの伝播を停止します。
次に、once
イベント修飾子の例を実行して、構文を試します。 次の強調表示されたコードを前のスニペットに追加します。
<template> <button v-on:click.once="handleClick">Click Me</button> </template> ...
.once
修飾子を使用すると、関数handleClick
は1回だけ実行されます。 Click Me ボタンをクリックしてみると、アラートがポップアップ表示されます。 アラートをクリアしてから、もう一度クリックします。 イベントはすでに1回発生しているため、発生しません。
v-on
ディレクティブにも省略構文があります。 省略構文を使用するには、v-on:
を@
に置き換えます。
<template> <button @click.once="handleClick">Click Me</button> </template> ...
これにより、v-on:click.once
と同じ動作になります。
イベントがv-on
で対処されたので、v-bind
およびv-model
を使用してデータをテンプレート要素にバインドすることに進むことができます。
v-bind
およびv-model
ディレクティブの使用
Vue.jsはModel-View-ViewModel(MVVM)フレームワークです。つまり、個別のデータ(モデル)がHTML(ビュー)を更新し、ビューがモデルを更新します。 この分離は、ビュー、またはブラウザーでレンダリングされるものが、データ処理とは独立して動作できることを意味します。
MVVMアプローチを制定するために、Vueは、データ、小道具、および計算されたプロパティをVueコンポーネントに渡す方法を提供します。 これは、双方向データバインディングを使用して実行されます。これにより、ビューとモデルが相互に対話できるようになります。
次のコードでは、データ値に応じて変化する動的コンテンツを持つ<p>
要素があります。
<template> <p>I am from {{ city }}.</p> </template> <script setup> const city = 'Cincinnati' </script>
このスニペットでは、テンプレート:City
は、その後の<script>
要素のcity
定数へのデータ参照です。 現在のように、テンプレート:City
は文字列"Cincinnati"
に評価され、 I am fromCincinnatiという単語を含む段落要素がブラウザに表示されます。 Cincinnati
をSeattle
に変更すると、それに応じてテンプレートのテンプレート:City
が更新されます。
この動的コンテンツの場合、ディレクティブを使用する必要はありません。テンプレートはcity
定数に自動的にアクセスできます。 ただし、<script>
データを参照してHTML属性を動的にする場合は、データをv-bind
で明示的にバインドする必要があります。
これを説明するために、テンプレート:City
プレースホルダーをリンク(<a>
)タグで囲み、city
定数。 まず、テンプレート:City
を<a>
タグでラップして、ユーザーがそれをクリックして都市自体の詳細情報を取得できるようにします。 その後、wikipediaLink
という計算プロパティを作成し、適切なURLを返すようにします。 強調表示されたコードを追加します。
<template> <p>I am from <a href="">{{ city }}</a>.</p> </template> <script setup> import { computed } from 'vue' const city = 'Cincinnati' const wikipediaLink = computed(() =>`https://en.wikipedia.org/wiki/${city}`) </script>
<script>
要素で、Vueライブラリからcomputed
関数をインポートし、それを使用してwikipediaLink
にURLを割り当てました。 URL文字列は、テンプレートリテラルを使用して、city
の値に応じて変更します。
ウィキペディアのリンクができたので、先に進んで、計算されたプロパティ名を、前に追加したアンカータグのhref
属性に追加します。
<template> <p>I am from <a href="wikipediaLink">{{ city }}</a>.</p> </template> ...
この時点でこれをブラウザで表示すると、コンソールエラーが発生します。 これは、現在Vue.jsがwikipediaLink
を文字列リテラルと見なしているためです。これは有効なURLではありません。
wikipediaLink
計算プロパティの戻り値を使用するようにVue.jsに指示するには、v-bind
ディレクティブを使用する必要があります。 これにより、次のように、テンプレート内の参照が計算されたプロパティにバインドされます。
<template> <p>I am from <a v-bind:href="wikipediaLink">{{ city }}</a>.</p> </template> ...
これで、href
の値がシンシナティウィキペディアページのURLになります。 このURLは、city
プロパティがシアトルなどの別の都市に変更された場合に更新されます。
v-on
と同様に、v-bind
にも、使用することを選択できる省略形があります。 省略形を使用するには、次のように、v-bind:
を:
に置き換えます。
<template> <p>I am from <a :href="wikipediaLink">{{ city }}</a>.</p> </template>
Vue.jsには、値をdata
プロパティにバインドするために使用される別のディレクティブがあります。 ただし、このディレクティブはinput
タグに対してのみ機能します。
<template> <input v-model="city" type="text" /> </template> <script setup> const city = 'Cincinnati' </script>
v-model
ディレクティブを使用する場合、入力フィールドvalue
属性を引用符で囲まれたデータプロパティにバインドします。 フォーム<input />
タグには、v-bind
ではなくv-model
ディレクティブを使用することをお勧めします。
このVueコンポーネントは、次の画像に示すように、デフォルトのテキストCincinnatiでテキスト入力ボックスをレンダリングします。
このセクションでは、HTML属性を変数データまたは計算データにバインドするさまざまな方法について説明しました。 次に、v-html
ディレクティブを使用して、テンプレートにHTMLを挿入します。
v-html
ディレクティブの使用
このチュートリアルで取り上げる最後のパッケージ済みディレクティブはv-html
です。 このディレクティブは、文字列リテラル内のHTMLをブラウザが読み取るための生のHTMLに変換します。これにより、HTMLの作成方法と適用方法をより柔軟に設定できます。
この架空のコンポーネントには、data
プロパティを値として持つv-html
ディレクティブを持つ<div>
があります。
<template> <div v-html="someHtmlCode" /> </template> <script setup> const someHtmlCode = `<p>Some <span>HTML</span> in this string</p>` </script>
v-html
ディレクティブは、someHtmlCode
データ参照の文字列をテンプレートの<div />
に挿入するようにVue.jsに指示しています。 Vueでコンパイルすると、DOMに次のように表示されます。
<div> <p>Some <span>HTML</span> in this string</p> </div>
HTMLはブラウザでもレンダリングされます。
このディレクティブは、RESTAPIサービスからのHTMLまたは外部JavaScriptファイルからの大きなHTMLをレンダリングする必要がある場合に役立ちます。
チュートリアルのこの時点で、Vue.jsによって提供されるディレクティブを試しました。 ただし、Vueが提供しないディレクティブが必要になる場合があります。 このような場合、HTMLテンプレートの特定のロジックを処理するカスタムディレクティブを作成できます。
カスタムディレクティブの作成
Vue.jsフレームワークでは、プロジェクトの個々のニーズに合わせてカスタムディレクティブを作成することができます。 たとえば、このセクションでは、テンプレートの要素に特定のスタイルを適用するv-theme
ディレクティブを作成します。
この時点までは、スタンドアロンのVueプロジェクトをフォローする必要はありませんでした。 ただし、このセクションでは、VueCLIから生成された新しいプロジェクトを作成します。
ターミナルを開き、次のコマンドを使用して新しいプロジェクトを生成します。 このプロジェクトの名前はcustom-directive
になります。これは、ルートディレクトリの名前にもなります。
vue create custom-directive
このチュートリアルでは、Choose Vue Version
に対してVue 3x
を選択します。 アプリが作成されたら、選択したテキストエディタで生成されたプロジェクトを開きます。 次に、src
ディレクトリにあるmain.js
ファイルを開きます。
まず、このファイルを設定します。 createApp(App)
をconst
に保存して、後で参照できるようにします。
custom-directive / src / main.js
import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.mount('#app')
これで、createApp
関数が独自のconst
に組み込まれたので、ディレクティブを追加してこのアプリを拡張できます。
custom-directive / src / main.js
import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.directive("theme", {}) app.mount('#app')
このコードでは、Vueインスタンスのdirective()
関数を利用しています。 この関数は、ディレクティブ名(この場合はtheme
)とライフサイクルフックを持つオブジェクトの2つの引数を受け入れます。
このコードは、コンポーネントがmounted
のときに実行されるように設定します。 このマウントされたフックは、HTML要素であるel
と、ディレクティブに渡される値であるbinding
の2つの引数を受け入れます。 この情報を使用して、以下を作成できます。
custom-directive / src / main.js
const app = createApp(App) app.directive("theme", { mounted(el, binding) { } }) app.mount('#app')
このtheme
ディレクティブでは、要素のスタイルを決定するために文字列を渡します。 この文字列は、primary
、secondary
、またはtertiary
のいずれかになり、それぞれが仮想のカラースキームの色に対応します。
ディレクティブコードが配置されたので、ロジックを追加できます。 ディレクティブのクォータマーク内の値にアクセスするには、binding.value
を使用できます。 要素のテキストの色を変更するには、JavaScriptを使用してel
プロパティにアクセスします。
custom-directive / src / main.js
const app = createApp(App) app.directive("theme", { mounted(el, binding) { if (binding.value === 'primary') { el.style.color = 'red' } else if (binding.value === 'secondary') { el.style.color = 'green' } else if (binding.value === 'tertiary') { el.style.color = 'blue' } else { el.style.color = 'black' } } }) app.mount('#app')
このスニペットで強調表示されているセクションは、一連のif
/else
ステートメントです。 ディレクティブに渡される値がprimary
の場合、テキストの色はred
、secondary
はgreen
、tertiary
はblue
であり、デフォルトのblack
に戻る値はありません。
main.js
ファイルを閉じて保存します。
この時点で、Vue.jsアプリケーションで使用できるカスタムディレクティブを作成しました。 Vueはディレクティブ名の前にv-
を自動的に付けるため、テンプレートはv-theme
としてディレクティブにアクセスできます。
選択したテキストエディタでApp.vue
ファイルを開きます。 テンプレートに、テキストを含む<p>
タグを追加します。
custom-directive / src / App.vue
<template> <p>This text will change color based on the directive value!</p> </template>
このファイルを保存し、npm run serve
でアプリケーションを起動します。 これにより、localhost
の:8080
ポートでプロジェクトが実行されます。
npm run serve
生成されたプロジェクトを表示するには、選択したブラウザを開き、URLバーのlocalhost:8080
にアクセスします。 段落要素が黒でレンダリングされています。
次に、ディレクティブをHTMLに追加して、色を変更します。
custom-directive / src / App.vue
<template> <p v-theme="`primary`">This text will change color based on the directive value!</p> </template>
このファイルを保存して、Webブラウザで開きます。 引用符内の値は生の値であり、自動的にVueにバインドされるため、引用符内では、バックティックを使用してprimary
をラップして文字列に変換する必要があります。
ファイルを保存すると、レンダリングされたサイトのテキストが赤に変わります。
ディレクティブはbinding
オブジェクトの値を読み取り、それに応じてコードを実行します。 値がprimary
であるため、JavaScriptはテキストの色を赤に変更します。
このセクションでは、カスタムディレクティブを作成して登録し、そのロジックを実行しました。 また、新しいカスタムディレクティブを追加し、それをテンプレートのHTML要素に割り当てました。
結論
このチュートリアルでは、演習を実行して、ディレクティブとは何か、およびそれらの使用方法をテストしました。 具体的には、v-if
、v-on
、v-show
、v-html
などの最も一般的な組み込みディレクティブを使用しました。 これに加えて、独自のカスタムディレクティブを登録して作成しました。 このディレクティブv-theme
は、JavaScript関数を実行するために任意のHTML要素で使用できるようになりました。
いくつかのディレクティブを確認しましたが、Vue.jsによってさらに多くのディレクティブが利用可能になりました。 ディレクティブの詳細については、公式のVue.jsドキュメントを確認することをお勧めします。 Vueのその他のチュートリアルについては、Vue.jsシリーズページを使用してWebサイトを開発する方法を確認してください。