vue组件传值的几种方式

一、父子间传值

1.props / $emit

⼦组件中通过定义props接收⽗组件中通过v-bind绑定的数据
⽗组件中通过监听⼦组件中$emit的⾃定义事件接收数据

2.$parent / children

⼦组件中通过this. p a r e n t 这 个 对 象 获 取 ⽗ 组 件 中 的 数 据 ⽗ 组 件 中 通 过 t h i s . parent这个对象获取⽗组件中的数据 ⽗组件中通过this. parentthis.children这个数组获取⼦组件中的数据

3.$ref

⽗组件中定义⼦组件中的ref属性后,通过this.$refs.定义的属性名获取⼦组件数据
第3集 vue中组件间传值常⽤的⼏种⽅式(下)

实例
Parents.vue

<template>
  <div class="parent">
    <div>this is a parent page</div>
    <h3>{{msg}}</h3>
    <Child v-bind:msg="'from parent'" @showMsg="showMsg1" ref="child"></Child>
    <!-- @showMsg="showMsg1"监听事件 -->
  </div>
</template>

<script>
import Child from '@/views/Child.vue'


export default {
  data(){
    return{
      msg:''
    }
  
  },
  components: {
    Child
  },
  methods:{
    showMsg1(val){
      this.msg=val
    }
  },
  mounted () {
    console.log(this.$children[0].childMsg);
    console.log('ref',this.$refs.child)
  },
}
</script>



Child.vue

<template>
  <div class="child">
    <h1>This is a child page</h1>
    <h2>{{msg}}</h2>
    <button @click="passtoParent">子向父传值</button>
  </div>
</template>

<script>
  export default {
    //父向子传值
    props:{
      msg:{
        type:String,
        default:''
      }
    },
    data() {
      return {
        childMsg: 'childMsg'
      }
    },
    methods:{
      passtoParent(){
        this.$emit('showMsg','this is from child')
      }
    }
  }
</script>

<style lang="css" scoped>
  .child{
     background-color:red;
  }
      
</style>

二、⾮⽗⼦间传值

1.事件总线

// 原理上就是建⽴⼀个公共的js⽂件,专⻔⽤来传递消息
// bus.js
import Vue from 'vue'
export default new Vue;
// 在需要传递消息的地⽅引⼊
import bus from './bus.js'
// 传递消息
bus.$emit('msg', val)
// 接受消息
bus.$emit('msg', val => {
 console.log(val)
})

App.vue

<template>
  <div id="app">
    <button @click="passMsg">非父子传值App->Child</button>
    
    <router-view/>
  </div>
</template>
<script>
import bus from './util/bus'
  export default {
    methods: {
      passMsg() {
        bus.$emit('msg','this is from App')      
      }
    },  
  }
</script>

Child.vue

<template>
  <div class="child">
    <h2>This is a child page</h2>
    <h3>{{msg}}</h3>
    <h4>{{childMsg}}</h4>
    <button @click="passtoParent">子向父传值</button>
  </div>
</template>
<script>
import bus from '../util/bus'
  export default {
    //父向子传值
    props:{
      msg:{
        type:String,
        default:''
      }
    },
    data() {
      return {
        childMsg: 'childMsg'
      }
    },
    methods:{
      passtoParent(){
        this.$emit('showMsg','this is from child')
      }
    },
    mounted () {
      // bus.$on监听
      bus.$on('msg',(val)=>{
        this.childMsg=val
      });
    },
  }
</script>
<style lang="css" scoped>
  .child{
     background-color:red;
  }     
</style>

2.$attrs / $listeners

// 解决多级组件间传值的问题
// $attr 将⽗组件中不包含props的属性传⼊⼦组件,通常配合 interitAttrs 选项
⼀起使⽤。
// 如果不想在dom上出现属性,可设置interitAttrs: false
// $listeners监听⼦组件中数据变化,传递给⽗组件

实例
App.vue

<template>
  <div id="app">
    <button @click="passMsg">非父子传值App->Child</button>
    <Parent :msg='a' :msg2='b' :msg3='c'></Parent>//改动
    <router-view/>
  </div>
</template>


<script>
import bus from './util/bus'
import Parent from './views/Parent'
  export default {
  //改动
    data() {
      return {
        a: 'msga',
        b: 'msgb',
        c: 'msgc',

      }
    },
    components:{
      Parent
    },
    methods: {
      passMsg() {
        bus.$emit('msg','this is from App')
        
      }
    },
    
  }
</script>

Child.vue

<template>
  <div class="child">
    <h2>This is a child page</h2>
    <h3>{{msg}}</h3>
    <h4>{{childMsg}}</h4>
    <button @click="passtoParent">子向父传值</button>
  </div>
</template>

<script>
import bus from '../util/bus'
  export default {
    //父向子传值
    props:{
      msg:{
        type:String,
        default:''
      }
    },
    data() {
      return {
        childMsg: 'childMsg'
      }
    },
    methods:{
      passtoParent(){
        this.$emit('showMsg','this is from child')
      }
    },
    mounted () {
      //改动
      console.log('attrs',this.$attrs),
      // bus.$on监听
      bus.$on('msg',(val)=>{
        this.childMsg=val
      });
    },
  }
</script>

<style lang="css" scoped>
  .child{
     background-color:red;
  }
      
</style>

Parent.vue

<template>
  <div class="parent">
    <div>this is a parent page</div>
    <h1>{{msg}}</h1>
    <!-- 改动-->
    <Child v-bind:msg="'from parent'" @showMsg="showMsg1" ref="child" v-bind="$attrs"></Child>
    <!-- @showMsg="showMsg1"监听事件 -->
  </div>
</template>

<script>
import Child from './Child'


export default {
  data(){
    return{
      msg:''
    }
  
  },
  components: {
    Child
  },
  methods:{
    showMsg1(val){
      this.msg=val
    }
  },
  mounted () {
    console.log(this.$children[0].childMsg);
    console.log('ref',this.$refs.child)
  },
}
</script>



3.vuex

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值