组件传值
在子组件中通过props声明需要传参参数
父组件传值
通过 :参数进行传参
子组件调用父组件方法
子组件通过$emit(parentFunction,param…) 触发父组件事件
parentFunction 父组件方法名,父组件通过@parentFunction来声明该事件
param 可以给父组件事件传参
父组件调用子组件方法
如果需要让父组件调用子组件方法
需要在父组件中暴露子组件给模版
在子组件中暴露其方法给模版
需要使用setup,其在vue官方文档中解释为(顶级绑定暴露给模板)
完整示例
子组件 MaskModal.vue
<template>
<div class="mask" v-show="showModal">
<div class="real_mask"></div>
<div class="m_container">
<div class="title">
<span class="t_t">{{title}}</span>
# 这个通过$emit调用父组件的取消方法并传参
<span class="t_i" @click="$emit('cancel','已经取消了')"><b>x</b></span>
</div>
<div class="body">
<slot name="body">333</slot>
</div>
<div class="footer">
# 这个通过$emit调用父组件的提交方法
<div class="yes" @click="$emit('submit')">{{okTest?okTest:'同意'}}</div>
# 这个通过$emit调用父组件的取消方法
<div class="no" @click="$emit('cancel')">{{noTest?noTest:'不同意'}}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "MaskModal",
# 声明子组件需要的参数
props: {
showModal: Boolean,
okTest: String,
noTest: String,
},
setup: () => {
# 这里是为了让父组件能够调用子组件的方法
const childMethod = () => {
alert("成功调用子组件方法");
}
# 将子组件的方法通过setup暴露给顶级模版
return {
childMethod
}
},
data: () => {
return {
title: '协议声明',
}
},
}
</script>
# 样式 不解释
<style scoped lang="scss">
@import "src/assets/sass/mixin.scss";
@import "src/assets/sass/main.scss";
.mask {
@include create_mask();
z-index: 777;
.real_mask {
@include create_mask();
background-color: #333;
opacity: .5;
}
.m_container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 800px;
min-height: auto;
background-color: white;
.body {
width: 100%;
min-height: 100px;
}
.title {
width: 100%;
height: 70px;
background-color: #f5f5f5;
text-align: center;
line-height: 70px;
color: #424242;
font-size: 18px;
font-weight: 400;
.t_t {
float: left;
margin-left: 20px;
}
.t_i {
display: block;
position: relative;
float: right;
top: 22px;
height: 25px;
font-size: 25px;
width: 25px;
color: black;
border-radius: 25px;
margin-right: 20px;
line-height: 25px;
&:hover {
background-color: red;
color: white;
}
}
}
.footer {
width: 100%;
height: 81px;
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
.yes {
width: 160px;
height: 40px;
background-color: #ff6700;
text-align: center;
line-height: 40px;
color: white;
}
.no {
width: 160px;
height: 40px;
margin-left: 20px;
background-color: #b0b0b0;
line-height: 40px;
text-align: center;
color: white;
&:hover {
background-color: grey;
}
}
}
}
}
</style>
父组件 HomePage.vue
<template>
<common-header></common-header>
<product-menu></product-menu>
<product-show title="手机"></product-show>
<product-show title="平板"></product-show>
<router-view></router-view>
# show-modal="showModal" ok-test="ok" no-test="no" 给子组件传值
# @cancel="cancel" @submit="submit" 父组件事件 分别对应 $emit('cancel') $emit('submit')
# ref="child" 可以让我们直接访问底层 DOM 元素的情况 对应 const child
<mask-modal :show-modal="showModal" ok-test="ok" no-test="no" ref="child" @submit="handleClick" @cancel="cancel">
<template v-slot:body>
支付成功
</template>
</mask-modal>
</template>
<script>
import CommonHeader from "../components/CommonHeader";
import ProductMenu from "../components/ProductMenu";
import ProductShow from "../components/ProductShow";
import MaskModal from "../components/MaskModal";
import {ref} from 'vue'
export default {
setup: () => {
# child 变量名 需要同 组件上的ref 名称相同
const child = ref()
const handleClick = () => {
// 调用子组件的方法
# 需要子组件通过setup 暴露 childMethod 方法
child.value.childMethod()
}
# 原理 就是 通过ref 能直接访问 子组件dom
# 子组件暴露的方法 能从dom中直接调用
# 暴露子组件和 handleClick 方法
return {
child,
handleClick
}
},
name: "HomePage",
data: () => {
return {
showModal: true,
}
},
components: {CommonHeader, ProductMenu, ProductShow, MaskModal},
methods: {
cancel(message) {
console.log(message);
this.showModal = false;
},
},
mounted() {
}
}
</script>
<style lang="scss" scoped>
</style>