Hey, guys, I’m a quack. I’m a professional. 🦞

Summary in front:

Tipes: Encapsulation frame components use Teleport to avoid the positioning hierarchy potential caused by component nesting, and use defineProps, defineEmits, slots to increase the scalability of components.

🌲🌲 foreword: I have never packaged a pop-up component before, but I feel that a small pop-up component is not a sprinkle of water. And I needed a popover component for my new project today, so I made one. It doesn’t matter if you don’t do it. There are still lots of different little problems, and then share them with the big guys.

To start, let’s review the requirement, a common popbox component for global use. So there are a few points: public, global, frame, the following we are aimed at these points to achieve a little bit of frame components.

🍬🍬 public 🍬🍬 public this simple, I believe that everyone here must be holding a pinch, easy to achieve. To implement a body of content, MY approach is to use slots and parameter passing. The example simply passes two arguments, a header content and a Boolean value that controls turning on and off. This mainly involves the use of defineProps, defineEmits and slots for Vue3.

<template>
    <Mask @click="close" /> / / mask layer
    <div class="modal_all" v-if="visible">
        <slot name="header">// Add a custom header to the convenience page<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>// Open the popbox content to use</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>
// style is omitted
Copy the code

🍬🍬 global 🍬🍬 The basic layout is almost the same, the following is the global registration, the purpose is not to use every time to import. Vue2 can register global components directly by Vue.component(‘ name ‘, component). Provide an install method that is automatically called using app.use().

import Modal from './Modal/Modal.vue';
import Mask from './Modal/Mask.vue';

// Name cannot be written in script setup, so add one here
const coms = [
  {
    name: 'Modal'.// Use the component name
    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);
Copy the code

🍬🍬 shell 🍬🍬 In fact, the shell component is almost written here, then why to list the shell separately? Believe, also encountered in daily work location and level of problem, if we need to locate the components of the nested within a component of the Vue, because we in dealing with CSS for a wide variety of layer nested orientation, hierarchy and style becomes difficult, accidentally can appear some strange questions, so how to avoid this problem? Now use another portal Api from Vue3: Teleport. Tipes: Teleport simply mounts our component to the DOM element corresponding to the property to, like an arbitrary gate. Code first:

<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>
Copy the code

Let’s look at the hierarchy after we write it this way:

Through the to attribute, we specify that the position of the popup component is rendered at the same level as the layput component, but the teleport state visible is completely controlled by the component we call, which avoids the problem of locating the hierarchical style when we nested the component.

🌼🌼 At this point, a simple public popbox component has been written. However, while writing this component I ran into several non-problem problems 😅. ❗️❗️ port: ❗️ ️ port: ❗ 1.script setup cannot write the name property: if ts is not used, you can write a script tag, export it and write the name. If ts is used, the method will not work and an error will be reported. So let’s take advantage of the way I wrote it up here, and redefine it for ourselves as writing an object. ❗️❗️ ️ ️2. Adding a class style to a global component does not take effect: In fact, we normally write public components and want to directly control the style of the inner container in the outer layer. We can directly add a class name to the outer layer to increase the style, but when I write this popbox component, it does not take effect. After searching for a long time, I found that it is because I use teleport. So class cannot be inherited when parsing. The same problem can occur if the component does not have a root component. In fact, it doesn’t matter, we write content in the slot automatically open it, I believe that you will certainly not like me to make such a silly operation, ha ha.

🎉🎉🎉 Conclusion: In fact, the packaging of a bullet frame component is still very simple, but it can also be regarded as the accumulation of a little experience, the implementation of their own projects. It will also make sense to encapsulate more complex components later. No silicon step down to thousands of miles, come on, gentlemen!

Finally, I wish you study and progress, a successful career! 🎆 🎆 🎆