[ElementPlus] 更加简洁的父子组件弹窗表单

297 阅读1分钟

经过new bing的优化, 得到如下的代码

我问它props中的值无法被修改,方案是否可行, 它回答:

在 Vue 中,props 是单向数据流,不能直接修改。
但是,使用 v-model 的参数语法并不会直接修改 props 的值。它实际上是通过触发一个自定义事件来更新父组件中的值。

当你在子组件中使用 v-model:isShow="isShow" 时,它等同于在子组件中添加了以下代码:

<el-dialog :isShow="isShow" @update:isShow="$emit('update:isShow', $event)">
这样,当 el-dialog 组件触发 update:isShow 事件时,子组件会触发一个名为 update:isShow 的自定义事件
并将新值作为参数传递给父组件。然后,在父组件中,你可以监听这个自定义事件并更新 isShow 的值。

所以,使用 v-model 的参数语法是可行的,并且不会直接修改 props 的值。

父组件

<template>
    <div class="box">
        <!-- 测试弹窗组件 -->
        <el-button @click="showIt">查看弹窗</el-button>
        <Sub :isShow="isShow" @update:isShow="isShow = $event"/>
    </div>
</template>
<script lang="ts" setup>
    import { ref } from 'vue';
    import Sub from './Sub.vue'
    let isShow = ref(false);

    const showIt = () => {
        isShow.value = true
        console.log("显示弹窗");
        console.log(isShow.value);
        
    }
</script>

子组件

<template>
    <div>
        <el-dialog :model-value="isShow" @update:model-value="$emit('update:isShow', $event)" title="信息">
            <el-form :model="form">
                <el-form-item label="这是子表单" :label-width="formLabelWidth">
                    <el-input v-model="form.name" autocomplete="off" />
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="$emit('update:isShow', false)">Cancel</el-button>
                    <el-button type="primary">确认</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
    import {reactive} from "vue";

    const form = reactive({
        name: ''
    })

    const props = defineProps({
        isShow: Boolean
    })
</script>