父子组件通信
prop
最常用父子组件通信方式,父组件向子组件传递参数,子组件声明prop进行接收,若存在父组件传递给子组件的参数中有未声明prop的,则会将其放置在子组件的$attrs中
子组件Counter
<template>
</template>
<script>
export default {
props: ["num1", "num2"],
created() {
console.log(this.num1) // 1
console.log(this.num2) // 2
console.log(this.$attrs) // { num3: 3 }
}
}
</script>
父组件
<template>
<Counter :num1="1" :num2="2" :num3="3"/>
</template>
<script>
import Counter from "path/to/Counter"
export default {
components: {
Counter
},
}
</script>
$emit
$emit抛出一个事件给父组件并传递带上参数,父组件如果传递了该事件的回调,则父组件会执行该回调函数
$listeners
emit类似,不过$listeners存储的是父组件传递给子组件的所有事件,子组件可以通过该属性拿到对应的方法回调,直接执行并传递参数
子组件Counter
<template>
<button @click="$listeners.update(num1++)">click</button>
</template>
<script>
export default {
data() {
return {
num1: 0
}
}
}
</script>
父组件
<template>
<div>
<Counter @update="onUpdate"/>
<span>{{num}}</span>
</div>
</template>
<script>
import Counter from "path/to/Counter"
export default {
components: {
Counter
},
data() {
return {
num: 0
}
},
methods: {
onUpdate(num) {
console.log(num)
this.num = num;
}
}
}
</script>
ref
ref可以加在组件实例上,通过获取该ref得到组件实例,直接修改获取得到的组件实例的属性,例如data等
子组件Counter
<template>
<span>{{num1}}</span>
</template>
<script>
export default {
data() {
return {
num1: 0
}
}
}
</script>
父组件
<template>
<div>
<Counter ref="counter"/>
<button @click="onClick">+1</button>
</div>
</template>
<script>
import Counter from "path/to/Counter"
export default {
components: {
Counter
},
data() {
return {
num1: 0
}
},
methods: {
onClick() {
const counter = this.$refs["counter"];
counter.num1++;
}
}
}
</script>
slot和scope-slot
通过作用域插槽,可以让父组件在作用域插槽内部访问子组件传递给作用插槽的数据
子组件Counter
<template>
<div>
<header>
<slot name="userInfo" :userInfo="user"></slot>
</header>
<main>
some main info
</main>
</div>
</template>
<script>
export default {
data() {
return {
user: {
username: "ainuo5213",
description: "小蔡鸡"
}
}
}
}
</script>
父组件
<template>
<Counter ref="counter">
<template #userInfo="slotProp">
<p>昵称:{{slotProp.userInfo.username}}</p>
<p>描述:{{slotProp.userInfo.description}}</p>
</template>
</Counter>
</template>
<script>
import Counter from "path/to/Counter"
export default {
components: {
Counter
},
}
</script>
跨组件通信
vuex
vuex统一的数据仓库,全局共享单一实例的数据,例子见官方文档
router
router可以通过地址栏进行组件的间接通信
eventBus
导出一个vue的eventbus
export default new Vue({})
开启监听
import eventBus from "path/to/eventBus"
export default {
name: "App",
created() {
eventBus.$on("eventName", this.onHookInvoked)
},
destroyed() {
eventBus.$off("eventName", this.onHookInvoked)
},
methods: {
onHookInvoked(callback) {
const params = 22;
callback(params)
}
}
}
触发监听
<template>
<buttton @click="onClick">click</buttton>
</template>
<script>
import eventBus from "path/to/eventBus"
export default {
name: "App",
methods: {
onClick() {
eventBus.$emit("eventName", params => {
console.log(params)
});
}
}
}
</script>
provide和inject
父组件使用
<script>
import Numbers from './components/Numbers.vue'
export default {
name: 'App',
components: {
Numbers
},
provide: {
foo: "111"
}
}
</script>
子组件使用
<script>
export default {
name: 'HelloWorld',
inject: ["foo"],
mounted() {
console.log(this.foo)
}
}
</script>
若有其他案例请提供补充,谢谢大佬