这是我写的组件,
父组件代码:
子组件代码:
首先遇到的问题是,我希望点击draw的确定按钮显示dialog弹框,发现不能在dialog弹框中去定义true和false,要在外部传进去,所以我注释了子组件中的const hideOrshowItem = ref(false)代码,
然后子文件中用的所有的hideOrshowItem就都报错找不到了,然后使用defineProps获取hideOrshowItem,这时候就应该有了,但还是报错,于是询问了chatGPT:
问:
还是报错
回答:
在你的代码中,hideOrshowItem
是一个组件的属性,你应该从props
中获取它。你可以使用toRefs
函数将props
对象转换为响应式的变量,并使用解构赋值来获取hideOrshowItem
属性。
下面是修改后的代码示例:
<script setup lang="ts">
import { ref, defineProps, toRefs } from "vue";
const props = defineProps<{
title: string;
text: string;
hideOrshowItem: boolean;
}>();
const { hideOrshowItem } = toRefs(props);
function closeAlert() {
hideOrshowItem.value = !hideOrshowItem.value;
console.log(hideOrshowItem.value, "hideorshowitem");
}
function showDialog() {
console.log("展示dialog");
hideOrshowItem.value = true;
}
function clickButton() {
console.log("点击按钮");
hideOrshowItem.value = !hideOrshowItem.value;
console.log(hideOrshowItem.value, "hideorshowitem");
}
</script>
<template>
<div>
<a @click="showDialog">点击打开 Dialog</a>
<div class="wrapper" :class="{ 'dialog-style': !hideOrshowItem }"></div>
<div class="white-box" :class="{ 'dialog-style': !hideOrshowItem }">
<div class="headline">
<span>{{ props.title }}</span>
<svg
t="1697281987826"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4001"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="14"
height="14"
@click="closeAlert()"
>
<path
d="M899.174 154.603l-29.782-29.782-357.397 361.114-357.397-361.114-29.782 29.782 361.114 357.397-361.114 357.397 29.782 29.782 357.397-361.114 357.397 361.114 29.782-29.782-361.114-357.397z"
p-id="4002"
fill="#bfbfbf"
></path>
</svg>
</div>
<div class="text">{{ props.text }}</div>
<div class="footer">
<button class="btn" @click="clickButton">取消</button>
<button class="btn" @click="clickButton">确定</button>
</div>
</div>
</div>
</template>
修改代码后确实可以获取了,使用了toRefs结构出hideOrshowItem来使用
现在点击draw的确定按钮可以显示dialog弹框了,但有个问题,dialog的取消确定和关闭按钮点击都没有效果,查看控制台console结果hideOrshowItem都是true,点多少次都是true,继续问chatGPT:
问:
打印出来结果一直是true
回答:
hideOrshowItem
是一个从父组件中接收的props属性,不能直接修改,需要使用emit来通知父组件修改props属性值。你需要在子组件中定义一个事件,并调用$emit()
方法来触发该事件以通知父组件更新。
修改后的代码示例如下:
<script setup lang="ts">
import { defineProps, toRefs, defineEmits } from "vue";
const props = defineProps<{
title: string;
text: string;
hideOrshowItem: boolean;
}>(); // 定义属性
const { hideOrshowItem } = toRefs(props); // 将hideOrshowItem变为响应式的变量
const emits = defineEmits(["update:hideOrshowItem"]); // 定义事件
function closeAlert() {
emits("update:hideOrshowItem", false); // 发送update事件给父组件
}
function showDialog() {
emits("update:hideOrshowItem", true); // 发送update事件给父组件
}
function clickButton() {
emits("update:hideOrshowItem", !hideOrshowItem.value); // 发送update事件给父组件,并传递新的hideOrshowItem值
}
</script>
<template>
<div>
<a @click="showDialog">点击打开 Dialog</a>
<div class="wrapper" :class="{ 'dialog-style': !hideOrshowItem }"></div>
<div class="white-box" :class="{ 'dialog-style': !hideOrshowItem }">
<div class="headline">
<span>{{ props.title }}</span>
<svg
t="1697281987826"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4001"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="14"
height="14"
@click="closeAlert()"
>
<path
d="M899.174 154.603l-29.782-29.782-357.397 361.114-357.397-361.114-29.782 29.782 361.114 357.397-361.114 357.397 29.782 29.782 357.397-361.114 357.397 361.114 29.782-29.782-361.114-357.397z"
p-id="4002"
fill="#bfbfbf"
></path>
</svg>
</div>
<div class="text">{{ props.text }}</div>
<div class="footer">
<button class="btn" @click="clickButton">取消</button>
<button class="btn" @click="clickButton">确定</button>
</div>
</div>
</div>
</template>
我们在子组件写了emits来使用defineEmits相符组件传递update:hideOrshowItem
当点击closeAlert,showDialog和clickButton的时候会传递相应的true或false给父组件,
在上面的代码中,我们使用defineEmits()
定义一个名为update:hideOrshowItem
的事件,用来通知父组件更新hideOrshowItem
属性。然后在closeAlert()
、showDialog()
和clickButton()
方法中,我们调用emits()
函数来发出update
事件并传递新的hideOrshowItem
值。这样就可以让父组件更新hideOrshowItem
的值了
到这里子组件给父组件传递了update:hideOrshowItem,那副组件肯定要接受,所以继续问:
问:
父组件怎么写
回答:
在父组件中,你需要使用子组件并传递hideOrshowItem
属性,并监听子组件的update:hideOrshowItem
事件来更新hideOrshowItem
的值。
下面是一个示例,展示了父组件如何使用子组件和更新hideOrshowItem
的值:
<template>
<div>
<ChildComponent :hideOrshowItem="hideOrshowItem" @update:hideOrshowItem="updateHideOrshowItem" />
<button @click="toggleHideOrshowItem">切换 hideOrshowItem 的值</button>
</div>
</template>
<script>
import ChildComponent from "@/components/ChildComponent.vue";
export default {
components: {
ChildComponent,
},
data() {
return {
hideOrshowItem: true,
};
},
methods: {
updateHideOrshowItem(value) {
this.hideOrshowItem = value;
},
toggleHideOrshowItem() {
this.hideOrshowItem = !this.hideOrshowItem;
},
},
};
</script>
上述代码是chatGPT举了一个父组件的例子,使用@update:hideOrshowItem来触发一个事件更新控制dialog显示的值,
我们的父组件写法上面有,
定义updateHideOrshowItem事件,e接收的是true或者false,因为我们控制dialog显示隐藏的值是:hideOrshowItem="showDialog",所以控制showDialog.value是true或者false实现