株式会社コードリック株式会社コードリック
トップ
TOP
会社情報
COMPANY
請負開発
ORDER
自社開発
PRODUCT
開発実績
RECORD
お知らせ
NEWS
ブログ
BLOG
お問い合わせ
CONTACT
TOPトップCOMPANY会社情報ORDER請負開発PRODUCT自社サービスRECORD開発実績NEWSお知らせBLOGブログCONTACTお問い合わせ
BLOG
ブログ
  1. TOP > 
  2. BLOG
  3.  > プログラミング
  4.  > Vue.js3.4で簡単になった親子間の双方向バインディング
2024/4/5

Vue.js3.4で簡単になった親子間の双方向バインディング

プログラミング
どうもこんにちは!樋渡です。

今回は、Vue3.4で安定版になった「defineModel」についてのお話です。
実験的に導入されたVue3.3の時から非常に便利だと思っていたので、これで気兼ねなく使うことができます。

defineModelは主に、親子間での双方向バインディングをしたい時に使います。
以前までの書き方よりも、直観的かつ簡略化して記述することが出来ます。

早速、具体的な使用方法について触れていきましょう。
今回はインプットフォームのコンポーネントを例に説明していきます。
まずは、共通して使う親側のvueファイルを記述します。

▼親コンポーネント 

// parent.vue
<script lang="ts" setup>
import children from "./children.vue";
import { ref } from "vue";
const message = ref("")
</script>
<template>
<children type="text" v-model="message" />
</template>

そして、従来の書き方で親子間の双方向バインディングをすると下記のようになります。

▼子コンポーネント(以前までの記述)

// children.vue
<script lang="ts" setup>
const props = defineProps({
modelValue: {
type: String,
required: true,
})
const emit = defineEmits(['update:modelValue'])
const model = computed({
get: () => props.modelValue,
set: (val: string) => emit('update:modelValue', val)
})
</script>
<template>
<input type="text" v-model="model" />
</template>

今見ても少しややこしい書き方だなと思います。
インプットフォームのコンポーネントくらいであれば、もっとシンプルに書きたいものです。
defineModelを使えば、もっと短い記述で全く同じことができます。

▼子コンポーネント(defineModelを使った記述)

// children.vue
<script lang="ts" setup>
const model = defineModel<string>()
</script>
<template>
<input type="text" v-model="model" />
</template>

以前までの記述と比べると、非常にシンプルですよね。
複数のv-modelを渡したい時は下記のようにします。

▼子コンポーネント(複数のv-modelを渡す)

// children.vue
<script lang="ts" setup>
const name = defineModel<string>("name")
const address = defineModel<string>("address")
</script>
<template>
<input type="text" v-model="name" />
<input type="text" v-model="address" />
</template>

 ▼親コンポーネント

// parent.vue
<script lang="ts" setup>
import children from "./children.vue";
import { ref } from "vue";
const name = ref("")
const address = ref("")
</script>
<template>
<children type="text" v-model:name="name" />
<children type="text" v-model:address="address" />
</template>

子コンポーネント側でそれぞれに名前を付けてあげて、親側で指名して使うといった感じです。
また、defaultやrequiredのオプションも付与することが出来ます。

▼子コンポーネント(default等のオプションを付ける)

// children.vue
<script lang="ts" setup>
const name = defineModel<string>("name", { required: false, default: "匿名" })
const address= defineModel<string>("address", { required: true })
</script>
<template>
<input type="text" v-model="name" />
<input type="text" v-model="address" />
</template>

さらに、親から渡ってきた値を少し変更したい場合は、computedを使わなくもdefineModelに直接、getやsetが使えるようです。
できる事が同じで短く書けるなら、それに越したことはないですよね。

親子間の双方向バインディングは使用頻度が高いと思いますので、まだ使ったことがない方はぜひ試してみてください。
back
トップ
TOP
会社情報
COMPANY
請負開発
ORDER
自社サービス
PRODUCT
開発実績
RECORD
お知らせ
NEWS
ブログ
BLOG
お問い合わせ
CONTACT
トップ
TOP
会社情報
COMPANY
請負開発
ORDER
自社サービス
PRODUCT
開発実績
RECORD
お知らせ
NEWS
ブログ
BLOG
お問い合わせ
CONTACT
株式会社コードリック
〒920-0362 石川県金沢市古府3丁目45-2
TEL 076-249-8388 / FAX 076-203-0044
SDGsのロゴ
株式会社コードリック
〒920-0362 石川県金沢市古府3丁目45-2
TEL 076-249-8388 / FAX 076-203-0044
プライバシーポリシー
SDGsのロゴ
©株式会社コードリック. All Rights Reserved.プライバシーポリシー
©株式会社コードリック. All Rights Reserved.