Vue实践--父子组件间的通信(未完待续)

父子组件间的通信(在这里父组件就是你自定义的标签,子组件就是父组件template里面的内容),父组件通过props选项向子组件传递参数或数据,子组件接收到参数后根据参数的不同来执行不同的操作。也就是说,在组件中使用props选项来声明需要从父组件接受的数据(通俗点说就是,组件在注册的时候通过props选项声明子组件(template所指)需要从父组件中接受的数据),props选项的值可以是字符串数组或者对象

值是字符串数组:

HTML部分:

<!-- (例1):父子通过props传递 -->
		<my-component :message="msg" array="[1,2,3,4]"></my-component>
JS部分:

Vue.component("my-component",{
			props:["message","array"],
			// 子组件
			template:"<div >{{message}}<div @click='changeVal'>{{message}}</div></div>",
			
		})
注意:
  1.如果你直接在父组件上自定义属性并且传递数字,布尔值,数组,对象,而不是使用v-bind在父组件上绑定属性,传递的仅仅是字符串。如下面的例子:

HTML部分:

<my-component array="[1,2,3,4]"></my-component>
		<!-- 9 -->
		<my-component :array="dataArray"></my-component>
		<!-- 4 -->
JS部分:

	Vue.component("my-component",{
			props:["message","array"],
			// 子组件
			template:"<div >{{message}}<div @click='changeVal'>{{message}}</div></div>",
			data:function(){
				return {
					tips:"我来自data选项"
				}
			}
			
		})
		var myApp = new Vue({
			el:"#container",
			data:{
				msg:"来自父组件上的数据",
				dataArray:[1,2,3,4],
				initMsg:"初始化数据"
			}
		})

 2.同一个组件在复用的时候是相互独立的

通过上例我们可以发现,无论是组件中data函数的返回值还是从父组件中传递过来的数据,子组件都能操作,那么他们之间有何区别呢
我个人感觉主要是作用域:props声明的数据可能来自于Vue实例中的data选项,而data函数返回值,其作用域仅仅在于组件内部,是自己的私有数据。因此可以在data函数中将props数据作为返回值保存起来,这样以后你就可以随意操纵数据了,也就避免了直接操纵父组件数据,从而影响父组件。
其实在Vue2.x中,通过props传递数据是单向的,也就是说,当父组件数据的变化会引起子组件数据的变化,但是反之不行,这也意味着,其实在子组件中无论你怎么操作从props传递过来的数据,父组件的状态都不会改变

为了验证这个想法,看下面的例子

HTML部分:

<div class="model">
			<our-component :mero="initMsg"></our-component>
			<input type="text" name="test" v-model = "initMsg">
			<span>{{initMsg}}</span>
		</div>
JS部分:

Vue.component("our-component",{
			props:["mero"],
			template:"<div @click='changeMSG'>{{mero}}</div>",
			methods:{
				changeMSG:function(){
					alert(1)//this表示当前的组件our-component(可以视组件的地位和Vue实例的地位差不多)
					this.mero = "我被改变啦!"
				}
			}
		})
		
		var myApp = new Vue({
			el:"#container",
			data:{
				msg:"来自父组件上的数据",
				dataArray:[1,2,3,4],
				initMsg:"初始化数据"
			}
		})

结果:

初始化的时候是这样的:


当触发点击事件的时候,变成了这样:


可以看到,span元素内的值一直都没有变化,也就说明实例中的initMsg没有发生改变,由于v-bind是双向绑定的,所以父组件中对应的属性没有发生改变(虽然我们看不到),但即使是这样也要注意:为了安全起见,从父组件中传递过来的数据,要在组件的data选项中将其保存起来,或者利用计算属性


说完了父组件向子组件传递数据,那么子组件要向父组件传递数据该怎么办?其实子组件向父组件通信通过$emit()实现;

大意为子组件使用了一个事件,比如click然后产生了一个效果(组件中methods选项中的函数做的事),然后将这样的效果命名放入父组件(this.$emit(自定义事件名,[参数1]),[参数2]……),注意事件名要小写字母,不要用驼峰命名法)中,当做一个事件来触发,每当这样的效果发生一次时,这样父组件的事件也被触发了(v-on给父组件绑定以上自定义事件),即可以产生另一种效果(一般操作的是Vue实例中的数据,随意操作,可以传参参数子组件中的数据,也可以不传),这样可以加强这两个效果的紧密联系,并且这样有趣又好用的方式也可以用在自己想要的地方。这样当绑定在子组件上的事件触发的时候,父组件上的事件也会触发并执行一系列方法。

例如:

HTML部分

<div id="container" v-cloak>
		<p>当前的值是:<span>{{total}}</span></p>
		<!-- 给父组件绑定自定义事件 -->
		<my-component
		 @increasefunc="changeTotal"
		@decreasefunc="changeTotal"
></my-component></div>

JS部分:

// 自定义组件;
		Vue.component("my-component",{
			template:"\
					<div>\
						<button @click='increaseTotal'>add</button>\
						<button @click='decreaseTotal'>reduce</button>\
					</div>",
			data:function(){
				return{
					counter:0
				}
			},
			methods:{
				increaseTotal:function(){
					this.counter++;
					console.log(this.counter)
					// 同下
					this.$emit("increasefunc",this.counter);
				},
				decreaseTotal:function(){
					this.counter--;
					console.log(this.counter);
					// 定义自定义事件名,第一个参数是事件名,第二个参数及以后是要传递的数据
					// 也可以不传递参数,事件名自定义
					this.$emit("decreasefunc",this.counter)
				}
			}
		})
		var myApp = new Vue({
			el:"#container",
			data:{
				total:0
			},
			methods:{
				changeTotal:function(total){
					// 形参total用来保存从子组件传递过来的数据的,也可以不传参,
					this.total++;
				}
			}
		})
以上当点击绑定在子组件上的click事件的时候,就会通过this.$emit()方法“告诉”父组件:子组件点击了(事件被触发了),那么此时绑定在父组件上的对应的自定义事件也会触发,并执行相应的函数changeTotal函数,实现了子组件和父组件事件的单向紧耦合






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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值