質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Q&A

解決済

2回答

498閲覧

Vue.js+Composition APIでの片方向バインディング(?)書き方がわかりません。

hayashida

総合スコア4

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

0グッド

0クリップ

投稿2023/02/25 15:07

前提

VueJS、Composition APIともに初心者です。
Visual Studio Code+Eslint+VolarでVueJSをお勉強しています。

実現したいこと

親コンポーネントから、子コンポーネントへ任意のタイミングで初期値を渡すのですが、
子コンポーネント側では、初期値として渡されたプロパティを更に変更可能としたいです。
ただ、いわゆる双方向バインディングは行わず、
親コンポーネントからは一方的に値を渡すだけの、片方向バインディング(?)を記述したいです。

上記内容について、記述方法をご存じの方がおられましたら、
ご教授頂けないでしょうか?

該当のソースコード

親コンポーネントは、子コンポーネントを配置し、ボタンで子コンポーネントの初期値を変更可能としています

ParentComponent.vue

1<template> 2 <div> 3 <div>{{ "親モードは「" + mode + "」モードです" }}</div> 4 5 <!-- 子モードの値を変更する --> 6 <div> 7 <button @click="mode = '追加'">追加</button> 8 <button @click="mode = '編集'">編集</button> 9 <button @click="mode = '照会'">照会</button> 10 </div> 11 <!-- 親モードは変えられたくないのでv-bindで渡す --> 12 <ChildComponent :mode="mode" /> 13 </div> 14</template> 15 16<script setup lang="ts"> 17import { ref } from "vue"; 18import ChildComponent from "./ChildComponent.vue"; 19 20type Mode = "" | "追加" | "編集" | "照会"; 21 22const mode = ref<Mode>(""); 23</script>

子コンポーネントで、プロパティ「mode」をそのままv-bindへ渡すことができなかったので、
computedでリアクティブ変数を用意してみたのですが。。。

ChildComponent.vue

1<template> 2 <div v-if="mode !== ''">{{ "子モードは「 " + refMode + "」モードです" }}</div> 3 4 <!-- 自分のモードを変更する --> 5 <select v-model="refMode"> 6 <option></option> 7 <option>追加</option> 8 <option>編集</option> 9 <option>照会</option> 10 </select> 11</template> 12 13<script setup lang="ts"> 14import { computed } from "@vue/reactivity"; 15import { defineProps, PropType } from "vue"; 16type Mode = "" | "追加" | "編集" | "照会"; 17 18const props = defineProps({ 19 mode: { 20 type: String as PropType<Mode>, 21 default: "", 22 }, 23}); 24 25const refMode = computed(() => { 26 return props.mode; 27}); 28</script>

発生している問題・エラーメッセージ

上記コードでは、子コンポーネント側で値を変えようとすると以下のエラーが発生します。

reactivity.esm-bundler.js:1188 Write operation failed: computed value is readonly

computed で作成した変数はreadonlyなのですね。。。

試したこと

Writable Computedというのもあるようですが、
試したところ、エラーは発生しなくなりましたが、相変わらず子コンポーネントの値は変わりません。

ChildComponent.vue

1// const refMode = computed(() => { 2// return props.mode; 3// }); 4const refMode = computed({ 5 get() { 6 return props.mode; 7 }, 8 set() { 9 // 親コンポーネントの値は変えたくないので何もしない 10 }, 11});

そもそも、Computedで作成した変数をv-modelに渡すのがダメなのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

refによって返されたmodeはmode.valueにしないと値を取得できないはずです。

refはイベントも継承させる働きを持つので、そのまま参照しようとしてもできないですよ。したがって、mode.valueを子コンポーネントに渡せば、そのままpropsから受け取れると思います。

投稿2023/04/20 06:52

FKM

総合スコア3640

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

親コンポーネントから、子コンポーネントへ任意のタイミングで初期値を渡すのですが、子コンポーネント側では、初期値として渡されたプロパティを更に変更可能としたいです。

コンポーネントでchildModeを定義し、onMounted()で値をコピーすればいいのでは。
https://ja.vuejs.org/api/composition-api-lifecycle.html#onmounted

<template> <div v-if="mode !== ''">{{ "子モードは「 " + childMode + "」モードです" }}</div> <!-- 自分のモードを変更する --> <select v-model="childMode"> ... type Mode = "" | "追加" | "編集" | "照会"; const childMode = ref<Mode>(""); const props = defineProps({ mode: { type: String as PropType<Mode>, default: "", }, }); onMounted(() => { this.childMode = newMode // ?? })

もし、途中で値が変わるのであれば、ウォッチャー https://ja.vuejs.org/guide/essentials/watchers.html を使う、とか。

watch(mode, async (newMode, oldMode) => { this.childMode = newMode // ?? })

投稿2023/02/26 02:45

shiketa

総合スコア3971

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayashida

2023/02/27 00:27

早速の回答ありがとうございます!! >もし、途中で値が変わるのであれば、ウォッチャーを使う、とか。 ウォッチャーを使うのが正解なのですね。。。 なんか、微妙ですね。。。 子コンポーネントは、親コンポートン側の使われ方を意識した作りにしないといけなんですね。。。 今回の質問では、親コンポーネント側の変数を変えたくないので、v-bindで渡しているのですが、 場合によっては、親コンポーネント側の変数を変えたい(子コンポーネント側で変更された値に)場合もあり、 その時はv-modelでパラメータを渡すのだと思うのですが、 ご提示頂いたコードでは、v-modelで渡しても、親コンポーネント側の値は変わらないんですよね? 親コンポーネントからv-bindで渡せば(途中で値が変更できる)初期値として、 v-modelで渡せば双方向バインディングとして、 のような子コンポーネントは出来ないのでしょうか?
FKM

2023/04/20 06:52

refによって返されたmodeはmode.valueにしないと値を取得できないはずです。 refはイベントも継承させる働きを持つので、そのまま参照しようとしてもできないですよ。したがって、mode.valueを子コンポーネントに渡せば、そのままpropsから受け取れると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問