The whole process record of vue3 recursive component encapsulation

The whole process record of vue3 recursive component encapsulation

Preface

When writing a project today, I encountered a need for a custom right-click menu. There are submenus in the menu, so recursive components are used at this time. So I wrote this article to record the process of writing recursive components.

1. Recursive components

A recursive component, as the name suggests, calls itself within the component itself. So we first build a component and call itself within itself. The common recursive component is the tree component that is often used in our projects. Below is the source code of a recursive component I implemented to meet the project requirements.

<template>
   <ul class="list-container">
       <li v-for="(item,index) in listData" 
            :key="index" class="list-item" 
            @click.prevent.stop="handleClick($event,item)"
            @mouseover="childrenMenuIndex=index"
            >
           <span class="list-item_span">
               {{item.text}}
           </span>
           <CaretRightOutlined v-if="item.children" />
           <!-- Determine whether to call itself -->
           <div v-if="item.children&&childrenMenuIndex===index"
            class="context-menu context-menu_children"
           >
            <!-- Calling the component itself -->
            <list-comp :list-data='item.children' @hideContextMenu='hideContextMenuEvent' />
           </div>
       </li>
   </ul>
</template>
<script>
import { defineComponent, ref } from "vue";
import {CaretRightOutlined} from '@ant-design/icons-vue';
export default defineComponent({
    name:'list-comp',
    props:{
        listData:{
            type:Array,
            default:()=>[]
        }
    },
    components:{
        CaretRightOutlined
    },
    emits:
        "hideContextMenu"
    ],
    setup(props,{emit}){
    	//Click event const handleClick=(event,{text,callBack})=>{
            emit('hideContextMenu');
            //callBack is the callback function you passed in. If passed in, the custom callback function will be called if (callBack) {
                callBack();
                return;
            }
        }
        const hideContextMenuEvent=()=>{
            emit('hideContextMenu');    
        }
        //Used to identify the currently selected menu item const childrenMenuIndex=ref(-1);
        const eventNames=['click','contextmenu'];
        onMounted(()=>{ 
            eventNames.forEach(eventName=>window.addEventListener(eventName,hideContextMenuEvent))
        })
        onBeforeUnmount(()=>{
            eventNames.forEach(eventName=>window.removeEventListener(eventName,hideContextMenuEvent))
        })
        return {
            handleClick,
            childrenMenuIndex,
            hideContextMenuEvent
        }
    }
})
</script>

Precautions

  • Inside the recursive component itself, when calling itself, it is necessary to receive the custom event sent by itself through emit on the recursive component. After receiving it, trigger the custom event again through emit inside the component.
  • By listening to the click event, you can trigger a custom event through emit and listen outside the component; you can also build the callback yourself when passing data to the component through props, so you don't need to trigger a custom event through emit.
  • When you click a menu item in a recursive component, you need to destroy the recursive component. All we need to do is to listen to click, contextmenu and other events through event bubbling in the recursive component to destroy the component, and then trigger the custom event through emit so that the outside world can receive it, thereby achieving the purpose of destroying the component.
  • When calling the click event inside a recursive component, you need to prevent event bubbling and the default event. You can add click.prevent.stop after the click event to prevent event bubbling and default events.

2. Right-click menu component

In my project, I use components to implement the right-click menu. Of course, it can also be implemented through plug-ins. The right-click menu here is essentially a secondary encapsulation of the recursive component. In fact, there is no need for secondary encapsulation. You can directly use the recursive component as the right-click menu.

<template>
    <teleport to='body' >
        <div class="content-menu_container" :style="styleObj">
            <list-comp 
                :list-data='menuData'
                @hideContextMenu='windowClickHandler'
             />
        </div>
    </teleport>
</template>
<script>
import { defineComponent } from "vue";
import ListComp from "./list-comp.vue"
export default defineComponent({
    name:"contextMenu",
    components:{
        ListComp
    },
    props:{
        styleObj:{
            type:Object,
            default:()=>{}
        },
        menuData:{
            type:Array,
            default:()=>[]
        }
    },
    emits:['closeContextMenu'],
    setup(props,{emit}){
        const windowClickHandler=()=>{
            emit('closeContextMenu')
        };
        return {
            windowClickHandler,
        }
    }
})
</script>

Precautions

When calling the right-click menu in a project, you need to disable the right-click menu event of the window itself first. Then implement your own custom menu events. The implementation code is shown below.

const showContextMenu=(event)=>{
    //Disable default events and prevent bubbling event.stopPropagation();
    event.preventDefault();
    state.showContextMenu=true;
    state.styleObj={
      left:event.clientX+ "px",
      top:event.clientY+'px'
    }
  }
  //Monitor the right-click menu event of the window itself onMounted(()=>{
    window.addEventListener('contextmenu',showContextMenu)
  })
  onBeforeUnmount(()=>{
    window.removeEventListener('contextmenu',showContextMenu)
  })

Summarize

This is the end of this article about vue3 recursive component encapsulation. For more relevant vue3 recursive component encapsulation content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue3+TypeScript implements a complete example of a recursive menu component
  • Vue.js recursive component to implement tree menu (example sharing)
  • Vuejs uses recursive components to implement tree directories
  • Vue.js learning recursive components
  • Vue2 recursive component to implement tree menu
  • Learn how to use Vue3 recursive components in 10 minutes

<<:  Detailed explanation of data types and schema optimization in MySQL

>>:  Detailed steps for using jib for docker deployment in Spring Cloud

Recommend

About ROS2 installation and docker environment usage

Table of contents Why use Docker? Docker installa...

Detailed tutorial on Docker pulling Oracle 11g image configuration

Without further ado Start recording docker pullin...

Tomcat source code analysis of Web requests and processing

Table of contents Preface 1. EndPoint 2. Connecti...

Implementation example of JS native double-column shuttle selection box

Table of contents When to use Structural branches...

VMware Workstation download and installation detailed tutorial

Virtual machines are very convenient testing soft...

Implementing a simple student information management system based on VUE

Table of contents 1. Main functions 2. Implementa...

A brief analysis of crontab task scheduling in Linux

1. Create a scheduling task instruction crontab -...

Tomcat components illustrate the architectural evolution of a web server

1. Who is tomcat? 2. What can tomcat do? Tomcat i...

How to implement Mysql scheduled task backup data under Linux

Preface Backup is the basis of disaster recovery....

Introduction to the B-Tree Insertion Process

In the previous article https://www.jb51.net/arti...