Vue3中,子组件通过setup函数中的第一个参数值 props 拿到定义的组件参数进行使用。如果要向父组件传参,需要使用setup函数中的第二个参数值 context(组件上下文)中的emit。
例1:Tab菜单子组件
- 创建子组件Tabs.vue
<template>
<div class="Tabs">
<div v-for="(menu, index) in listMenu" :key="index"
@click="menuClick(menu.name)"
:class="{ 'mactive' : menu.isActive === true ? true : false }">
{{ menu.name }}
</div>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
name: 'Tabs',
props: {
listMenu: { // 菜单数据
type: Array,
required: true,
default(){
return []
}
}
},
setup(props, context){
const listMenu = props.listMenu
function menuClick (menuName) {
// 通过自定义事件回传值
context.emit('menuClick', { menuName })
}
return {
listMenu,
menuClick
}
}
})
</script>
<style lang='scss'>
.Tabs{
padding: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: space-around;
height: 50px;
background-color: #0087AC;
color: black;
}
.mactive{
color: white;
font-weight: bold;
}
</style>
- 父组件
<template>
<!--使用子组件,传值并监听子组件自定义事件拿值-->
<Tabs :listMenu="listMenu" @menuClick="menuClick" />
</template>
<script>
import { defineComponent, ref } from "vue";
import Tabs from '../components/Tabs'
export default defineComponent({
name: "Index",
components: {
Tabs
},
setup() {
const listMenu = ref([
{
name : '总部',
isActive : true
},
{
name : '地球',
isActive : false
},
{
name : '火星',
isActive : false
}
])
function menuClick (param) {
listMenu.value.forEach(item => {
item.isActive = item.name === param.menuName ? true : false
})
}
return {
listMenu,
menuClick
}
}
});
</script>
例2:搜索子组件
- 创建子组件Search.vue
<template>
<div class="searchInp">
<div class="inp">
<input type="text" :placeholder="placeholder" v-model="search.content" />
<span @click="handlerSearch">搜索</span>
</div>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
name: 'Search',
props: {
tip: {
type: String,
reuquired: false,
default: ''
}
},
setup(props, { emit }) {
const placeholder = props.tip
const search = ref({
content: ''
})
function handlerSearch () {
emit('searchClick', search.value)
}
return {
placeholder,
search,
handlerSearch
}
}
})
</script>
<style lang="scss">
.searchInp{
height: 40px;
line-height: 40px;
width: 100%;
background-color: #0087AC;
border-radius: 20px;
color: white;
}
.inp input{
width: 80%;
height: 30px;
line-height: 30px;
background-color: transparent;
border: none;
outline: none;
color: white;
}
.inp input::-webkit-input-placeholder{
color: white;
}
.inp span{
width: 20%;
}
</style>
- 父组件
<template>
<!--使用子组件,传值并监听子组件自定义事件拿值-->
<Search tip="请输入搜索内容" @searchClick="searchClick" />
<h3>子组件传值内容:{{ searchCon }}</h3>
</template>
<script>
import { defineComponent, ref } from "vue";
import Search from '../components/Search'
export default defineComponent({
name: "Index",
components: {
Search
},
setup() {
const searchCon = ref('')
function searchClick (searCon) {
searchCon.value = searCon.content
}
return {
searchClick,
searchCon
}
}
});
</script>