Vue component recursion (vue implements multi-level menu rendering through component recursion)

If the number of menu nesting levels is known, the menu to be rendered can be looped through v-for, but if we don’t know how many levels of sub-menus we need to loop, then v-for cannot solve the problem at this time

To achieve dynamic rendering, we don’t know how many layers of menu data we get. There are two solutions:

  • Operate dom to add sub-menus layer by layer (vue does not recommend operating dom, so this solution is not recommended)
  • Encapsulate our menu into components, and implement menu rendering through recursive components

First post a demo
demo address : https://download.csdn.net/download/qq_25992675/12853870

  1. Dynamic rendering menu
  2. You can load the submenu by clicking the menu rendering

Insert picture description here

In fact, component recursion is very simple. You don’t need to register yourself when calling yourself in a component. You only need to call yourself in the form of a label on the page through the component’s name.


Recursive use of components

Here only paste code fragment is used mainly describes the components of recursion, you may want to see the complete demo carrier demo

Component declaration

important point:

  1. Menu: the name of the component, you can call yourself by using the defined name: "Menu" as the label
  2. The @click.stop attribute should be added to the component to prevent the parent menu click event from being triggered when the submenu or blank part is clicked
  3. Because my menu has its own selected style, there are some ternary judgments on the class, which can be defined according to your own needs.
<template>
<div class="menu" @click.stop>
    <div v-for="(item, index) in menuList" :key="index" @click.stop :class="menu-item" @click="chooseMenu(index, item)">
        <span :class="item.checkIndex == index ? 'name choose-item' : 'name'">{
    
    {
    
    
        item.name
      }}</span>
        <span :class="item.checkIndex == index ? 'index choose-item' : 'index'">
            {
    
    {
    
     index + 1 }}
        </span>
        <Menu class="menu-children" :menuList="item.childrens" @back="back(index, $event)"></Menu>
    </div>
</div>
</template>

<script>
export default {
    
    
    name: "Menu",
    props: {
    
    
        menuList: Array,
    },
    methods: {
    
    
        /**
         * @author: yx
         * @method: 选择菜单,返回菜单信息以及列下标
         * @Date: 2020-09-17 10:40:18
         */
        chooseMenu(index, item) {
    
    
            let child = {
    
    
                index: [index],
                item,
            };
            this.$emit("back", child);
        },
        /**
         * @author: yx
         * @method: 向上次依次返回选择的菜单信息以及列下标
         * @Date: 2020-09-17 10:40:27
         */
        back(index, event) {
    
    
            event.index.push(index);
            this.$emit("back", event);
        },
    },
};
</script>

Component call

important point:

  1. Because the style needs to be changed each time the selection is made, but the recursive component cannot update the dom immediately after changing the value of menList, so here I define a refresh, and refresh the component through refresh
<template>
	<div class="home">
	    <Menu v-if="refresh" :menuList="menuList" @back="back($event)"></Menu>
	</div>
</template>

<script>
import Menu from "../components/menu";
export default {
    
    
  name: "Home",
   data() {
    
    
        return {
    
    
            refresh: true,
            menuList: [{
    
    
                id: 1,
                name: "测试",
                checkIndex: 0,
                isFirst: true,
                childrens: [{
    
    
                   id: 2,
                    name: "测试1级1",
                    checkIndex: 0,
                    childrens: [{
    
    
                        id: 6,
                         name: "测试2级1",
                         checkIndex: 2,
                         childrens: [],
                     },
                     {
    
    
                        id: 7,
                         checkIndex: 2,
                         name: "测试2级2",
                         childrens: [],
                     }],
                 }],
            }],
            nowIndex: 0,
            columnIndex: [], // 列下标
        };
    },
    methods:{
    
    
    	 back(item) {
    
    }
    }
     components: {
    
    
        Menu,
    }
};
</script>

Guess you like

Origin blog.csdn.net/qq_25992675/article/details/108645333