Vue组件 ( 组件通信 )

组件注册

  1. Vue.component(组建名称, 组件的配置)
  2. 在组件中使用components的配置项来表示
  3. 问题:
    组件命名问题
    • 组件命名和html原生标签冲突 Header Footer ----> header footer

    • 大驼峰的写法

        Vue.componennt('ZhangJun',{
          template: '<div></div>'
        })
      
      
        <div id = "app">
          <!-- <ZhangJun></ZhangJun>   错的-->
          <zhang-jun></zhang-jun>
        </div>
      
      
        .box{
          background-color: red
        }
      
      
        box.style.backgroundColor = 'red'
      

组件通信

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

  1. 父子组件通信
    • 绑定的是简单类型数据
      1. 父组件中定义数据, 通过单向数据绑定的形式, 将数据绑定在子组件身上, 属性是自定义属性,
      2. 子组件通过配置项中的props接收数据, props可以是一个数组,数组中放的是自定义属性名称
      3. 那么这个自定义属性可以向data中的数据一样直接在子组件模板中使用
      4. 父组件中数据一旦修改, 子组件数据就会修改, 那么这也就是单项数据流
      5. 案例:
               <!-- html代码 --!>
         	  <div id="app">
         	    <Father></Father>
         	  </div>
         	  <template id="father">
         	    <div class="father-box">
         	      <h3> father 组件</h3>
         	      <hr>
         	      <Son v-bind:money = "money"></Son>
         	      <Son :money = "money"></Son>
         	    </div>
         	  </template>
         	  <template id="son">
         	    <div class="son-box">
         	      <h3> son 组件</h3>
         	      <p> 我爸这个月给了我: {{ money }}生活费 </p>
         	    </div>
         	  </template>
      
         //JS代码
      	<script>
      	  Vue.component('Father',{
      	    template: '#father',
      	    data(){
      	      return {
      	        money: 1000
      	      }
      	    }
      	  })
      	  Vue.component('Son',{
      	    template: '#son',
      	    props: ['money']
      	  })
      	  new Vue({
      	    el: '#app'
      	  })
      	</script>
          ```
      
  2. 子父通信(效果上像, 间接的使用了父组件的东西 ) 【不推荐大家使用】
    • 绑定复杂数据类型 --------
    • 父组件中的数据是一复杂数据类型, 那么父组件绑定数据的时候, 给子组件的是一个引用地址
    • 案例:
  		<div id="app">
  		    <Father></Father>
  		  </div>
  		  <template id="father">
  		      <div>
  		        <h3>father</h3>
  		        <p>father现在有: {{sifangqian.money}} 块 </p>
  		        <Son :sifangqian = 'sifangqian'></Son>
  		      </div>
  		  </template>
  		  <template id="son">
  		    <div>
  		      <h3>Son</h3>
  		      <input type="text" v-model = "sifangqian.money">
  		      <p> 老爸给了我:{{ sifangqian.money  }}块 </p>
  		    </div>
  		  </template>
<script>
		    //JS代码
		  Vue.component('Father',{
		    template: '#father',
		    data(){
		      return {
		       sifangqian: {
		         money: 1000
		       }
		      }
		    }
		  })
		  Vue.component('Son',{
		    template: '#son',
		    props: ['sifangqian']
		  })
		  new Vue({
		    el: '#app'
		  })
		</script>
 3. 子组件可以通过这个引用地址, 修改这个数据
 4. 效果上像, 子组件和父组件通信了, 违背单项数据流 
 5. 案例:
				 <div id="app">
				    <King></King>
				  </div>
				  <template id="king">
				      <div>
				        <h3> 我是国王: </h3>
				        <p> 我国库中有:{{ gk }} 钱 </p>
				        <People :getmoney = "getMoney"></People>
				      </div>
				  </template>
				  <template id="people">
				      <div>
				        <h3> 我是国王的子民 </h3>
				        <button @click = "getmoney(1000)"> 上缴 </button>
				      </div>
				  </template> 
 				//JS代码
 				<script>
 				  Vue.component('King',{
 				    template: '#king',
 				    data(){
 				      return {
 				        gk: 0
 				      }
 				    },
 				   methods: {
 				    getMoney(value){
 				      this.gk += value
 				    }
 				   }
 				  })
 				  Vue.component('People',{
 				    template: '#people',
 				    props: ['getmoney']
 				  })
 				  new Vue({
 				    el: '#app'
 				  })
 				</script>
 -父组件可以传递一个方法给子组件
   1. 父组件定义方法, 然后将这个方法通过单向数据绑定的形式传递给子组件
   2. 子组件通过props属性接收, 然后通过 @click = "方法名"
  
 - 通过自定义事件来实现通信
   1. 父组件中定义 数据  和  方法(方法时用来操作数据的)
   2. 在子组件身上绑定自定义事件
   3. 子组件定义方法, 在这个方法中通过  this.$emit(eventType,实际参数) 来调用自定义事件的事件处理程序
          <!-- html结构代码 -->
          <div id="app">
            <King></King>
          </div>
          <template id="king">
              <div>
                <h3> I am king </h3>
                <!-- <People v-on: get = "get"></People> -->
                <p> 国库中有:{{ gk }} 钱 </p>
                <People @get = "get"></People>
              </div>
          </template>
          <template id="people">
            <div>
              <h3> I am people </h3>
              <button @click = "give"> 交钱 </button>
            </div>
          </template>
          <!-- js代码 -->
            Vue.component('King',{
              template: '#king',
              data () {
                return {
                  gk: 0
                }
              },
              methods: {
                get( value ){
                  this.gk += value 
                }
              }
            })
            Vue.component('people',{
              template: '#people',

              data () {
                return {
                  money: 2000
                }
              },
              methods: {
                give () {
                  this.$emit('get', this.money/2)
                }
              }
            })
            new Vue({
              el: '#app'
            })  
  1. 非父子组件通信

    • 使用ref来绑定组件, (注意:ref也可以绑定DOM元素) 【ref链】
      -1. 在父组件的模板中, 使用ref = refName 绑定在两个兄弟组件身上
      -2. 在任意一个子组件中, 就可以通过 this. p a r e n t . parent. parent.refs.refName 就可以获得另一个子组件了, 同时这个自组件身上的数据和方法同样也得到了
      -3. 案例:
        	<!--html代码--!>
        	<div id="app">
        <Father></Father>
      </div>
      
      <template id="father">
        <div>
          <h3> 我是父亲 </h3>
          <hr>
          <Boy ref = "boy" ></Boy>
          <hr>
          <Girl ref = "girl" ></Girl>
      
          <div ref = 'hello'>
            你好
          </div>
        </div>
      </template>
      
      <template id="boy">
          <div>
      
            <h3> I am boy </h3>
            <p> 我现在有:{{ cash }} 钱 </p>
          </div>
      </template>
      
      <template id="girl">
        <div>
      
          <h3> I am girl </h3>
          <button @click = 'give'> 给body 1000块 </button>
        </div>
      </template>
      
        //JS代码
        	<script>
      Vue.component('Father',{
        template: '#father',
        data () {
          return {
            name: 'father'
          }
        }
      })
      Vue.component('Boy',{
        template: '#boy',
        data () {
          return {
            cash: 2000
          }
        },
        methods: {
          incrementCash (value) {
            this.cash += value
          }
        }
      })
      Vue.component('Girl',{
        template: '#girl',
        data () {
          return {
            money: 1000
          }
        },
        methods: {
          give(){
            console.log('====================================');
            console.log(this.$parent);
            console.log('====================================');
            // console.log( this.$parent.$refs ) // { body: Vuecomponent,girl: VueComponent }
            this.$parent.$refs.boy.incrementCash( this.money )
      
            // this.$parent.$children
          }
        }
      })
      new Vue({
        el: '#app'
      })
      
    ``` - 通过事件总线(bus) -1. 它是通过事件的发布(声明), 以及事件的订阅(触发)来做的 -2. 首先在js中 创建一个bus对象(vm) ```javascript var bus = new Vue() ``` - 3. 在Count组件中定义数据, 和修改数据的方法 - 4. 在Count组件中 通过 created 钩子 , 进行bus事件的发布 ```javascript created: { bus.$on('add',this.addCount) } ``` - 5. 在MyButton组件的方法中通过 bus进行事件的订阅 ```javascript increment () { bus.$emit( 'add' ) } ```
    -6  案例:
    
      <div id="app">
          <my-button></my-button>
          <Count></Count>
        </div>
        <template id="button">
          <button @click = "increment"> increment </button>
        </template>
        <template id="count">
          <div>
            {{ count }}
          </div>
        </template>
        ```
      ```javascript
      		//JS代码
      		<script>
      		
      		  var bus = new Vue()
      		
      		  Vue.component('MyButton',{
      		    template: '#button',
      		    methods: {
      		      increment () {
      		        bus.$emit('add')
      		      }
      		    }
      		  })
      		  Vue.component('Count',{
      		    template: '#count',
      		    data () {
      		      return {
      		        count: 0
      		      }
      		    },
      		    methods: {
      		      addCount(){
      		        this.count ++
      		      }
      		    },
      		    created () { //created表示组件在创建结束之后就会自动触发的一个方法
      		      //表示组件的装载结束(template模板的装载)
      		     bus.$on('add',this.addCount)
      		
      		    }
      		  })
      		  new Vue({
      		    el: '#app'
      		  })
      		</script>
    
    
  2. 多组件状态共享

    • 使用 Vue-Router
    • 使用状态管理工具 Vuex
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值