Vue组件之间传值

要点

一、父组件给子组件传值–数据

  1. 父组件调用子组件的时候,给子组件绑定一个动态属性(:xx=yy),属性值yy来自父组件
  2. 在子组件内, 用props对象(与data,methods同级),接收父组件传来的属性 [“xx”]

二、父组件主动获取子组件的数据和方法

  1. 父组件调用子组件的时候,给子组件一个属性,ref=“xxx”
  2. 在父组件里通过:this.$refs.xxx.数据–获取数据,this.$refs.xxx.方法–调用方法

三、子组件主动获取父组件的数据和方法

在子组件里通过:this.$parent.数据–获取数据,this.$parent.方法 --调用方法

四、非父子组件(兄弟组件)传值

  1. 新建一个js文件,引入Vue,实例化Vue,暴露这个实例
  2. 在要广播的地方引入刚才的定义的实例
  3. 通过–实例名.$emit('广播名称',数据)—进行广播
  4. 在要接收数据的地方监听广播----通过–实例名.$on('广播名称',function(){})

五、爷组件给孙组件传值

$attrs:包含了所以父组件在孙组件上设置的属性
$listeners:包含了作用在这个组件上所有的监听器(监听事件),可以通过 v-on=" $listeners"将事件监听指向这个组件内的子元素(包括内部的子组件)。

(1).通过属性传递(爷->孙)
1.在爷爷组件中,给父组件绑定一个属性:xx=“1”,
2.给父组件用 子组件用v-bind="$attrs" 获取爷爷组件的传给父组件的属性
3.在子组件中,通过this.$attrs.xx 获取爷爷组件传给父组件的值

(2).通过事件传递(孙->爷)

  1. 在子组件中,自定义事件 并传值 this.$emit("自定义事件名",20)
  2. 给父组件,给子组件设置 v-on="$listeners"
  3. 在爷爷组件中,通过@自定义事件名的方式触发爷爷组件自己的方法,监听算组件传来的数据

父组件组件在其中传递props以及事件的过程中,不必在写多余的代码,仅仅是将$attrs以及$listeners向上或者向下传递即可。

父组件向子组件传值

  • 父组件发送的形式是以属性的形式绑定值到子组件身上。
  • 然后子组件用属性props接收
  • 子组件的mounted函数先于父组件的mounted函数调用
    若:
    1.父组件在mounted函数中将原data定义的arr:[ ],新赋值为arr:[1,2,3],
    2.父组件给子组件传值,子组件获得arr
    3.子组件在mounted函数中打印arr,打印的结果为[ ]空
    原因:子组件的mounted函数先于父组件的mounted函数调用,因为子组件调用mounted时,父组件还没有调用mounted,此时arr:[ ]。
    等到父组件调用mounted后,才会有arr:[1,2,3]

父组件:

<template>
   <div id="app">
        <div>{{pmsg}}</div>
        <menuitem title='来自父组件的值'></menuitem> 
        <menuitemq :title='ptitle' content='hello'></menuitemq>
      </div>
</template>

<script>
import menuitemq from '@/components/menuitemq'
export default {
//   name: '',
  data () {
    return {
      pmsg: '父组件中内容',
      ptitle: '动态绑定属性'
    };
  },
  
  components: {
      menuitemq
  },
  mounted () {},
  methods: {}
}
</script>

<style lang='stylus' scoped>
</style>

子组件:

<template>
  <div>{{msg + "----" + title + "-----" + content}}</div>
</template>

<script>
export default {

  // 3、 子组件用属性props接收父组件传递过来的数据,注册属性
props: ['title', 'content'],
data() {
    return {
        msg: '子组件本身的数据'
    }
},
  components: {},
  mounted () {},
  methods: {}
}
</script>

<style lang='stylus' scoped>
</style>


     
    
   

子组件向父组件传值

  • 子组件用$emit()触发事件
  • $emit() 第一个参数为 自定义的事件名称 第二个参数为需要传递的数据
  • 父组件用v-on 监听子组件的事件

父组件:

<template>
    <div id="app">
        <div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
         <!-- 2 父组件用v-on 监听子组件的事件
    		这里 enlarge-text  是从 $emit 中的第一个参数对应   handle 为对应的事件处理函数	
    	-->	
        <menuitemq :parr='parr' @enlargetext='handle'></menuitemq>
      </div>
</template>

<script>
import menuitemq from '@/components/menuitemq'
export default {
//   name: '',
  data () {
    return {
      pmsg: '父组件中内容',
            parr: ['apple','orange','banana'],
            fontSize: 10
    };
  },
  
  components: {
      menuitemq
  },
  mounted () {},
  methods: {
      handle: function(val){
              // 扩大字体大小
              this.fontSize += val;
            }
  }
}
</script>

<style lang='stylus' scoped>
</style>
子组件:
<template>
<div>
  <ul>
    <li :key="index" v-for="(item,index) in parr" >{{item}}</li>
    </ul>
    <button @click="fn">扩大父组件中字体大小</button>
    <button @click="fm">扩大父组件中字体大小</button>
  </div>
</template>

<script>
export default {
  name: "",
  data() {
    return {};
  },
  props: ["parr"],
  components: {},
  mounted() {},
  methods: {
    fn(){
      this.$emit("enlargetext",5)
    },
    fm(){
      this.$emit("enlargetext",10)
    }
  }
};
</script>

<style lang='stylus' scoped></style>

兄弟之间的传递

  • 兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
  • 提供事件中心 var hub = new Vue()
  • 传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
  • 接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
  • 销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据

兄弟a----testa.vue

  <template>
  <div>
    <div>a:{{num}}</div>
    <div>
      <button @click='handle'>点击</button>
    </div>
  </div>
</template>

<script>
import Bus from '@/bus.js'
export default {
  name: "",
  data() {
    return {
       num: 0
    };
  },
  props: [],
  components: {},
  mounted() {
     // 3、接收数据方,通过mounted(){} 钩子中  触发hub.$on(方法名
    Bus.$on('a-event', (val) => {
      this.num += val;
    });
  },
  methods: {
    handle(){
      //2、传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)   触发兄弟组件的事件
      Bus.$emit('b-event', 2);
      // console.log("to")
      console.log(this)
    }

  }
};
</script>

<style lang='stylus' scoped></style>

    

兄弟b----testb.vue

<template>
   <div>
       <div>b:{{num}}</div>
       <div>
           <button @click='handle'>点击</button>
        </div>
    </div>
</template>

<script>
import Bus from '@/bus.js'
export default {
  name: '',
  data () {
    return {
       num: 0
      
    };
  },
  props:[],
  components: {},
  mounted () {
    // console.log(this)
       // 3、接收数据方,通过mounted(){} 钩子中  触发hub.$on()方法名
    Bus.$on('b-event', (val) => {
    

        console.log(val)
        this.num += val;
        console.log(this.num)

    });
  },
  methods: {
     
      handle(){
        //2、传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)   触发兄弟组件的事件
        Bus.$emit('a-event', 1);
        }
  }
}
</script>

<style lang='stylus' scoped>
</style>

父组件–father.vue

<template>
<div id="app">
  <div>父组件</div>
  <div>
    <button @click='handle'>销毁事件</button>
    </div>
    <testa></testa>
    <testb></testb>
    
    </div>
</template>

<script>
import testa from '@/components/testa'
import testb from '@/components/testb'
import Bus from '@/bus.js'
export default {
//   name: '',
  data () {
    return {
    
    };
  },
  
  components: {
      testa,
      testb
  },
  mounted () {},
  methods: {
      handle:()=>{
        //4、销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据  
        Bus.$off('a-event');
        Bus.$off('b-event');
            }
  }
}
</script>

<style lang='stylus' scoped>
</style>

总线—Bus.js

import Vue from 'vue'
var Bus = new Vue();
export default Bus;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值