VueJS(七)

今天继续学习组件通信

昨天学到父组件在子组件的自定义标签上使用v-on来监听子组件触发的自定义事件

<body>
		<div id="app">
			<p>总数:{{total}}</p>
			<my-component
			   @increase="handleGetTotal"   
			   @reduce="handleGetTotal"></my-component>
		</div>
		<script>
			Vue.component('my-component',{
				template:'\
				<div>\
				   <button @click="handleIncrease">+1</button>\
				   <button @click="handleReduce">-1</button>\
				</div>',
				data:function(){
					return {
						counter:0
					}
				},
				methods:{
					handleIncrease:function(){
						this.counter++;
						this.$emit('increase',this.counter);
					},
					handleReduce:function(){
						this.counter--;
						this.$emit('reduce',this.counter);
					},
				}
				
			});
			var app =new Vue({
				el:'#app',
				data:{
					total:0
				},
				methods:{
					handleGetTotal:function(total){
						this.total = total;
					},
				}
			})
		</script>
	</body>

子组件一共两个按钮,分别实现加一减一的功能,在改变组件data中的counter后,通过$emit()再把它传递给父组件,父组件使用两个v-on绑定(v-on:可以简写成@),$emit()的第一个参数是自定义事件的名字,后面的都是需要传递的参数,可以多写或者不写。
这个就是子组件向父组件传递数据的过程!!!

v-on在珠江上除了有监听自定义事件的功能外,还可以监听DOM时间,用上.native的修饰符表示监听的是一个原生事件(???不知道)

<my-qian v-on:click.native="handleClick"></my-qian>

使用v-model
自定义组件上可以使用v-model指令

		<script>
			Vue.component('my-component',{
				template:'<button @click="handleClick">+1</button>',
				data:function(){
					return{
						counter:0
					}
				},
				methods:{
					handleClick:function(){
						this.counter++;
						this.$emit('input',this.counter);
					}
				}
			});
			var app = new Vue({
				el:'#app',
				data:{
					total:0
				}
			})
		</script>
	</body>

就标签本来是通过绑定函数,函数再传值,使用v-model的时候就是直接绑定了数据

v-model还可以用来创建自定义的表单输入组件

<body>
		<div id="app">
			<p>{{total}}</p>
			<my-component v-model="total"></my-component>
			<button @click = "handleReduce">-1</button>
		</div>
		<script>
			Vue.component('my-component',{
				props:['value'],
				template:'<input :value="value" @input="updateValue">',
				methods:{
					updateValue:function(event){
						this.$emit('input',event.target.value);
					}
				}
			});
			var app = new Vue({
				el:'#app',
				data:{
					total:0
				},
				methods:{
					handleReduce:function(){
						this.total--;
					}
				}
			})
		</script>
	</body>

非父子组件通信
一般指的是兄弟组件和跨多级组件

vue它所使用的方式是找一个空的vue实例作为中央事件总线
也就是所谓的中介

	<body>
		<div id="app">
			{{message}}
			<component-a></component-a>
		</div>
		<script>
			var bus = new Vue();
			
			Vue.component('component-a',{
				template:'<button @click="handleEvent">传递时间</button>',
				methods:{
					handleEvent:function(){
						bus.$emit('on-message','来自组件component-a的内容');
					}
				}
			});
			
			var app = new Vue({
				el:'#app',
				data:{
					message:''
				},
				mounted:function(){
					var _this = this;
					bus.$on('on-message',function(msg){
						_this.message = msg;
					});
				}
			})
		</script>
	</body>

首先,他这里是创建了一个空的vue实例,bus,定义了一个组件comonent-a,还有一个vue实例app
在实例app注册的内容中监听了来自bus的一个事件on-message,在组件中点击按钮会通过bus把事件on-message发出去,此时app就会收到来自bus的事件

简单概括流程就是这个组件是注册了一个按钮,按钮点击的函数handleEvent内容是bus,然后注册的实例app是在监听这个bus的事件的,一旦点击将函数的参数赋值给message,这样一来就做到了组件和一个vue实例之间的数据通信,实质上他们是通过bus交流的,bus获得了组件的数据,vue实例又通过bus获得数据,属实绕

除了使用中央事件总线bus这个手段外,还有两种方法:

父链
在子组件中,使用this.$parent可以直接访问该组件的父实例或组件,父组件也可以使用this.$children来访问他所有的子组件,而且可以递归向上或向下无限访问,直至根实例或最内层的组件

<body>
		<div id="app">
			{{message}}
			<component-a></component-a>
		</div>
		<script>
			Vue.component('component-a',{
				template:'<button @click="handleEvent">通过父链直接修改数据</button>',
				methods:{
					handleEvent:function(){
						this.$parent.message='xxxxxxxxxx';
					}
				}
			});
			var app = new Vue({
				el:'#app',
				data:{
					message:''
				}
			})
		</script>
	</body>

就直接访问父的数据,但是书上说这样容易提高耦合度,应该避免
推荐使用props和$emit来通信

然后是子组件索引

	<body>
		<div id="app">
			<button @click="handleRef">通过ref获取子组件实例</button>
			<component-a ref="comA"></component-a>
		</div>
		<script>
			Vue.component('component-a',{
				template:'<div>子组件</div>',
				data:function(){
					return {
						message:'子组件内容'
					}
				}
			});
			var app =new Vue({
				el:'#app',
				methods:{
					handleRef:function(){
						var msg = this.$refs.comA.message;
						console.log(msg);
					}
				}
			})
		</script>
	</body>

就是通过一个索引一样的形式,

var msg = this.$refs.comA.message;

获得组件中message的数据值

使用slot分发内容
混合使用父组件内容和子组件模板的时候,会使用到slot

props传递数据、events触发事件、slot内容分发构成了Vue组件的3个API来源

作用域的概念
编译的作用域

<child-component>
     {{message}}
</child-component>

这里的message就是一个shot?,他绑定的是父组件的数据而不是组件<child-component>的数据
父组件模板的内容实在父组件的作用域内编译,子组件模板的内容实在子组件作用域内编译?
这好像说的废话

<body>
		<div id="app">
			<my-qian v-show="showqian"></my-qian>
		</div>
		<script>
			Vue.component('my-qian',{
				template:'<div>子组件</div>'
			});
			var app = new Vue({
				el:'#app',
				data:{
					showqian:true
				}
			})
		</script>
	</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值