Skip to content

父子组件之间通信的方式

  • 父组件传递给子组件:通过props属性
  • 子组件传递给父组件:通过$emit触发事件

父组件传递给子组件

  • 可以通过props来完成组件之间的通信
  • 什么是Props?
    • Props是你可以在组件上注册一些自定义的attribute
    • 父组件给这些attribute复制,子组件通过attribute的名称获取到对应的值

Props

props的数组语法

  • 弊端:
    • 不能对类型进行验证
    • 没有默认值

父组件

javascript
<script>
  import myComponents from './components/myComponents.vue';

  export default {
    components: {
      myConponents
    }
  }
</script>

<template>
  <my-components name="Terrisa" age="19"></my-components>
</template>

子组件

javascript
<template>
    <h2>Hello! How are you? This is my component!</h2>
    <h2>name: {{ name }}</h2>
    <h2>age: {{ age }}</h2>
</template>

<script>
    export default {
        props: ['name', 'age']
    }
</script>

props的对象语法

  • type——规定类型
  • default——规定默认值
  • required——是否必须传入

例子:

javascript
<script>
    export default {
        // props: ['name', 'age']
        props: {
            name: {
                type: String,
                default: 'Aihara Kotoko',
                required: true,
            },
            age: {
                type: Number,
                default: 19
            }
        }
    }
</script>
  • 如果是对象类型,必须是一个函数返回的对象
javascript
            friend: {
                type: Object,
                default() {
                    return {
                        name: 'Jerram'
                    }
                }
            }

非Prop的Attribute

  • 当我们传递给一个组件某个属性时,但是该属性并没有定义对应的props或者emits时,就称之为非Prop的Attribute

  • 常见的包括class、style、id属性等

  • Attribute继承:

    • 当组件有单个根节点时,非Prop的Attribute将自动添加到根节点的Attribute中
    • 也可以通过在子组件option api中添加inheritAttrs: false禁用
    • 在没有对应的prop时像拿到数据可以这样做:
    javascript
    <h2 :class="$attrs.name">姓名: {{ name }}</h2>

子组件传递给父组件

  • 首先,我们需要在子组件中定义好在某些情况下触发的事件名称
  • 其次,在父组件中以v-on的方式传入要监听的事件名称,并且绑定到对应的方法中
  • 最后,在子组件中发生某个事件的时候,根据事件名称触发对应的事件

this.$emit

  • 让子组件发出去一个自定义事件
  • 第一个参数自定义事件名称
  • 第二个参数是传递的参数

例子:

子组件

vue
    <button @click="yearPass(1)">1 year later</button>
javascript
        methods: {
            yearPass(years) {
                this.$emit("yearPass", years)
            }
        }
javascript
        emits: ["yearPass"] //起到一个注册说明的作用,可以不要

父组件

vue
  <my-components @yearPass="grow"></my-components>
javascript
    methods: {
      grow(years) {
        this.age += years
      }
    }

非父子组件之间通信

Provide/Inject(在实际开发中用的非常非常少)

  • Provide/Inject用于非父子组件之间共享数据:

  • 无论层级结构有多深,父组件都可以作为其所有子组件的依赖提供者

  • 父组件有一个provide选项来提供数据

  • 子组件有一个inject选项来开始使用这些数据

  • 父组件不需要知道哪些子组件使用它provide的property

  • 子组件不需要知道inject的property来自哪里

  • 这不是响应式的,要变成响应式可以在provide中使用computed

  • 注意:因为computed返回的是一个ref对象,需要取出其中的value来使用

用的很少,因为一般都是在状态管理库里面来进行的

也可以通过事件总线来实现

  • 可以额外下载别人封装好的包

  • created() { eventBus.emit("name") }

  • created() { eventBus.on("name", () => {}) }

  • unmounted() { eventBus.off("name") }

  • 真实开发中,最好添加监听之后也移除监听,但是不移除一般也没有问题