zoukankan      html  css  js  c++  java
  • vue之递归组件

    组件通过自身属性name进行递归调用自身组件渲染,

    案例:实现页面tree菜单

    父组件

    <template>
    <div class="home">
        <!-- 首页左侧菜单区域 -->
        <div class="aside">
            <menu-aside :menuData="menuData"></menu-aside>
        </div>
    </div>
    </template>
    <script>
    import MenuAside from './menu/menuAside'
    export default {
        name: 'home',
        data() {
            return {
                menuData: [{//左侧菜单数据
                    name: '布局',
                    id: 'bj',
                    openFlag: false,
                    selectFlag: false,
                    level: 1,
                    children: [{
                        name: '三分布局',
                        id: 'sfbj',
                        openFlag: false,
                        selectFlag: false,
                        level: 2,
                        children: [{
                            name: '三级菜单',
                            id: 'sjcd',
                            openFlag: false,
                            selectFlag: false,
                            level: 3,
                            children: []
                        }]
                    }]
                },{
                    name: '按钮',
                    id: 'an',
                    openFlag: false,
                    selectFlag: false,
                    level: 1,
                    path: '/button',
                    children: []
                }],
            }
        },
        components: {
            MenuAside,//左侧菜单递归组件
        }
    }
    </script>

    子组件(递归组件)

    <template>
    <div class="menuAside">
        <ul>
            <li v-for="(item,index) in menuData" :key="item.id">
                <div :class="['currentMenu',{childrenMenuSelect:item.selectFlag}]" @click="currentMenu(item,index)" >
                    <span class="leftIcon"></span>
                    <!-- item.level*20 通过层级进行层级缩进 -->
                    <span class="centerMenu" :style="{'padding-left': item.level*20 + 'px'}">{{item.name}}</span>
                    <span class="rightIcon" v-if="item.children&&item.children.length!=0">
                        <img src="../../assets/img/shangjiantou.png" alt="" v-if="!item.openFlag">
                        <img src="../../assets/img/jiantou.png" alt="" v-else>
                    </span>
                </div>
                <!-- item.children&&item.children.length!=0&&item.openFlag  通过菜单数据children进行结束递归渲染 -->
                <div class="childrenMenu" v-if="item.children&&item.children.length!=0&&item.openFlag">
                    <menu-aside :menuData="item.children"></menu-aside>
                </div>
            </li>
        </ul>
    </div>
    </template>
    <script>
    export default {
        name: 'menuAside',
        data() {
            return {
                
            }
        },
        props: {
            // 菜单数据
            menuData: {
                type: Array,
                default: [{
                    name: '标准菜单',
                    id: 'bzcd',
                    children: []
                }]
            }
        },
        created() {
    
        },
        methods: {
            /**
             * 点击当前菜单事件
            */
            currentMenu: function(item,index) {
                item.openFlag = !item.openFlag;//菜单层级展开收起
                this.$store.commit('changeMenuEvent',item.id);//通过Vuex进行全局记录当前菜单切换并相应(选中样式渲染)进行操作
                this.$router.push(item.path);//页面路由跳转
            },
            /**
             * 循环重置菜单数据选中状态selectFlag
            */
            cycleMenuData: function(lists) {
                for(let item of lists) {
                    item.selectFlag = false;//清除当前菜单选中样式
                    if(this.$store.state.selectFlag == item.id) {//匹配当前选中菜单并渲染选中样式
                        item.selectFlag = true;
                    }
                    if(item.children&&item.children.length) {//结束循环条件
                        this.cycleMenuData(item.children);
                    }
                }
            },
        },
        watch: {
            /**
             * 通过VUex进行存储,监听左侧菜单切换-进行左侧菜单样式还原,当前活动菜单样式渲染及相关操作
            */
            '$store.state.changeMenuFlag'(val) {
                this.cycleMenuData(this.menuData);
            }
        },
    }
    </script>

    通过Vuex进行菜单切换变量管理,解决菜单点击时样式渲染问题

    import Vue from 'vue';
    import Vuex from 'vuex';
    Vue.use(Vuex);
    const store = new Vuex.Store({
        state: {
            changeMenuFlag: false,//标记菜单切换进行菜单切换监听
            selectFlag: null,//当前活动菜单id
        },
        mutations: {
            /**
             * 菜单切换事件
            */
            changeMenuEvent: function(state,item) {
                state.changeMenuFlag = !state.changeMenuFlag;//菜单切换标记
                state.selectFlag = item;//当前活动菜单id
            }
        }
    })
    export default store

    实现效果

  • 相关阅读:
    Python爬虫开源项目代码,爬取微信、淘宝、豆瓣、知乎、新浪微博、QQ、去哪网等 代码整理
    python ---split()函数讲解
    常见的操作系统及linux发展史
    第五次作业
    第四次软件工程作业
    软件工程——第三次作业
    软件工程--第二次作业
    软件工程--第一次作业
    在SQL Server中调用.NET程序集
    c#中使用ABCpdf处理PDF,so easy
  • 原文地址:https://www.cnblogs.com/emilyzz/p/14251133.html
Copyright © 2011-2022 走看看