Vue之组件传值

父子间通信(props/$emit)

1.父组件向子组件传值

父组件通过绑定属性的方式向子组件传值,子组件通过props来接收。
父组件:

<template>
  <div id="app">
    <Child :msg="msg"/>
  </div>
</template>

<script>
import Child from './components/Child.vue'

// 父组件通过绑定自定义属性来给子组件传值
export default {
  name: 'App',
  components: {
    Child
  },
  data() {
    return {
      msg: 'hi, my child!'
    }
  }
}
</script>

子组件:

<template>
  <div>
      <div>子组件接收到父组件的信息:{{msg}}</div>
  </div>
</template>

<script>
export default {
    // 子组件通过props来接收父组件传递过来的值,props有以下两种写法:
    // props: ['msg'],
    props: {
        msg: {
            type: String,
            defalut: ''
        }
    }

}
</script>
2.子组件向父组件传值

子组件绑定一个事件,通过this.$emit()来触发;父组件通过v-on来监听事件
子组件:

<template>
  <div>
      <button @click="toFather">点击发送信息给父组件</button>
  </div>
</template>

<script>
export default {
    data() {
        return {
            sonMsg: 'hello, father!'
        }
    },
    methods: {
        // 子组件绑定一个事件,通过this.$emit()来触发
        toFather() {
            this.$emit('toFather', this.sonMsg)
        }
    }

}
</script>

父组件:

<template>
  <div id="app">
    <Child @toFather="fatherHandle"/>
    <p>父组件接收到子组件传递过来的信息: {{sonMsg}}</p>
  </div>
</template>

<script>
import Child from './components/Child.vue'

// 父组件通过v-on监听事件
export default {
  name: 'App',
  components: {
    Child
  },
  data() {
    return {
      sonMsg: ''
    }
  },
  methods: {
    fatherHandle(msg) {
      // 子组件传递过来的值
      this.sonMsg = msg
    }
  }
}
</script>

兄弟组件间通信

事件总线($emit/$on)
  1. 创建事件中心管理组件组件的通信EventBus.js:一个空的Vue实例,用来传递和接收事件。
import Vue from 'vue'
export default new Vue()
  1. 发送的组件
    在要传值的组件导入这个事件中心,绑定事件并通EventBus.$emit()来触发
<template>
  <div>
      <button @click="add">1</button>
  </div>
</template>

<script>
// 发送组件导入事件中心,绑定事件并通过$emit()来触发事件
import EventBus from './EventBus'
export default {
    data() {
        return {
            count: 0
        }
    },
    methods: {
        add() {
            this.count++
            EventBus.$emit('add', this.count)
        }
    }
}
</script>
  1. 接受的组件
    在接受的组件中导入这个事件中心,通过EventBus.$on()来监听回调
<template>
  <div>
      <div>num: {{num}}</div>
  </div>
</template>

<script>
// 在接受组件导入事件中心,通过$on()来监听回调
import EventBus from './EventBus'
export default {
    data() {
        return {
            num: 0
        }
    },
    created() {
        EventBus.$on('add', count => {
            this.num = count
        })
    }
}
</script>

跨组件间通信

依赖注入(provide/inject)

Vue的依赖注入可以实现很深层次的通信。provide和inject是Vue提供的两个钩子,和data、methods同级。

  • provide钩子用来发送数据或方法;
  • inject钩子用来接受数据和方法。
    注意: 依赖注入所提供的属性是非响应式的
    祖先组件:
<template>
  <div id="app">
    <Child/>
  </div>
</template>

<script>
import Child from './components/Child.vue'

export default {
  name: 'App',
  // provide钩子用来发送数据或方法
  provide() {
    return {
      // Fname: 'father datas'
      app: this,
    }
  },
  components: {
    Child,
  },
  data() {
    return {
      msg: 'hi, my child!',
    }
  },
}
</script>

后代组件:

<template>
  <div>
      <!-- <div>Fname:{{Fname}}</div> -->
      <div>{{app.msg}}</div>
  </div>
</template>

<script>
export default {
    // inject钩子用来接收数据或方法
    // inject: ['Fname'],
    inject: ['app'],

}
</script>

ref/$refs

ref属性用在子组件上, 它的引用就指向了子组件的实例。可以通过实例来访问组件的数据和方法。
子组件:

<template>
  <div></div>
</template>

<script>
export default {
    data() {
        return {
            name: 'ref of children'
        }
    },
    methods: {
        sayHi() {
            console.log('hi, father!')
        }
    }
}
</script>

父组件:

<template>
  <div id="app">
    <div>refName: {{refName}}</div>
    <Ref ref="childRef"/>
  </div>
</template>

<script>
import Ref from './components/Ref.vue'
export default {
  name: 'App',
  components: {
    Ref,
  },
  data() {
    return {
      refName: ''
    }
  },
  mounted() {
    // 通过Vue实例来访问组件的数据和方法
    this.refName = this.$refs.childRef.name,
    this.$refs.childRef.sayHi()
  },
}
</script>

$parent/$children

  • 使用$parent可以让组件访问父级的实例(是上一级的父级),值是一个对象
  • 使用$children可以让组件拿到所有子组件的实例,它的值是一个无序的数组,且访问的数据也不是响应式的
    子组件:
<template>
  <div>
  </div>
</template>

<script>
export default {
    data() {
        return {
            sonMsg: 'hello, father!'
        }
    },
    mounted() {
        // this.$parent可以访问上一级的实例,值为一个对象
        console.log(this.$parent.msg); // hi, my child!
    },

}
</script>

父组件:

<template>
  <div id="app">
    <Child/>
    </div>
  </div>
</template>

<script>
import Child from './components/Child.vue'

export default {
  name: 'App',
  components: {
    Child,
  },
  data() {
    return {
      msg: 'hi, my child!',
    }
  },
  mounted() {
    // this.$chiildren拿到所有的子组件实例,值为一个无序的数组
    console.log(this.$children);
  },
}
</script>

$attrs/$listeners

$attrs/$listeners实现组件的跨代通信

  • inheritAttrs,它默认是true,继承所有父组件除了props之外的所有属性值;设置为false,就只继承class属性。
  • $attrs:包含了父组件除了props绑定之外的属性(calss和style也除外),作用于子组件,通过v-bind="$attrs"传入组件内;
  • $listeners: 包含了父组件中的v-on监听器(除了.native修饰的),作用与子组件,通过v-on="$listeners"传入组件内
    祖父组件:
<template>
  <div id="app">
    <AttrsChild :msg="msg" msg2="grandSon接收的信息" :obj="obj" @parentHadel="grandParentHandel"/>
  </div>
</template>

<script>
import AttrsChild from './components/attrsChild.vue'

export default {
  name: 'App',
  components: {
    AttrsChild
  },
  data() {
    return {
      msg: 'I am props datas',
      obj: {
        name: 'limi',
        age: 25,
      }
    }
  },
  mounted() {
    
  },
  methods: {
    grandParentHandel() {
      console.log('我是祖父事件');
    }
  }
}
</script>

<style>
</style>

父组件:

<template>
  <div>
      <Son v-bind="$attrs" v-on="$listeners"/>
  </div>
</template>

<script>
import Son from './atrrsSon.vue'
// $attrs:包含所有父级除了props绑定的属性,
// $listeners: 包含所有父级除了.native修饰的v-on事件监听
export default {
    components: {
        Son
    },
    props: ['msg'],
    // inheritAttrs: false, // 只继承class
    created() {
        this.$emit('parentHadel') // 我是祖父事件
        console.log(this.msg, '----msg'); // I am props datas ----msg
        console.log(this.$attrs,'----this.$attrs'); // obj: { name: 'limi', age: 25 }
    }

}
</script>

<style>

</style>

孙子组件:

<template>
  <div>
  </div>
</template>

<script>
export default {
    props: ['msg2'],
    inheritAttrs: false, // 只继承class
    created() {
        this.$emit('parentHadel') // 我是祖父事件
        console.log(this.msg2, '---msg2'); // grandSon接收的信息 ---msg2
        console.log(this.$attrs,'----this.$attrs'); // obj: { name: 'limi', age: 25 }
    }

}
</script>

<style>

</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值