父子组件之间通信的方式
- 父组件传递给子组件:通过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") }真实开发中,最好添加监听之后也移除监听,但是不移除一般也没有问题
