父子组件数据双向绑定

566 阅读2分钟
原文链接: blog.csdn.net

使用情景:一般情况下我们使用一个组件,可以通过prop给这个组件传值,组件可以使用emit来改变使用者的数据。如果频繁修改同一个数据,那么可以使用v-model进行父子组件数据的双向绑定。常用于处理输入的文本编辑组件。

下面的html代码复制到一个文件中运行即可显示效果

一、使用propemit实现双向绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<title>子父组件双向绑定</title>
	</head>
	<body>
		<div id="root"></div>
		<script type="text/javascript">
			const compoent = {
				props: {
					value: String
				},
				methods:{
					handleChange(e) {
                        //使用事件监听机制将事件发布出去,由父组件监听并获取
						this.$emit('input', e.target.value);
					}
				},
				template: `
					<div>
						子组件中的值:<input :value="value" @input="handleChange"></input>
					</div>`,
			}
			var app = new Vue({
				el:'#root',
				data(){
					return{
						value:''
					}
				},
				components:{
					CompOne: compoent //注册组件
				},
				template:`
					<div>
						父组件中的值:<input v-model='value'></input>
						<comp-one :value="value" @input="value = arguments[0]">
            			</comp-one>
					</div>`
			});
		</script>
	</body>
</html>

二、使用v-model实现双向绑定

事实上,上面的propemit已经实现了v-model的功能,下面的方式等效:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<title>子父组件双向绑定</title>
	</head>
	<body>
		<div id="root"></div>
		<script type="text/javascript">
			const compoent = {
				props: {
					value: String
				},
				methods:{
					handleChange(e) {
						this.$emit('input', e.target.value);
					}
				},
				template: `
					<div>
						子组件中的值:<input :value="value" @input="handleChange"></input>
					</div>`,
			}
			var app = new Vue({
				el:'#root',
				data(){
					return{
						value:''
					}
				},
				components:{
					CompOne: compoent //注册组件
				},
				template:`
					<div>
						父组件中的值:<input v-model='value'></input>
						<comp-one v-model="value"></comp-one>
					</div>`
			});
		</script>
	</body>
</html>

三、父子组件双向绑定的通用版本

至此,父子组件数组双向绑定功能已经实现,以后写组件的时候需要相互传数据的时候就可以这样使用了。但是上面的写法限定了我们父子组件的数据必须使用同一个变量,名字需要一致,因此需要改进,给子组件加上一个model属性:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<title>子父组件双向绑定</title>
	</head>
	<body>
		<div id="root"></div>
		<script type="text/javascript">
			const compoent = {
				model: {
					prop: 'value1',
					event: 'change'
				},
				props: ['value1'],
				methods:{
					handleChange(e) {
						this.$emit('change', e.target.value);
					}
				},
				template: `
					<div>
						子组件中的值:<input :value="value1" @input="handleChange"></input>
					</div>`,
			}
			var app = new Vue({
				el:'#root',
				data(){
					return{
						value:''
					}
				},
				components:{
					CompOne: compoent
				},
				template:`
					<div>
						父组件中的值:<input v-model='value'></input>
						<comp-one v-model="value"></comp-one>
					</div>`
			});
		</script>
	</body>
</html>