TechVue.jsJapanese

[ Vue3 + TypeScript ] 子コンポーネント で実装した ドロップダウン で選択した内容を リアクティブ に 親コンポーネント と 連携する方法

Tech

リアクティブ な アプリケーション を 再利用可能で 独立した コンポーネント と言う概念を使ってが容易に実装できるのが Vue.js の利点の一つだといえます。 この コンポーネント の利点を活かすために 各 コンポーネント をあまり大きなサイズ にしないことが一つの ポイント になってきます。 一方で 単一の コンポーネント 内部で リアクティブ に実現できていた機能を コンポーネント に分割して実現しようとすると コンポーネント 間で データ のやりとりを実現する必要があります。 

本記事では 通常 ツリー 構造となる コンポーネント の 「親 コンポーネント から 子 コンポーネント」、 「子 コンポーネント から 親 コンポーネント」 のそれぞれについて リアクティブ な データ のやりとりを TypeScript で実現する方法について ドロップボックス (Select) を例に用いて 整理していきます。

macOS: 12.3
vue: 3.2.31
typescript: 4.5.5
vue3 API: Composition API
bootstrap: 5.1.3

Vue3 + TypeScript + Bootstrap5 プロジェクトの準備

[ads]

今回の記事で使用するプロジェクトを用意します。

  • npm int vue@3 を使ってプロジェクト作成
  • TypeScript を有効にする
  • bootstrap5 をインストール

参考記事:

親 コンポーネント (App.vue)

create-vue で作成された プロジェクト に存在する App.vue を 親 コンポーネント として利用します。 以下のように 子 コンポーネント として 新規に作成する Child.vue を インポート し それを template で呼び出す形にします。 style については、プロジェクト作成時から変更しないため、割愛しています。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">setup</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"ts"</span>></span><span class="javascript">
<span class="hljs-keyword">import</span> Child <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Child.vue'</span>
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">Child</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">setup</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"ts"</span>></span><span class="javascript"> <span class="hljs-keyword">import</span> Child <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Child.vue'</span> </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <span class="hljs-tag"><<span class="hljs-name">template</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">Child</span> /></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<script setup lang="ts">
import Child from './components/Child.vue'
</script>
 
<template>
 <div>
   <Child />
 </div>
</template>

子コンポーネント (Child.vue)

続いて 子 コンポーネント を準備します。 src / components に 新規 ファイル として 以下の内容で Child.vue ファイル を作成します。

template には 、Bootstrap5 の公式サイト の サンプル を引用してきています。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<script setup lang="ts">
</script>
<<span class="hljs-keyword">template</span>>
<div>
<<span class="hljs-keyword">select</span> <span class="hljs-keyword">class</span>="form-select" aria-label="Default select example">
<<span class="hljs-keyword">option</span> selected><span class="hljs-keyword">Open</span> this <span class="hljs-keyword">select</span> menu</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="1">One</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="2">Two</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="3">Three</<span class="hljs-keyword">option</span>>
</<span class="hljs-keyword">select</span>>
</div>
</<span class="hljs-keyword">template</span>>
<script setup lang="ts"> </script> <<span class="hljs-keyword">template</span>> <div> <<span class="hljs-keyword">select</span> <span class="hljs-keyword">class</span>="form-select" aria-label="Default select example"> <<span class="hljs-keyword">option</span> selected><span class="hljs-keyword">Open</span> this <span class="hljs-keyword">select</span> menu</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="1">One</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="2">Two</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="3">Three</<span class="hljs-keyword">option</span>> </<span class="hljs-keyword">select</span>> </div> </<span class="hljs-keyword">template</span>>
<script setup lang="ts">
</script>
 
<template>
   <div>
       <select class="form-select" aria-label="Default select example">
           <option selected>Open this select menu</option>
           <option value="1">One</option>
           <option value="2">Two</option>
           <option value="3">Three</option>
       </select>
   </div>
</template>

その他

Bootstrap5 を使うために main.ts に以下の1行を追加します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-keyword">import</span> { createApp } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App.vue'</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"bootstrap/dist/css/bootstrap.min.css"</span>
createApp(App).mount(<span class="hljs-string">'#app'</span>)
<span class="hljs-keyword">import</span> { createApp } <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span> <span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App.vue'</span> <span class="hljs-keyword">import</span> <span class="hljs-string">"bootstrap/dist/css/bootstrap.min.css"</span> createApp(App).mount(<span class="hljs-string">'#app'</span>)
import { createApp } from 'vue'
import App from './App.vue'
import "bootstrap/dist/css/bootstrap.min.css"
 
createApp(App).mount('#app')

この段階でのアプリ動作

特に 各 コンポーネント に プロパティ もない状態で ドロップダウン が 動いている状態です。

次の ステップ では 親 コンポーネント である App.vue に設置した コンテンツ の内容に応じて、 子 コンポーネント に設置した ドロップボックス (Select) の値を リアクティブ に 変化させてみます。


親から子へ データを連携する (Props)

[ads]

子 コンポーネント に ドロップダウン と連動する プロパティ 追加

まずは 準備として Child.vue に ドロップダウン と連動する プロパティ を defineProps を用いて追加していきます。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<script setup lang="ts">
defineProps([<span class="hljs-string">'modelValue'</span>])
</script>
<<span class="hljs-keyword">template</span>>
<div>
<<span class="hljs-keyword">select</span>
<span class="hljs-keyword">class</span>="form-select"
aria-label="Default select example"
v-model="modelValue">
<<span class="hljs-keyword">option</span> selected><span class="hljs-keyword">Open</span> this <span class="hljs-keyword">select</span> menu</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="1">One</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="2">Two</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="3">Three</<span class="hljs-keyword">option</span>>
</<span class="hljs-keyword">select</span>>
</div>
</<span class="hljs-keyword">template</span>>
<script setup lang="ts"> defineProps([<span class="hljs-string">'modelValue'</span>]) </script> <<span class="hljs-keyword">template</span>> <div> <<span class="hljs-keyword">select</span> <span class="hljs-keyword">class</span>="form-select" aria-label="Default select example" v-model="modelValue"> <<span class="hljs-keyword">option</span> selected><span class="hljs-keyword">Open</span> this <span class="hljs-keyword">select</span> menu</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="1">One</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="2">Two</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="3">Three</<span class="hljs-keyword">option</span>> </<span class="hljs-keyword">select</span>> </div> </<span class="hljs-keyword">template</span>>
<script setup lang="ts">
defineProps(['modelValue'])
</script>
 
<template>
   <div>
       <select
           class="form-select"
           aria-label="Default select example"
           v-model="modelValue">
           <option selected>Open this select menu</option>
           <option value="1">One</option>
           <option value="2">Two</option>
           <option value="3">Three</option>
       </select>
   </div>
</template>

ドロップダウン の選択に応じて値が変化する プロパティ modelValue を実装し、期待通り動作していることが分かります。

なお、この段階では modelValue という名称でなくても問題ありませんが、親 コンポーネント と連携する際には modelValue 以外の名称だとうまくいきませんので、注意してください。ここでは 親 コンポーネントとの連携も見据えて modelValue という名称で進めていきます。

参考:
https://vuejs.org/guide/components/events.html#v-model-arguments

親 コンポーネント に 子 コンポーネント と連動する変数 と その変数を変化させる テキストボックス を追加

親 コンポーネント の App.vue に 子 コンポーネント と連動する ref オブジェクト の 変数 item を追加します。ドロップダウンの初期値として “One” が表示されるように 値は 1 としています。

同時に、この itemv-model に指定した テキストボックス を追加します。ここで入力した値を 子 コンポーネント に連携させてみます。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">setup</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"ts"</span>></span><span class="actionscript">
<span class="hljs-meta"><span class="hljs-meta-keyword">import</span> </span></span></span><span class="hljs-template-variable">{ ref }</span><span class="xml"><span class="javascript"> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>
<span class="hljs-keyword">import</span> Child <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Child.vue'</span>
<span class="hljs-keyword">const</span> item = ref(<span class="hljs-string">'1'</span>)
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
Parent:
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name">hr</span> /></span>Child:
<span class="hljs-tag"><<span class="hljs-name">Child</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">template</span>></span></span>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">setup</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"ts"</span>></span><span class="actionscript"> <span class="hljs-meta"><span class="hljs-meta-keyword">import</span> </span></span></span><span class="hljs-template-variable">{ ref }</span><span class="xml"><span class="javascript"> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span> <span class="hljs-keyword">import</span> Child <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Child.vue'</span> <span class="hljs-keyword">const</span> item = ref(<span class="hljs-string">'1'</span>) </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> <span class="hljs-tag"><<span class="hljs-name">template</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span>></span> Parent: <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">hr</span> /></span>Child: <span class="hljs-tag"><<span class="hljs-name">Child</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item"</span> /></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">template</span>></span></span>
<script setup lang="ts">
import { ref } from 'vue'
import Child from './components/Child.vue'
 
const item = ref('1')
</script>
 
<template>
 <div>
   Parent:
   <input v-model="item" />
   <hr />Child:
   <Child v-model="item" />
 </div>
</template>

早速 この コード を動かし、 テキストボックス に値を入力してみます。

親 コンポーネント に実装した テキストボックス に値を入力すると それに対応した 子 コンポーネント の ドロップダウン が変化していることが分かります。  親 コンポーネント の変数の値が Child コンポーネント での v-model で 子 コンポーネント 側へ リアクティブ に連携されているためです。

次の ステップ では、 ドロップボックス の選択に合わせて テキストボックスの内容を変化させてみます。 つまり 今の実装とは 逆で 「子 コンポーネント から 親 コンポーネント へ データ を連携」 するという流れになります。


子 コンポーネント から 親 コンポーネント へ データ を連携する (Emit)

[ads]

先ほどの状態で ドロップダウン から値を選択してみても、親 コンポーネント の テキストボックス の値は 変わりません。

先ほど、実装した処理は あくまで 親 から 子 への一方通行の連携だからです。 それでは 子 から 親 への データ 連携を実装してみます。 子 から 親 への データ 連携には Emit という機能を用います。

Emit の実装

まずは Emit 処理を defineEmits を用いて定義します。 ここでも defineProps での modelValue と同様に update:modelValue と言う名称で定義してください。 それ以外の名称ですと 親 に連携することができません。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<script setup lang=<span class="hljs-string">"ts"</span>>
<span class="hljs-function"><span class="hljs-title">defineProps</span><span class="hljs-params">([<span class="hljs-string">'modelValue'</span>])</span></span>
<span class="hljs-function"><span class="hljs-title">defineEmits</span><span class="hljs-params">([<span class="hljs-string">'update:modelValue'</span>])</span></span>
</script>
<script setup lang=<span class="hljs-string">"ts"</span>> <span class="hljs-function"><span class="hljs-title">defineProps</span><span class="hljs-params">([<span class="hljs-string">'modelValue'</span>])</span></span> <span class="hljs-function"><span class="hljs-title">defineEmits</span><span class="hljs-params">([<span class="hljs-string">'update:modelValue'</span>])</span></span> </script>
<script setup lang="ts">
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>

続いて 定義した Emit を呼び出す部分を実装します。 今回は ドロップダウン ですので select タグ に @change を追加することで ドロップダウン を選択する都度 Emit を呼び出し 親へ連携していこうと思います。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<select
<span class="hljs-attribute">class</span>=<span class="hljs-string">"form-select"</span>
<span class="hljs-attribute">aria-label</span>=<span class="hljs-string">"Default select example"</span>
<span class="hljs-attribute">v-model</span>=<span class="hljs-string">"modelValue"</span>
@<span class="hljs-attribute">change</span>=<span class="hljs-string">"<span class="hljs-variable">$emit</span>('update:modelValue', <span class="hljs-variable">$event</span>.target.value)"</span>
>
<select <span class="hljs-attribute">class</span>=<span class="hljs-string">"form-select"</span> <span class="hljs-attribute">aria-label</span>=<span class="hljs-string">"Default select example"</span> <span class="hljs-attribute">v-model</span>=<span class="hljs-string">"modelValue"</span> @<span class="hljs-attribute">change</span>=<span class="hljs-string">"<span class="hljs-variable">$emit</span>('update:modelValue', <span class="hljs-variable">$event</span>.target.value)"</span> >
       <select
           class="form-select"
           aria-label="Default select example"
           v-model="modelValue"
           @change="$emit('update:modelValue', $event.target.value)"
       >

$event.target.valueemit の引数とすることで  option タグ の value で指定した値が親に連携されることになります。

それでは 早速この状態で実行していきます。

無事、 子 コンポーネント で実装した ドロップダウン で選択した項目に対応した値が 親 コンポーネント で実装した テキストボックス に反映されています。 先ほど実装した 親から子 への実装も引き続き有効ですので これで双方向のデータ 連携 が完成しました。

補足 Object is possibly ‘null’.ts(2531) への対応

ここまでの コード で目的の機能を実装することができましたが、 実は以下の TypeScript Warning が出力されています。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-built_in">Object</span> <span class="hljs-keyword">is</span> possibly <span class="hljs-comment">'null'.ts(2531)</span>
<span class="hljs-built_in">Object</span> <span class="hljs-keyword">is</span> possibly <span class="hljs-comment">'null'.ts(2531)</span>
Object is possibly 'null'.ts(2531)

これは tsconfig.json で 以下のいずれかの設定をしている場合に出力されるためです。これらをいずれも false にすれば出力されなくなりますが、せっかくの警告が抑制されてしまうので、やはり根本解決してみることにします。

Type Annotations を明示する (HTMLSelectElement)

警告の原因は Type Annotations を省略しているため、 暗黙的に any 型 と判断されていることにあります。 ですので、 明示的に Type Annotations を記載することで 警告 に対応することができます。 TypeScript 公式 サイト でも 「any は型チェックできないため 基本的に避けるべき」 と説明されています。

select エレメント では HTMLSelectElement インターフェース を用いることになりますので この HTMLSelectElement を明示的にコードに記載していきます。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<select
<span class="hljs-attribute">class</span>=<span class="hljs-string">"form-select"</span>
<span class="hljs-attribute">aria-label</span>=<span class="hljs-string">"Default select example"</span>
<span class="hljs-attribute">v-model</span>=<span class="hljs-string">"modelValue"</span>
@<span class="hljs-attribute">change</span>=<span class="hljs-string">"<span class="hljs-variable">$emit</span>('update:modelValue', (<span class="hljs-variable">$event</span>.target as HTMLSelectElement).value)"</span>
>
<select <span class="hljs-attribute">class</span>=<span class="hljs-string">"form-select"</span> <span class="hljs-attribute">aria-label</span>=<span class="hljs-string">"Default select example"</span> <span class="hljs-attribute">v-model</span>=<span class="hljs-string">"modelValue"</span> @<span class="hljs-attribute">change</span>=<span class="hljs-string">"<span class="hljs-variable">$emit</span>('update:modelValue', (<span class="hljs-variable">$event</span>.target as HTMLSelectElement).value)"</span> >
       <select
           class="form-select"
           aria-label="Default select example"
           v-model="modelValue"
           @change="$emit('update:modelValue', ($event.target as HTMLSelectElement).value)"
       >

このように記載することで 実装した機能の動作はそのままに TypeScript の 警告 が表示されなくなります。

参考:
https://vuejs.org/guide/typescript/composition-api.html#typing-event-handlers


まとめ

[ads]

親 -> 子 defineProps を用いる

  • modelValue という名称を使う

子 -> 親 defineEmits を用いる

  • update:modelValue という名称を使う

Object is possibly 'null' へ対応するためには Type Annotation を明示する (ここでは HTMLSelectElement


[ads]

今回使用した サンプル コード

App.vue

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">setup</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"ts"</span>></span><span class="actionscript">
<span class="hljs-meta"><span class="hljs-meta-keyword">import</span> </span></span></span><span class="hljs-template-variable">{ ref }</span><span class="xml"><span class="javascript"> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span>
<span class="hljs-keyword">import</span> Child <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Child.vue'</span>
<span class="hljs-keyword">const</span> item = ref(<span class="hljs-string">'1'</span>)
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span></span>
<span class="xml"><span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">setup</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"ts"</span>></span><span class="actionscript"> <span class="hljs-meta"><span class="hljs-meta-keyword">import</span> </span></span></span><span class="hljs-template-variable">{ ref }</span><span class="xml"><span class="javascript"> <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span> <span class="hljs-keyword">import</span> Child <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Child.vue'</span> <span class="hljs-keyword">const</span> item = ref(<span class="hljs-string">'1'</span>) </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span></span>
<script setup lang="ts">
import { ref } from 'vue'
import Child from './components/Child.vue'

const item = ref('1')
</script>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-tag"><<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
Parent:
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item"</span> /></span>
<span class="hljs-tag"><<span class="hljs-name">hr</span> /></span>Child:
<span class="hljs-tag"><<span class="hljs-name">Child</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">template</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span>></span> Parent: <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item"</span> /></span> <span class="hljs-tag"><<span class="hljs-name">hr</span> /></span>Child: <span class="hljs-tag"><<span class="hljs-name">Child</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"item"</span> /></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<template>
  <div>
    Parent:
    <input v-model="item" />
    <hr />Child:
    <Child v-model="item" />
  </div>
</template>

Child.vue

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<script setup lang=<span class="hljs-string">"ts"</span>>
<span class="hljs-function"><span class="hljs-title">defineProps</span><span class="hljs-params">([<span class="hljs-string">'modelValue'</span>])</span></span>
<span class="hljs-function"><span class="hljs-title">defineEmits</span><span class="hljs-params">([<span class="hljs-string">'update:modelValue'</span>])</span></span>
</script>
<script setup lang=<span class="hljs-string">"ts"</span>> <span class="hljs-function"><span class="hljs-title">defineProps</span><span class="hljs-params">([<span class="hljs-string">'modelValue'</span>])</span></span> <span class="hljs-function"><span class="hljs-title">defineEmits</span><span class="hljs-params">([<span class="hljs-string">'update:modelValue'</span>])</span></span> </script>
<script setup lang="ts">
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
</script>
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<<span class="hljs-keyword">template</span>>
<div>
<<span class="hljs-keyword">select</span>
<span class="hljs-keyword">class</span>="form-select"
aria-label="Default select example"
v-model="modelValue"
@change="$emit('update:modelValue', ($event.target as HTMLSelectElement).value)"
>
<<span class="hljs-keyword">option</span> selected><span class="hljs-keyword">Open</span> this <span class="hljs-keyword">select</span> menu</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="1">One</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="2">Two</<span class="hljs-keyword">option</span>>
<<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="3">Three</<span class="hljs-keyword">option</span>>
</<span class="hljs-keyword">select</span>>
</div>
</<span class="hljs-keyword">template</span>>
<<span class="hljs-keyword">template</span>> <div> <<span class="hljs-keyword">select</span> <span class="hljs-keyword">class</span>="form-select" aria-label="Default select example" v-model="modelValue" @change="$emit('update:modelValue', ($event.target as HTMLSelectElement).value)" > <<span class="hljs-keyword">option</span> selected><span class="hljs-keyword">Open</span> this <span class="hljs-keyword">select</span> menu</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="1">One</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="2">Two</<span class="hljs-keyword">option</span>> <<span class="hljs-keyword">option</span> <span class="hljs-keyword">value</span>="3">Three</<span class="hljs-keyword">option</span>> </<span class="hljs-keyword">select</span>> </div> </<span class="hljs-keyword">template</span>>
<template>
    <div>
        <select
            class="form-select"
            aria-label="Default select example"
            v-model="modelValue"
            @change="$emit('update:modelValue', ($event.target as HTMLSelectElement).value)"
        >
            <option selected>Open this select menu</option>
            <option value="1">One</option>
            <option value="2">Two</option>
            <option value="3">Three</option>
        </select>
    </div>
</template>
[ads]
Ads