总结放后面:
Tipes: 封装弹框组件应用了 Teleport,防止了组件嵌套可能导致的定位层级的隐患,还应用了 defineProps,defineEmits,插槽减少了组件的拓展性。
🌲🌲 前言:
之前始终没有本人去封装过一个弹框组件,然而感觉一个小小的弹窗组件那不是洒洒水小意思了。而后明天新我的项目中须要一个弹窗组件,所以我就做了一个。不做不要紧一做发现还是有很多不同的小问题,而后就把遇到的问题和大佬们分享一下。开始先回顾一下需要,一个全局应用的公共弹框组件。那么就有几个要点:公共、全局、弹框,上面咱们就针对这几个要点去一点点实现弹框组件。
🍬🍬公共🍬🍬
公共这个简略,置信在座的各位大佬必定都是手拿把掐,轻轻松松就实现了。先实现一个主体内容,我的办法就是应用插槽和参数传递。例子只是简略的传递两个参数,一个题目内容一个管制关上和敞开的布尔值。次要波及到 Vue3 两个 Api 的应用 defineProps,defineEmits 还有插槽的应用。
<template>
<Mask @click="close" /> // 蒙板层
<div class="modal_all" v-if="visible">
<slot name="header"> // 不便页面减少定制头部
<div class="modal_header">
<p class="modal_header_title">{{title}}</p>
<p class="modal_header_img" @click="close"></p>
</div>
</slot>
<div class="modal_content">
<slot></slot> // 凋谢弹框内容应用
</div>
</div>
</template>
<script lang=”ts” setup>
defineProps({
visible: {
type: Boolean,
default: false,
},
title: {type: String,},
});
const emit = defineEmits([‘update:visible’]);
const close = () => {
emit('update:visible', false);
};
</script>
// 款式省略
复制代码
🍬🍬全局🍬🍬
根本布局差不多了,上面就是全局注册,目标是为了不必每次应用每次都要引入。vue2 在注册全局组件的时候,间接 Vue.component('名称', 组件)就能够了,那么在 vue3 中怎么批量注册全局组件呐?提供一个 install 办法,应用 app.use()主动调用。
import Modal from ‘./Modal/Modal.vue’;
import Mask from ‘./Modal/Mask.vue’;
// 在 script setup 不能写 name,所以在这里加一个
const coms = [
{
name: 'Modal', // 应用组件的名称
compent: Modal,
},
{
name: 'Mask',
compent: Mask,
},
];
export default {
install: (app) => {
coms.forEach((item) => {app.component(item.name, item.compent);
});
},
};
// main.ts
import Common from ‘./common/index’;
const app = createApp(App);
app.use(Common);
复制代码
🍬🍬弹框🍬🍬
其实弹框组件写到这里曾经差不多了,那为什么要把弹框这个独自列出来说一下呐?置信各位大佬在日常工作中也遇到过定位和层级的问题,如果咱们把须要定位的组件嵌套在 Vue 的某个组件外部,因为 css 各种层的起因咱们在解决嵌套的定位、层级 和款式就会变得很艰难,一不小心就会呈现一些奇奇怪怪的问题,那么怎么去防止这个问题?上面就要应用到 Vue3 中另外一个传送门 Api:Teleport。
Tipes: Teleport 就是将咱们的组件挂载到属性 to 对应的 DOM 元素中,相似一个任意门。
先上代码:
<teleport to=”#mask_modal” v-if=”visible”>
<div class="modal_cent">
<Mask @click="close" />
<div class="modal_all">
<slot name="header">
<div class="header">
<p class="header_title">{{title}}</p>
<p class="header_img" @click="close"></p>
</div>
</slot>
<div>
<slot></slot>
</div>
</div>
</div>
</teleport>
复制代码
咱们来看一下这样写之后的层级:
通过 to 属性,指定弹框组件渲染的地位与 layput 组件同级,然而 teleport 的状态 visible 又是齐全由咱们调用的组件管制,就防止了咱们在嵌套组件的时候定位层级款式的问题。
🌼🌼 至此,一个简略的公共弹框组件曾经写的差不多了。而后在写这个组件的过程中我还是遇到了几个不算问题的问题😅。
❗️❗️❗️1.script setup 中没法写 name 属性:
如果没有用 ts 的话,能够再写一个 script 标签,在外面导出而后写 name。如果应用 ts,那么这个办法就行不通就会报错。那么就利用我下面写的办法,本人从新定义一下写一个对象那样。
❗️❗️❗️2. 间接给全局组件加一个 class 加款式不失效:
其实咱们失常写公共组件,在应用的中央想间接在外层管制外部容器的款式,咱们能够间接在里面加一个类名去减少款式,然而我在写这个弹框组件的时候却始终不失效,找了半天起初才发现原来是因为我应用了 teleport,所以在解析的时候 class 不能被继承。同样要是组件内没有一个根组件同样会呈现这样的问题。这样其实也没关系,咱们在插槽内写内容主动撑开就能够了,置信各位大佬必定不会像我一样搞这么傻的操作,哈哈。
🎉🎉🎉结语:
其实一个弹框组件的封装还是很简略的,不过也算是积攒了一点教训,把本人的我的项目施行落地。前面去封装更加简单的组件也会比拟有思路。不积硅步无以至千里,加油各位大佬!
最初
如果你感觉此文对你有一丁点帮忙,点个赞。或者能够退出我的开发交换群:1025263163 互相学习,咱们会有业余的技术答疑解惑
如果你感觉这篇文章对你有点用的话,麻烦请给咱们的开源我的项目点点 star: https://gitee.com/ZhongBangKe… 不胜感激!