[Vue][自定义事件]关于组件prop双向绑定的理解和程序调试

父组件使用 prop 传递数据给子组件。子组件通过自定义事件与父组件通信。

自定义事件从子组件向父组件传递数据的步骤可大致归纳为:

1. 子组件模板中的原生事件(如click)绑定事件函数

2. 回调函数实现子组件内部数据的更新,同时触发自定义事件:$this.emit(//customEvent)

3. 父组件模板中v-on监听自定义事件

$emit+v-on偏向于事件函数的监听和触发,主要指向methods中的函数。

自定义事件的另一方面主要是针对prop自定义特性的双向绑定,偏向于纯数据的更新。采用以下方式:

父组件:<comp :foo="bar" @update:foo="val => bar = val"></comp>

子组件:this.$emit('update:foo', newValue) //当子组件需要更新 foo 的值时,它需要显式地触发一个更新事件

请看以下代码:

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>update改变父组件数据</title>
	<style type="text/css"></style>
	<script src = "https://unpkg.com/vue"></script>
</head>
<body>
	<div id="dr">
	    <!-- 注意! @update:my-message不能是驼峰和kebab-case模式-->
	    <h2>父组件{{name}}</h2>
	    <child :message="name" @update:message="val => name = val"></child>
	</div>

	
	<script>
//Prop双向绑定
	Vue.component("child", {
	    props: ["message"],
	    template: '<div>\
	    <p>{{message}}</p>\
	    <button @click="refresh">emit</button>\
	    </div>',
	    methods: {
	    	refresh: function () {
	    		this.$emit('update:message','brightRanger');
	    	}
	    }
	});
	var dr = new Vue({
	    el: "#dr",
	    data: {
	        name: "DarkRanger",
	    }
	});
	</script>
</body>
</html>

      

        而对于非表单,通常在子组件使用<button>按钮触发子组件的事件,子组件函数中$emit触发父组件的自定义事件;对于表单,v-model是一个原生事件,默认实现表单控件元素上的双向数据绑定,无法改写加入自定义的语句,如果要加入$emit触发父组件的自定义事件,就要对v-model变通,把语法糖还原:
(1)v-bind:value="something"
(2)v-on:input="something = $event.target.value">
在第(2)条input监听事件中加入$emit,触发父组件的数据更新

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>v-model变通实现父、子组件表单的双向绑定</title>
	<style type="text/css"></style>
	<script src = "https://unpkg.com/vue"></script>
</head>
<body>
	<h3>update改变父组件状态</h3>
	<div id="dr05">
	    <div>
	        <div>HTML表单</div>
	        <div>{{name}}</div>
	        <input type='text' v-model="name" />
	    </div>
	    <br />
	    <div>
	        <div>component组件的表单(update):</div>
	        <!--:message="name"是父更新子,@update:message是子更新父-->
	        <dr05 :message="name" @update:message="val => name = val"></dr05>
	    </div>
	</div>

	
	<script>
//Prop类型绑定
	Vue.component("dr05", {
	    props: ["message"],
	    //  当子组件需要更新子组件的值时,它需要显式地触发一个更新事件,父组件执行此事件更数据。对于非表单,通常在子组件使用<button>按钮触发子组件的事件,子组件函数中$emit触发父组件的自定义事件;对于表单,v-model是一个原生事件,默认实现表单控件元素上的双向数据绑定,无法改写加入自定义的语句,如果要加入$emit触发父组件的自定义事件,就要对v-model变通,把语法糖还原:
	    // (1)v-bind:value="something"
	    // (2)v-on:input="something = $event.target.value">
	    // 在第(2)条input监听事件中加入$emit,触发父组件的数据更新
	    template: '<div>\
	    <div>{{message}}</div>\
	    <input type="text" v-bind:value="message" v-on:input="refresh($event.target.value)" />\
	    </div>', // 注意事件函数中的形参,传入的参数是&event.target.value,
	    methods: {
	    	refresh: function (inputVal) {
	    		this.$emit('update:message',inputVal);
	    	}
	    }
	});
	var dr05 = new Vue({
	    el: "#dr05",
	    data: {
	        name: "DarkRanger",
	    }
	});
	</script>
</body>
</html>

最后再强调程序调试中发现的两点:

1. @update:foo="val => bar = val"语句中,prop名foo既不能用驼峰命名,也不能用kebab-case模式命名;

2. 表单prop双向传递中,$emit触发的事件函数,传入的参数是$event.target.value而不是value




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值