vue之组件通信

注意: 组件通信, 无论效果是如何的, Vue都是单向数据流(组件之间的数据通信)

1. 父子组件通信

A: 绑定的是简单类型数据

  • 父组件中定义数据, 通过单向数据绑定的形式, 将数据绑定在子组件身上, 属性是自定义属性,
  • 子组件通过配置项中的props接收数据, props可以是一个数组,数组中放的是自定义属性名称
  • 那么这个自定义属性可以向data中的数据一样直接在子组件模板中使用
  • 父组件中数据一旦修改, 子组件数据就会修改, 那么这也就是单项数据流

通过 v-bind 和props 进行动态绑定数据 ,

<body>
         <div id="app">
                 <Father></Father>
         </div>

                <template id="father">   //template外用
                          <div>
                                <h3>我是</h3>
                                <Son :sw="cd"> </Son>
  //对于这里   使用 v-bind:sw=“cd” 其中sw代表的是子组件的值,指的就是props后面的值,
  //cd代表的是父组件的属性,指的是data里面的
                          </div>
                </template>

 	<template id="son" >
 	            <h3>  {{ sw }}  </h3>            
        </template>
 
<script>
 Vue.component( 'Father',{  //创建Father组件
             template: '#father',
              data(){    //除了new Vue实例其他地方的data都是用data函数表示,而且还要有return返回值
                       return {
                              cd: 5000
                           } 
                    }
             })
 
 Vue.component( 'Son',  {   //创建Son组件
                     template:'#son',   //挂载
                       props:['sw']  //设置sw属性
                        })
 
 new Vue({
          el: '#app',
 })
</script>
1.5. 子父通信(效果上像, 间接的使用了父组件的东西 ) 【不推荐大家使用】

B: 绑定复杂数据类型 --------

  • 父组件中的数据是一复杂数据类型, 那么父组件绑定数据的时候, 给子组件的是一个引用地址
  • 子组件可以通过这个引用地址, 修改这个数据
  • 效果上像, 子组件和父组件通信了, 违背单项数据流
	<body>
	  //对于在这里父元素传递给子元素的值肯定是复杂数据类型(引用类型)像对象,数组,才能在改变子元素值的同时改变父元素的值
	        <div id='app'>
	                <Farther></Farther>
	        </div>
	
	    <template id="farther">
			<div>
				<h3> farther </h3>
				得到 {{ get.money }}
				<Son :offer="get"></Son>
			</div>
	    </template>
	
		<template id="son">
			<div>
				<h3>son</h3>
				<input type="text" v-model="offer.money"> 
				上交 {{ offer.money }}
			</div>
		</template>
		
	<script>
	Vue.component('Farther',{
	                 template: '#farther',
	                 data(){
	                   return{
	                          get:{
	                                money:''
	                              }
	                          }
	                   }
	              })
	
	Vue.component('Son',{
	                template:'#son',
	                props:['offer']
	               })
	
	new Vue({
	          el: '#app',
	        })
	</script>
	</body>

C: 父组件可以传递一个方法给子组件

  • 父组件定义方法, 然后将这个方法通过单向数据绑定的形式传递给子组件
  • 子组件通过props属性接收, 然后通过 @click = “方法名”
		<body>
		        <div id="app">
		              <Farther></Farther>
		        </div> 
		
		<template id="farther">
		        <div>
		                 得到 {{ all }}
		                 <Son :offer='get'> </Son>
		        </div>
	    </template>
	
	  <template id="son">
		<div>
			<button
			@click="offer(1000)" 
			>上交</button>
		</div>
	 </template>
	
	<script>
		Vue.component('Farther',{
		                  template:'#farther',
		                            data(){
		                                return {
		                                         all:0,
		                                        }
		                                  },
						methods:{
						     get(val){
						          this.all += val
						             }
						  }
		                  })
		
		Vue.component('Son',{
		            template:'#son',
		             props:['offer']
		        })
		
		new Vue({
		          el:'#app'
		       })
	</script>

2. 通过自定义事件来实现通信

  1. 父组件中定义 数据 和 方法(方法时用来操作数据的)
  2. 在子组件身上绑定自定义事件 通过@eventType=‘父组件中要执行的函数’@就是V-on的缩写
  3. 子组件定义方法, 在这个方法中通过 this.$emit(eventType,实际参数) 来调用自定义事件的事件处理程序
	<div id="app">
	          <Farther></Farther>
	</div>
	
	   <template id="farther">
	        <div>
	            <h3>获得 {{ val }}</h3>
	            <Son @suibian='get'></Son>   
	        </div>
	  </template>
	
	  <template id="son">
	      <div>
	            <h3> {{ all }}</h3>
	          <button @click='give'>上交</button>
	     </div>
	  </template>
	
	  <script>
	        Vue.component('Farther',{
	                   template:'#farther',
	                              data () {
			                        return{
			                             val:0
			                           } 
	                                   },
	                   methods:{
	                            get(arg){
	                                   this.val += arg 
	                                    }
	                              }
	                     })
	
	       Vue.component('Son',{
	                     template:'#son',
	                                 data () {
	                                        return {
	                                                  all:1000
	                                                }
	                                         },
	                      methods:{
	                                  give () {
	                                        this.$emit('suibian',this.all)
	                                             }
	                                     }
	                            })
	
	     new Vue({
	           el:'#app',
	         })
	</script>
3. 非父子组件通信

1- 使用ref来绑定组件, (注意:ref也可以绑定DOM元素) 【ref链】

  • 在父组件的模板中, 使用ref = refName 绑定在两个兄弟组件身上
  • 在任意一个子组件中, 就可以通过 this. p a r e n t . parent. parent.refs.refName 就可以获得另一个子组件了, 同时这个自组件身上的数据和方法同样也得到了
    <body>
         <div id="app">
               <Farther></Farther>
         </div>
   
       <template id="farther">
          <div> 
               <h3>父亲</h3>
               <Boy ref='boy'></Boy>  //绑定ref
               <Girl ref='girl'></Girl>   
          </div>
       </template>
   
       <template id="boy">
            <div>
              <h3>男孩</h3>
              {{ pocket }}
           </div>
        </template>
   
        <template id="girl">
             <div>
                <h3>女孩</h3>
               {{ once }}
               <button @click='give'></button>
            </div>
        </template>
   
      </body>
   <script>
   	Vue.component('Farther',{
   	              template: '#farther',
   	})
   	
   	Vue.component('Boy',{
   	                template: '#boy',
   	                data () {
   	                return {
   	                     pocket:200
   	                         }
   	                   },
   	                methods:{
   	                       increment(arg){
   	                                this.pocket += arg
   	                                }
   	                        }
   	                 })
   	
          Vue.component('Girl',{
                           template: '#girl',
                          data () {
                          return{
                                once:500 
                                 } 
                             },
                          methods:{
                                 give () {
                                      this.$parent.$refs.boy.increment(this.once)  //必须在<Boy/>和<girl/>组件里面写ref并且赋个名称才能有效,单纯的只写ref 也能会有输出,但是只有赋了名字才能找到具体的主件
                                          }
                                     }
                             })
                  new Vue({
                           el: '#app'
                           })
   </script>

2- 通过事件总线(bus)

  • 它是通过事件的发布(声明), 以及事件的订阅(触发)来做的
  • 首先在js中 创建一个bus对象(vm)
                var bus = new Vue()
    
  • 在Count组件中定义数据, 和修改数据的方法
  • 在Count组件中 通过 created 钩子 , 进行bus事件的发布
       created: {
              bus.$on('add',this.increment)
       }
    
  • 在MyButton组件的方法中通过 bus进行事件的订阅
        dingYue () {
                 bus.$emit( 'add' )
        }
    
	 <body>
	       <div id="app">
	            <my-button></my-button>
	            <Num></Num>
	       </div>
	
	      <template id="zeng">
	          <div>
	              <button id="increment"
	                @click="chu"
	              >增加</button>
	         </div>
	      </template>
	
	       <template id="num">
	           <div>
	              {{ count }}
	           </div>
	       </template>
	
	  <script>
		var bus=new Vue;
		Vue.component('MyButton',{
				template: '#zeng',
				methods:{
				    dingYue () {
				         bus.$emit('add')
				        }
		              }
		      })
		
		Vue.component('Num',{
		           template:'#num',
		            data () {
		                   return{
		                         count:0
		                        }
		                   },
		           methods:{
		                increment(){
		                        this.count++
		                                }
		                         },
		           created(){
		                  bus.$on('add',this.increment)
		                    }
		             })
		
		 new Vue({
		        el: '#app',
		   })
      </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值