props / $emit
最经典&使用最多的通信方式,父组件通过props的方式向子组件传递数据,子组件通过$emit向父组件通信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| // 父组件 <template> <div id="app"> <HelloWorld :msg='msg' @onChangeFatherMsg='onChangeFatherMsg' /> </div> </template>
<script> import HelloWorld from "./components/HelloWorld.vue"; export default { name: "App", data() { return { msg: "Welcome to Your Vue.js App", }; }, components: { HelloWorld, }, methods: { onChangeFatherMsg(e) { this.msg = e; }, }, }; </script>
// 子组件 <template> <div class="hello"> <h1 @click="changeFatherMsg">{{ msg }}</h1> </div> </template>
<script> export default { name: "HelloWorld", props: { msg: String, }, methods: { changeFatherMsg() { this.$emit("onChangeFatherMsg", "hello world"); }, }, }; </script>
|
$children / $parent(vue 3.x已移除)
要注意边界情况,如在#app上拿$parent得到的是new Vue()的实例,在这实例上再拿$parent得到的是undefined,而在最底层的子组件拿$children是个空数组。也要注意得到$parent和$children的值不一样,$children 的值是数组,而$parent是个对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| // 父组件 <template> <div id="app"> <button @click="changeChildren">改变子组件值</button> <HelloWorld /> </div> </template>
<script> import HelloWorld from "./components/HelloWorld.vue";
export default { name: "App", data() { return { fatherMsg: "hello", }; }, components: { HelloWorld, }, methods: { changeChildren() { this.$children[0].privateMsg = "嘿嘿嘿"; }, }, }; </script>
// 子组件 <template> <div class="hello"> <h1>{{ privateMsg }}</h1> </div> </template>
<script> export default { name: "HelloWorld", data() { return { privateMsg: "子组件", }; }, mounted() { console.log(this.$parent.fatherMsg); }, }; </script>
|
provide/ inject
provide 和 inject 主要在开发高阶插件/组件库时使用。并不推荐用于普通应用程序代码中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| // 父组件 <template> <div id="app"> <HelloWorld /> </div> </template>
<script> import HelloWorld from "./components/HelloWorld.vue";
export default { name: "App", provide: { for: "子组件", }, components: { HelloWorld, }, }; </script>
// 子组件 <template> <div class="hello"> <h1>{{ privateMsg }}</h1> </div> </template>
<script> export default { name: "HelloWorld", inject: ["for"], data() { return { privateMsg: this.for, }; } }; </script>
|
$refs
ref如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| // 父组件 <template> <div id="app"> <HelloWorld ref="helloworld"/> </div> </template>
<script> import HelloWorld from "./components/HelloWorld.vue";
export default { name: "App", components: { HelloWorld, }, mounted(){ console.log(this.$refs.helloworld.privateMsg) } }; </script>
// 子组件同上
|
eventBus
EventBus是消息传递的一种方式,基于一个消息中心,订阅和发布消息的模式,称为发布订阅者模式。(eventBus原理)
on(‘name’, fn)订阅消息,name:订阅的消息名称, fn: 订阅的消息
emit(‘name’, args)发布消息, name:发布的消息名称 , args:发布的消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import Vue from 'vue' export const EventBus = new Vue();
<template> <div class="hello"> <h1 @click="componentAEvent">{{ num }}</h1> </div> </template>
<script> import { EventBus } from "../exentBus"; export default { name: "HelloWorld", data() { return { num: 1, }; }, methods: { componentAEvent() { EventBus.$emit("add", { num: this.num++, }); }, }, }; </script>
<template> <div class="hello"> <h1>{{ count }}</h1> </div> </template>
<script> import { EventBus } from "../exentBus";
export default { name: "HelloWorld", data() { return { count: 0, }; }, mounted() { EventBus.$on("add", (params) => { this.count = params.num; }); }, }; </script>
|
$attrs与 $listeners(vue 3.x 移除了$listeners)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| // 父组件 <template> <div id="app"> <HelloWorld name='name' age='18' gender='男' /> </div> </template>
<script> import HelloWorld from "./components/HelloWorld.vue";
export default { name: "App", components: { HelloWorld, }, }; </script>
// 子组件 <template> <div class="hello"> <h1>{{ num }}</h1> </div> </template>
<script> export default { name: "HelloWorld", data() { return { num: 1, }; }, inheritAttrs: false, {age: "18", gender: "男"} props: { name, }, mounted() { console.log(this.$attrs); // inheritAttrs为true时的输出 {name: "name", age: "18", gender: "男"} }, }; </script>
|