Vue手写dialog组件模态框过程详解
tjq11111 人气:0在vue项目下创建文件dialog
实现思路
1、dialog组件为模态框,因此应该是固定定位到页面上面的,并且需要留一定的插槽来让使用者自定义显示内容
2、难点在于如何一句话打开dialog,也就是下面的index.js文件的内容:导入我们已经写好的组件(可以先写一个及其简单的),模块暴露出一个函数(DiaLog)用于生成dialog,这里主要利用到vue中的createApp函数,createApp创建应用,将应用挂载到我们的新建div标签上,随着用户触发点击事件,将div标签销毁即可
index.js文件
import dialog from './index.vue' import { createApp} from 'vue' export const DiaLog = (obj) => { const app = createApp(dialog, { ...obj, on_click: (flg) => { console.log(flg); div.remove() }, }) const div = document.createElement('div') app.mount(div) document.body.appendChild(div) }
使用
<template> <div class="app"> <button @click="DiaLog({_title:'我不想起标题'})">起飞</button> </div> </template> <script setup> import { DiaLog } from './package/dialog/index.js' </script> <style scoped lang="scss"> .app { height: 1200px; } </style>
index.vue文件
<template> <div class="dialog"> <h1 v-if="props._title">{{ props._title }}</h1> <div> <slot></slot> </div> <div class="btn"> <button @click="emitFn(false)">取消</button> <button @click="emitFn(true)" class="success">确认</button> </div> </div> <div class="background" v-if="props._background"></div> </template> <script setup> const props = defineProps({ _title: { type: String, default: '无标题' }, _background: { type: Boolean, default: true } }) const emit = defineEmits([ '_click' ]) const emitFn = (boolean) => { emit('_click', boolean) } </script> <style scoped lang="scss"> .dialog { background-color: white; z-index: 999; position: fixed; width: 400px; min-height: 200px; left: 50%; top: 50%; border: 1px solid rgba(0, 0, 0, 0.5); transform: translateX(-50%) translateY(-50%); display: flex; flex-direction: column; justify-content: space-between; padding: 15px; h1 { font-size: 20px; font-weight: 400; padding: 0; margin: 0; } .btn { display: flex; justify-content: end; button { padding: 5px 15px; border-radius: 5px; border: 2px solid #E2E2E2; font-size: 14px; cursor: pointer; } .success { color: white; background-color: #36AD6A; margin-left: 20px; } } } .background { width: 100vw; height: 100vh; position: fixed; left: 0; // display: none; top: 0; background-color: rgba(0, 0, 0, 0.5); z-index: 99; } </style>
加载全部内容