当前位置: 首页 > article >正文

element-plus弹窗二次封装踩坑

1 基于element-plus的二次封装弹窗很常见。代码如下:

父组件:

import Dialog from './components/Dialogs/testDailog.vue'

const show=ref(false)
const openDialog=()=>{
  show.value=true

}



<button @click="openDialog" >打开dialoag</button>
<Dialog   v-model="show"/>

弹窗的内容:

<template>
  <el-dialog
    v-model="visible"
    title="Tips"
    width="30%"
    @close="handerClose"
  >
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <el-button @click="cancel">取消</el-button>
    <el-button @click="confirm">确定</el-button>
      
  </el-dialog>
</template>

<script setup lang='ts'>

import { ref, reactive, watch, onMounted, onUnmounted } from 'vue'

const emits=defineEmits(['close','confirm','update:modelValue'])

const props=defineProps({
    modelValue:{
        type:Boolean,
        default:false
    }
})
const visible=ref(false)

const cancel=()=>{
    emits('update:modelValue',false)
}
const confirm=()=>{
    emits('update:modelValue',false)
}

const handerClose=()=>{
    console.log("点击关闭按钮");
    emits('update:modelValue',false)
}

watch(()=>props.modelValue,(newVal)=>{
    visible.value=newVal;
    console.log("props.modelValue",props.modelValue);
    emits('update:modelValue',newVal)
})



</script>


<style lang='scss' scoped>

</style>

到这基本上就可以实现了。这一版的特点就是弹窗的关闭时其实本身没有销毁。我们是通过双向绑定跟新了弹窗的状态

但是我们考虑一个场景,就是表单弹窗复用。新增和编辑态我们要做区分。这时候我们手动传属性标识是编辑还是新增就很麻烦。有一个简单的办法就是我们在关闭弹窗时直接把它销毁,这样每次我们只需要在生命周期的onMounted中判断是否有id传过来就可以了。如果有id则说明是编辑态。否则是新增的场景。这样就很容易区分。我们改造下代码:

改进版

销毁弹窗我们通过v-if来控制

父组件
  
<button @click="openDialog" >打开dialoag</button>
  <Dialog  v-if="show" v-model="show"/>
//注意这里增加了v-if
弹窗组件
<template>
  <el-dialog
    v-model="visible"
    title="Tips"
    width="30%"
    @close="handerClose"
  >
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <P>This is a message</P>
    <el-button @click="cancel">取消</el-button>
    <el-button @click="confirm">确定</el-button>
      
  </el-dialog>
</template>

<script setup lang='ts'>

import { ref, reactive, watch, onMounted, onUnmounted } from 'vue'

const emits=defineEmits(['close','confirm','update:modelValue'])

const props=defineProps({
    modelValue:{
        type:Boolean,
        default:false
    }
})
const visible=ref(props.modelValue)

const cancel=()=>{
    emits('update:modelValue',false)
}
const confirm=()=>{
    emits('update:modelValue',false)
}

const handerClose=()=>{
    console.log("点击关闭按钮");
    emits('update:modelValue',false)
}

onMounted(()=>{
    console.log("挂载");
})

onUnmounted(()=>{
    console.log("卸载");
})
watch(()=>props.modelValue,(newVal)=>{
    visible.value=newVal;
    console.log("props.modelValue",props.modelValue);
    emits('update:modelValue',newVal)
})



</script>


<style lang='scss' scoped>

</style>

在组件内部,我们通过定义visible,初始状态和props.modelValue绑定,后续跟新在watch里同步,这样就可以实现每次销毁和挂载

注意:

const visible=ref(props.modalValue),定义visible的时候一定要先和props.modalValue进行绑定。不然父组件点击不会弹出来


http://www.kler.cn/a/418943.html

相关文章:

  • vue 2 父组件根据注册事件,控制相关按钮显隐
  • YOLO 标注工具 AutoLabel 支持 win mac linux
  • 算法刷题Day1
  • windows docker 入门
  • Permute for Mac 媒体文件格式转换软件 安装教程【音视频图像文件转换,简单操作,轻松转换,提高效率】
  • 看华为,引入IPD的正确路径
  • repo仓库转移到自己本地的git服务器
  • PostgreSQL17官网下载详细教程
  • Flutter 指纹识别
  • MVC core 传值session
  • Android 混淆问题
  • Rust vs Java:后端开发应该选哪个?
  • npm 最新国内淘宝镜像地址源 (旧版已不能用)
  • VS Code前端常用插件
  • 使用ECharts创建带百分比标注的环形图
  • ZOOKEEPER [Zookeeper——Docker下安装部署]
  • 解决“ VMware Tools for Windows Vista and later“报错问题
  • 泷羽sec-云技术
  • 机器学习6_支持向量机_算法流程
  • 易速鲜花聊天客服机器人的开发(下)
  • 服务器数据恢复—raid6阵列硬盘被误重组为raid5阵列的数据恢复案例
  • qt QConicalGradient详解
  • 解决虚拟机中 GitHub 无法通过 HTTPS 访问的问题
  • springboot359智慧草莓基地管理系统(论文+源码)_kaic
  • 深度学习现有网络的使用和修改以VGG16为例
  • MFC中如何在工具条动态增加菜单