vue親子コンポーネントの双方向バインド伝達の実現


vueは一方向データストリームであるため、親子コンポーネントの値伝達中にpropsを使用して親コンポーネントの値をサブコンポーネントに渡すだけで、サブコンポーネントでprops伝達のデータを直接変更することはできません.サブコンポーネントでpropsから渡された値を変更すると、コンソールがエラーを報告します.つまり、データは常に親コンポーネントから子コンポーネントに渡され、子コンポーネントは親コンポーネントから渡された値を変更できません.親コンポーネントから渡された値を変更するには、親コンポーネントで元のデータを変更するしかありません.上記の考え方に基づいて、コンポーネントの値伝達の双方向バインドを実現することができ、以下のいくつかの方法をまとめた.
一、従来の方法
親コンポーネントはpropsを通じてサブコンポーネントに値を伝達し、同時に自分のデータを更新する方法を提供する.サブコンポーネントは、データを受信し、サブコンポーネントでデータを変更するときに親コンポーネントをトリガーする方法で、最新の値を親コンポーネントに渡します.
//    
<template>
	<child :msg='msg' :changeMsg='changeMsg'></child>
</template>
<script>
	import child from './child.vue';
	export default {
     
		components:{
      child };
		data(){
     
			return {
     
				msg:0
			}
		},
		methods:{
     
			changeMsg(data){
     
				this.msg = data;
			}
		}
	}
</script>
//    
<template>
	<div>
		<el-input :value='msg' @input='change($event)'></el-input>
	</div>
</template>
<script>
	export default {
     
		name:'child',
		props:{
     
			msg:[Number,String],
			changeMsg:Function //        
		},
		methods:{
     
			change(e){
     
				this.changeMsg(e);
			}
		}
	}
</script>

もう1つの類似の方法は、親コンポーネントがpropsを介してサブコンポーネントに値を渡し、自分のデータを更新する方法を提供し、サブコンポーネントが値を変更するときに$emitを介して親コンポーネントメソッドをトリガーし、最新の値を渡します.
二、sync修飾子
親コンポーネントの使用sync双方向バインド、サブコンポーネントは$emitによってupdate:prop名をトリガして親コンポーネントのデータを変更し、双方向バインドを実現します.
//    
<template>
	<child :msg.sync='msg'></child>
</template>
<script>
	import child from './child.vue';
	export default {
     
		components:{
      child };
		data(){
     
			return {
     
				msg:0
			}
		},
		methods:{
     
			changeMsg(data){
     
				this.msg = data;
			}
		}
	}
</script>
//    
<template>
	<div>
		<el-input :value='msg' @input='change($event)'></el-input>
	</div>
</template>
<script>
	export default {
     
		name:'child',
		props:{
     
			msg:[Number,String]
		},
		methods:{
     
			change(e){
     
				// update     ,      msg, e         
				this.$emit('update:msg',e);
			}
		}
	}
</script>

.sync修飾子は略記です.
<child :msg.sync='msg'></child>
//   
<child :msg.sync='msg' @update:msg='msg=e'></child>

三、v-model
vueカスタムコンポーネントv-modelの構文糖:
<child v-model='msg'></child>
//   
<child :msg.sync='msg' @update:msg='msg=e'></child>

したがって,サブコンポーネントで親コンポーネント値を変更するにはinputメソッドを呼び出すだけでよい.
//    
<template>
	<child :msg='msg' v-model='msg'></child>
</template>
<script>
	import child from './child.vue';
	export default {
     
		components:{
      child };
		data(){
     
			return {
     
				msg:0
			}
		}
	}
</script>
//    
<template>
	<div>
		<el-input :value='msg' @input='change($event)'></el-input>
	</div>
</template>
<script>
	export default {
     
		name:'child',
		props:{
     
			msg:[Number,String]
		},
		methods:{
     
			change(e){
     
				this.$emit('input',e);
			}
		}
	}
</script>

Inputを使用したくない場合は、カスタムメソッドを使用して親コンポーネントの値を変更するには、親コンポーネントにメソッドを定義し、サブコンポーネントにmodelを構成するだけです.
//    
<template>
	<div>
		<el-input :value='msg' @input='change($event)'></el-input>
	</div>
</template>
<script>
	export default {
     
		name:'child',
		model:{
     
			prop:'msg', //         
			event:'changeData' //               	
		},
		props:{
     
			msg:[Number,String]
		},
		methods:{
     
			change(e){
     
				this.$emit('changeData',e);
			}
		}
	}
</script>