【Vue.js】親子コンポーネント間のデータにラグがある
Q&A
Closed
解決したいこと
子コンポーネントのinput要素に入力される文字数を監視し、
文字数オーバーを検知したら、呼び出し元コンポーネントにあるbuttonをdisableにする。
前提
・フロントエンドをVue.js v2.6.10
・バックエンドをlaravelで構築しているアプリケーションを運用
・バックエンドは改修しない、vue.js側で解決する
・コンポーネントの構成も変えない(子の中にボタンを作るのは無し)
発生している問題・エラー
どうやらprops(子)の値が更新されるのが、emitで値を親が受け取ってからなので、
emitに渡した時点では値が最新にならずに1テンポ遅れて反映される。
<具体例>
親コンポーネント
<template>
<div>
<child
:name="userName"
@changeName="changeName($event)"
/>
</div>
<div>
<button :disabled="isDisabled">変更を保存</button>
</div>
</template>
(略)
<script>
export default {
data(){
return {
userName: "",
}
},
(略)
methods: {
changeName(e) {
this.isDisabled = e.error;
this.userName = e.value;
},
子コンポーネント
(略)
<template>
<input v-model="inputName" />
<span>{{inputName.length}}/10</span>
</template>
(略)
<script>
(略)
props: {
name: {
type: String,
},
(略)
computed: {
// ボタンの判定
isSubmitDisabled() {
return this.isNameOver
},
// 文字数オーバーの監視
isNameOver() {
return this.inputName.length > 10
},
inputName: {
get() {
if(!this.$props.name)return "";
return this.$props.name;
},
set(value) {
this.$emit('changeName', {value: value, error: this.isSubmitDisabled});
}
},
この場合、11文字目を入力した段階では何も起こらなず、12文字目を入力するとisDisabledが発動する。
自分で試したこと
・子コンポーネントでnameをwatchして{error: this.isSubmitDisabled}を$emitしてみたが、これも上手く動かなかった。