第一次用vue3写父子组件传值,记录一下嘻(三种写法)
第一种代码如下(子传父)
父组件 名为first-page
<template>
<div>
<one-dialog :show-dialog="state.showDialog" @updateDialog="updateDialog" />
</div>
</template>
<script setup>
import { reactive } from 'vue';
// 引入子组件
import OneDialog from '../../componets/one-dialog.vue';
const state = reactive({
showDialog: false
});
const updateDialog = showDialog => {
console.log(555, showDialog);
state.showDialog = showDialog;
};
</script>
<style scoped>
</style>
子组件 名为one-dialog
<template>
<div class="first-content">
<div class="first-content__dialog" @click="showClick">点击出现弹窗</div>
<div v-show="props.showDialog" class="dialog">
<div class="dialog__icon clearfix">
<img class="dialog__icon__close" src="../assets/images/close.png" @click="closeDialog" />
</div>
<div class="dialog__content">这是弹窗里面的内容</div>
</div>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
showDialog: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['updateDialog']);
const showClick = () => {
emit('updateDialog', true);
};
const closeDialog = () => {
console.log(999);
emit('updateDialog', false);
};
</script>
<style scoped>
.first-content__dialog {
cursor: pointer;
}
.dialog {
position: fixed;
font-size: 24px;
height: 360px;
width: 260px;
background-color: rgb(9, 66, 170);
border-radius: 20px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 1000;
}
.clearfix::after {
content: '';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.dialog__icon__close {
cursor: pointer;
float: right;
}
.dialog__content {
text-align: center;
}
</style>
第二种利用.sync修饰符,但是vue3中已经不支持这种语法,改成了v-model语法,并可支持多个v-model 具体可以参考vue3的官方文档呐 这是把点击出现弹窗的点击事件放到父组件中
上代码: 父组件代码
<template>
<div>
<div class="first-content__dialog" @click="showClick">点击出现弹窗</div>
<one-dialog v-model:showDialog="state.showDialog" />
</div>
</template>
<script setup>
import { reactive } from 'vue';
// 引入子组件
import OneDialog from '../../componets/one-dialog.vue';
const state = reactive({
showDialog: false
});
const showClick = () => {
state.showDialog = true;
};
</script>
<style scoped>
.first-content__dialog {
cursor: pointer;
}
</style>
子组件代码:
<template>
<div class="first-content">
<!-- <div class="first-content__dialog" @click="showClick">点击出现弹窗</div> -->
<div v-show="props.showDialog" class="dialog">
<div class="dialog__icon clearfix">
<img class="dialog__icon__close" src="../assets/images/close.png" @click="closeDialog" />
</div>
<div class="dialog__content">这是弹窗里面的内容</div>
</div>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
showDialog: {
type: Boolean,
default: false
}
});
const emit = defineEmits(['update:showDialog']);
const closeDialog = () => {
console.log(999);
emit('update:showDialog', false);
};
</script>
<style scoped>
.first-content__dialog {
cursor: pointer;
}
.dialog {
position: fixed;
font-size: 24px;
height: 360px;
width: 260px;
background-color: rgb(9, 66, 170);
border-radius: 20px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 1000;
}
.clearfix::after {
content: '';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.dialog__icon__close {
cursor: pointer;
float: right;
}
.dialog__content {
text-align: center;
}
</style>
第三种写法就是看官方文档中可以把修饰符去掉,那就去掉康康 父组件代码:
<template>
<div>
<div class="first-content__dialog" @click="showClick">点击出现弹窗</div>
<one-dialog v-model="state.showDialog" />
</div>
</template>
<script setup>
import { reactive } from 'vue';
// 引入子组件
import OneDialog from '../../componets/one-dialog.vue';
const state = reactive({
showDialog: false
});
const showClick = () => {
state.showDialog = true;
};
</script>
<style scoped>
.first-content__dialog {
cursor: pointer;
}
</style>
子组件代码:
<template>
<div class="first-content">
<!-- <div class="first-content__dialog" @click="showClick">点击出现弹窗</div> -->
<div v-show="props.modelValue" class="dialog"> // 传过来的值modelValue
<div class="dialog__icon clearfix">
<img class="dialog__icon__close" src="../assets/images/close.png" @click="closeDialog" />
</div>
<div class="dialog__content">这是弹窗里面的内容</div>
</div>
</div>
</template>
<script setup>
// import { reactive } from 'vue';
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
modelValue: { // 注意props的写法哦,是必须叫这个名字的
type: Boolean,
default: false
}
});
const emit = defineEmits(['update:modelValue']); // 注意modelValue写法哦,是必须叫这个名字的
const closeDialog = () => {
console.log(999);
emit('update:modelValue', false); // 跟emit里面的名字保持一致,也是叫modelValue
};
</script>
<style scoped>
.first-content__dialog {
cursor: pointer;
}
.dialog {
position: fixed;
font-size: 24px;
height: 360px;
width: 260px;
background-color: rgb(9, 66, 170);
border-radius: 20px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 1000;
}
.clearfix::after {
content: '';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.dialog__icon__close {
cursor: pointer;
float: right;
}
.dialog__content {
text-align: center;
}
</style>
好啦,就酱紫,刚上手写也是会有不一样的感触,所以记录一下,特别注意vue3的语法是可以使用多个v-model的,也是可以省略修饰符滴,但是必须叫modelValue,具体可以参考vue3官网