在vue中一个.vue文件就是一个组件,一般来说不会在一个文件写太多的代码,我们可以把重复使用的代码写到一个组件中,在另一个组件中引用这个被封装的组件,这样可以提高代码复用性。前一个组件叫做子组件,后一个叫做父组件。
父组件中引用子组件
父组件
<template>
<div class="main">
<p>I am father</p>
下面是子组件
<Child>直接在这里写内容是不会显示出来的</Child>
</div>
</template>
<script setup>
import Child from './components/Child.vue' //引入子组件
</script>
<style scoped>
.main {
width: 300px;
height: 300px;
border: 1px solid greenyellow;
}
</style>
子组件
<template>
<div>shit</div>
</template>
<script setup>
</script>
<style scoped>
div {
width: 100px;
height: 100px;
border: 1px solid blueviolet;
}
</style>
结果如下,可以看到在父组件中引用了子组件。在里面的内容不会显示。
定义了Child组件,我们可以在任意组件中引用这个组件。在同一个父组件中也可以多次使用子组件。
父子数据传递
组件定义的数据只能自己使用,但是不同组件之间想要传输数据怎么办呢?
在子组件中使用defineProps把要传递的属性暴露出去,这样父组件能够通过这个属性传递值给子组件。
注意:父组件中的命名要和子组件中defineProps中的属性命名一样,即:num要和defineProps中的num属性名字一样。
父组件
<template>
<div class="main">
<p>I am father</p>
下面是子组件
<Child :num="son.num"></Child>
</div>
</template>
<script setup>
import Child from './components/Child.vue' //引入子组件
import {reactive} from 'vue'
const son=reactive({
num: 123
})
</script>
<style scoped>
.main {
width: 300px;
height: 300px;
border: 1px solid greenyellow;
}
</style>
子组件
<template>
<div>
这里是父组件传来的值:{{props.num}}
</div>
</template>
<script setup>
const props=defineProps({
num: {
type: Number, //定义了num的类型,如果从父组件中传递过来的数据不是number类型就报错
default: 0 //默认值是0 如果父组件有值传过来就是传过来的,否则就是0
},
str: {
type: String
}
})
</script>
<style scoped>
div {
width: 100px;
height: 100px;
border: 1px solid blueviolet;
}
</style>
对于props有一个简易的写法:(不过这样的写法不能定义数据类型和默认值)
<script setup>
defineProps(['num',str])
</script>
结果如下,:num="son.num"把数据num传递给子组件。
子组件向父组件传递方法
组件之间不仅要传输数据,有时候还需要传递方法。
例如子组件是一个弹窗,当我想要它出现的时候点击一个按钮便弹出,当我不想要的时候就点击按钮把它关闭。
父组件
在父组件中写一个按钮,点击son.show变为true就会出现弹框
在中的@closeSon名字要和子组件中暴露出的名字一样
<template>
<div class="main">
<p>I am father</p>
<button @click="showSon">show son</button>
<Child @closeSon="close" v-show="son.show"></Child>
</div>
</template>
<script setup>
import Child from './components/Child.vue' //引入子组件
import {reactive} from 'vue'
const son=reactive({
title: 'shit',
show: false //默认是false 弹框不出现
})
const showSon=()=>{
son.show=true //弹框出现
}
//子组件传来的方法 点击子组件中的按钮子组件就消失
const close=()=>{
son.show=false
}
</script>
<style scoped>
.main {
width: 300px;
height: 300px;
border: 1px solid greenyellow;
}
</style>
子组件
子组件中使用defineEmits把方法暴露出去,注意名字要一样。
在子组件中点击按钮影响到父组件中的son.show变为false,弹框消失
<template>
<div>
<button @click="closeSon">close</button>
</div>
</template>
<script setup>
//使用defineEmits定义要传递的方法
const emit=defineEmits(['closeSon'])
// 写一个同名的方法
const closeSon=()=>{
emit('closeSon') //把它暴露给父组件
}
</script>
<style scoped>
div {
width: 100px;
height: 100px;
border: 1px solid blueviolet;
}
</style>
结果如下,当点击父组件中的按钮就会出现弹框,当点击子组件中的按钮弹框消失。