一、props
在Vue3中,props依然是一个非常重要的属性,通过在子组件中设置props选项,可以让父组件向子组件传递数据:
// 父组件传递数据到子组件
<template>
<child-component :message="parentMessage">
</child-component>
</template>
<script>
import ChildComponent from './ChildComponent';
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from parent component'
};
}
}
</script>
// 子组件接收props数据
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: {
message: String
}
}
</script>
此时,父组件向子组件传递了一个字符串类型的message数据,而子组件接收到该数据并直接在页面中渲染出来。
二、依赖注入provide/inject
在Vue3新增了provide/inject选项,用于实现父组件向子孙组件传递数据,使用方式如下:
// 父组件提供数据
<template>
<child-component>
</child-component>
</template>
<script>
import { provide } from 'vue';
import ChildComponent from './ChildComponent';
export default {
components: {
ChildComponent
},
setup() {
const parentMessage = 'Hello from parent component';
provide('message', parentMessage);
}
}
</script>
// 子组件接收provide中的数据
<template>
<grandchild-component></grandchild-component>
</template>
<script>
import { inject } from 'vue';
import GrandchildComponent from './GrandchildComponent';
export default {
components: {
GrandchildComponent
},
setup() {
const message = inject('message');
return {
message
}
}
}
</script>
// 孙子组件中使用父组件提供的数据
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
setup(props, { attrs, slots, emit }) {
// 这里也可以使用inject来获取到父组件提供的数据
}
}
</script>
在父组件中使用provide来提供数据,而在子孙组件中使用inject来获取父组件提供的数据。需要注意的是,provide/inject是依赖底层组件实例的引用来实现的,所以不能在setup函数外使用。
三、$attrs/$listeners
在Vue3中,$attrs/$listeners是一种新的组件属性,前者获取父组件传递过来的非prop属性,后者获取父组件传递过来的非prop事件,使用方式如下:
// 父组件向子组件传递非prop属性和事件
<template>
<child-component title="Hello World" @click="doSomething"></child-component>
</template>
// 子组件中使用$attrs和$listeners来访问父组件传递过来的数据
<template>
<div :title="$attrs.title" @click="$listeners.click"></div>
</template>
<script>
export default {
inheritAttrs: false // 必须设置,否则会将所有的非prop属性透传到根元素上
}
</script>
这里子组件中使用$attrs.data来访问title属性,$listeners.click来访问click事件。
四、$emit
在Vue3中,$emit是一种子组件向父组件传递数据的方法,使用方式如下:
// 子组件向父组件传递数据
<template>
<div @click="sendMessage"></div>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('message', 'Hello from child component');
}
}
}
</script>
// 父组件接收子组件传递过来的数据
<template>
<child-component @message="handleMessage"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent';
export default {
components: {
ChildComponent
},
methods: {
handleMessage(message) {
console.log(message);
}
}
}
</script>
子组件中通过$emit来传递数据,而父组件则通过@message来监听message事件,并在回调函数中获取到子组件传递过来的数据。
五、ref/$refs
在Vue3中,ref/$refs是一种组件引用方式,可以在父组件中通过ref属性来获取到子组件实例,从而可以调用子组件中的方法和属性,使用方式如下:
// 父组件中获取子组件实例
<template>
<child-component ref="child"></child-component>
</template>
<script>
import { ref } from 'vue';
import ChildComponent from './ChildComponent';
export default {
components: {
ChildComponent
},
setup() {
const childRef = ref(null);
return {
childRef
}
},
mounted() {
console.log(this.$refs.child); // 这里也可以获取到子组件实例
}
}
</script>
// 子组件中可以通过this.$emit来向父组件传递数据
<template>
<div></div>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('message', 'Hello from child component');
}
}
}
</script>
在父组件中,可以通过ref来获取到子组件的实例,在子组件中则可以通过this.$emit来向父组件传递数据。
通过以上五种方式,我们可以在Vue3中实现父子组件之间的数据传递和通信。需要根据实际场景来选择不同的实现方式,以达到更好的应用效果。