欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

组件通信

程序员文章站 2022-06-06 23:38:33
...

组件通信:

值得强调一点的是 无论组件通信结果如何,Vue都是单向数据流(组件之间的数据通信)。

1.父子通信:

绑定的是简单数据:
1.父组件中定义数据,通过单向数据绑定的形式,将数据绑定在子组件上,属性是自定义属性

2.子组件通过配置项中的props接受数据,props可以是一个数组,数组中放的是自定义属性名称

3.那么这个自定义属性可以向data中的数据一样直接在子组件的模板中使用。

4.父组件中的数据一旦发生改变,子组件中的数据也会跟着改变

举个栗子:
<div id="app">
  <father></father>
</div>
<template id="father">
   <div class="father-box">
        <h3>父组件</h3>
        <son v-bind:money = "money"></son>
        <son :money = "money"></son>
   </div>
</template>
<template id="son">
    <div class="son-box">
        <h3>子组件</h3>
        <p> {{ money }} </p>
    </div>
</template>
<script>
   Vue.component('father', {
      template : "#father",
      data (){
        return {
          money : 100
        }
      }
   })
   Vue.component('son', {
       template : "#son",
       props : [money]
   })
   new Vue({
      el: "#app",
   })
</script>

子父通信:

效果上间接使用的父组件的东西。
绑定复杂数据类型:

1.父组件中的数据是一个复杂数据类型,那么父组件绑定数据的时候,给子组件一个地址。
2.子组件可以通过这个地址来修改这个数据。
3.在效果上,子组件和父组件建立了通信,违背了单向数据流。
多说无益:
 <div class="app">
		<father></father>
 </div>
 <template id="father">
    <div class="father-box">
      <p>父组件 {{ setmoney.money }}</p>
      <son v-bind:setmoney="setmoney"></son>
    </div>
 </template>
 <template id="son">
     <div class="son-box">
       <input type ="text" v-model = "setmoney.money"/>
       <p>子组件 {{ setmoney.money }}</p>
     </div>
 </template>
 <script>
   Vue.component('father', {
      template : '#father',
      data () {
          return {
            getmoney : {
               money : 100
            }
          }
      }
   })
   Vue.component('son', {
      template : '#son',
      props : [setmoney]
   })
   new Vue({
      el : '.app'
   })
 </script>
除了这种传递对象的方式,父组件还可以传递一个方法给子组件.
1.父组件定义方法,然后将这个方法通过单向数据绑定的形式传递给子组件
2.子组件通过props属性接受,然后通过@click="方法名"
举例:
<div class="app">
		<father></father>
</div>
<template id="father">
	   <div>
	   	<h3>father</h3>
	   	<p> {{ money }} </p>
	   	<son :getmoney="getmoney"></son>
	   </div>
</template>
<template id="son">
	   <div>
	   	<h3>son</h3>
	   	<button @click="getmoney(100)">添加</button>
	   </div>
</template>
<script>
    Vue.component('father', {
    	template : '#father',
    	data () {
    		return {
    			money : 0
    		}
    	},
    	methods : {
    		getmoney (value){
    			this.money += value
    		}
    	}
    })
    Vue.component('son', {
    	template : '#son',
    	props : ['getmoney']
    })
	new Vue ({
		el : '.app'
	})
</script>
同自定义事件来实现通信:
--父组件上定义数据 和方法
--在子组件上绑定自定义事件
--子组件定义方法,在这个方法中通过 this.$emit(eventtype,实际参数)来调用
自定义事件的处理程序
 <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>
<script>
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'
     })  
</script>

非父子通信:

1.ref:

使用ref来绑定组件(ref也可以绑定DOM元素)
---在父级的模板中,使用ref = refName绑定在两个兄弟组件上。
---在任意一个子组件中,就可以通过this.$parent.$refs.refName就可以获取另一个组件,
同时这个组件上的数据和方法都可以获取到。
<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>
<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'
  })
</script>

2.通过事件总线bus

他是通过事件的发布(声明),以及事件的订阅(触发)来实行的。
首先创建一个bus对象:
 ---- var bus = new Vue()
 --在content组件中定义数据,和修改数据的方法
 --在content组件中通过created钩子,进行bus事件的发布
 ----created : {
       bus.$on('add', this.addcontent);
     }
--- 在MyButton组件的方法中通过bus进行事件的订阅
----iincrement() {
     bus.$emit( 'add' );
}
<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>
  <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>

组件生命周期:

钩子函数,就是options中的key,他的值是函数。
钩子函数写在其他函数的后面。
1.组件有哪几个阶段:
   初始阶段
   运行中阶段。
   销毁阶段
2.初始化阶段:

1.分为两个阶段:
   每个阶段包含两个生命周期钩子函数:
   钩子函数:
   1.beforeCreate:
     表示组件创建前的准备工作,为事件的发布订阅和生命周期做初始化。
     在这个钩子函数中:
        数据拿不到,真实DOM也拿不到。
     这个钩子函数在项目中没有什么实际用途。
   2.created :
     表示组件创建结束。
     这个钩子函数中:
       数据能够拿到,但真实DOM无拿到。
     这个钩子函数在项目中:
       数据请求,然后可以进行一次默认的数据修改。
   3.beforeMounte:
     表示组件装在前的准备操作
        判断el选项有没有,判断template有没有,如果没有需要手动装载。
        如果有,那么利用render函数进行模板的渲染。
     这个钩子函数中:
        数据拿到了,但真实DOM没有拿到。
     这个钩子函数在项目中:
        数据请求,可以进行一次数据的修改。
   4.mounted :
   表示组件装载结束,可以在视图中看到。
   这个钩子函数:
      数据能够拿到,真实DOM也能拿到。
   这个钩子函数在项目中:
      DOM操作可以进行,第三方库的实例化。
 总结:
 由上对比,我们可以知道,数据请求越提前越好,所以created常用于数据的请求和数据的修改,第三方库的实例化常在mounted中进行。

注意:

添加组件时,标签经常与h5中的标签同名,所以在使用组件时,请于前面添加个特殊字符(如你名字的缩写)