ext 实现一个鼠标滑过弹出 子菜单面板

本文介绍如何在ExtJS中实现自定义的镜像菜单功能。通过使用border布局及Ext.tree.Panel组件,并结合自定义的CloneMenuListView组件,实现了菜单的动态加载与展示。文章详细介绍了组件间的交互逻辑与菜单的渲染过程。
摘要由CSDN通过智能技术生成

1,效果如下


2,思路

页面使用了 border 布局 

west 就是 菜单所在的区域 使用 fit 布局 这样就只会显示第一个子元素

其实有两个 子元素

第二个 子元素 是一个 默认的 Ext.tree.Panel 给它设置一个 autoLoad 的 store 获取菜单的数据 

west 的第一个组件 也就是 给用户看的这个组件 我叫它镜像菜单 

当 treePanel 获取到数据之后 将 镜像菜单的 viewModel 中的默认数据更新 成 treePanel 的数据 然后 让镜像菜单重新渲染即可

接下来 基本就和treePanel 没什么关系了

在 镜像菜单的  initComponent 方法中 获取自己的 viewModel 的数据 渲染成菜单的样子即可 具体怎么渲染就是一下布局 一些事件了

通过 监听 mouseover 事件 触发滑动 

调用 menushow 方法 显示 子菜单面板

子菜单面板的点击事件 触发路由 加上想要的参数 就完成跳转了 然后在 路由事件中做一下对应的操作 比如生成新的 tab 页面等等 我的是跳到指定的 tab 页面

3,主要代码

Ext.define('app.view.main.Main', {
    extend: 'Ext.Container',
    xtype: 'app-main',

    requires: [
        'Ext.window.MessageBox',
        'app.view.main.MainController',
        'app.view.main.MainModel',
        'app.view.main.CloneMenuListView',
        'app.view.main.TrueMenuListView',
        'app.view.main.CenterContainer'
    ],

    layout: {
        type: 'border'
    },

    controller: 'main',
    viewModel: 'main',

    items: [
        {
            region: 'north',
            height: 60,
            style: {
                border: 0,
                borderBottom: '1px solid #ddd'
            },
            layout: {
                type: 'fit'
            },
            items: [
                {
                    xtype: 'button',
                    text: '自定义镜像菜单',
                    handler: 'headerBtnClick'
                }
            ]
        },
        {
            region: 'west',
            xtype: 'panel',
            title: '自定义菜单',
            style: {
                borderRight: '1px solid #eee'
            },
            reference: 'west',
            width: 150,
            layout: {
                type: 'fit'
            },
            items: [
                //{
                //    xtype:'trueMenuListView'
                //},
                {
                    xtype: 'cloneMenuListView'
                },
                {
                    xtype: 'trueMenuListView'
                }
            ]

        },
        {
            region: 'center',
            xtype: 'center-container'
        }
    ]
});


/**
 * Created by Sukla on 2017/11/24.
 */
Ext.define('app.view.main.TrueMenuListView', {
    extend: 'Ext.tree.Panel',
    alias: 'widget.trueMenuListView',
    reference: 'trueMenuListView',

    requires: [
        'Ext.data.TreeStore'
    ],
    rootVisible: false,
    useArrows: true,

    width: 150,
    store: Ext.create('app.store.TrueMenuListStore'),

    viewConfig: {
        listeners: {
            render: 'trueMenuRender'

        },
        getRowClass: function (record, rowindex, rowParams, store) {
            debugger;
            this.getRefOwner().getRefOwner().down('cloneMenuListView').getViewModel().set('arr',store.data.items);
            this.getRefOwner().getRefOwner().down('cloneMenuListView').initComponent();
        }
    }
})


/**
 * Created by Sukla on 2017/11/24.
 */
Ext.define('app.view.main.CloneMenuListView', {
    extend: 'Ext.Container',
    alias: 'widget.cloneMenuListView',
    reference: 'cloneMenuListView',

    width: 150,
    layout: {
        type: 'vbox'
    },
    cls: 'my-menu-contanier',
    defaults: {
        xtype: 'button',
        cls: 'myself-menu',
        overCls: 'myself-over-menu',
        listeners: {
            mouseover: 'myselfMenuOver'
        },
        width: 150,
        height: 34,
        style: {
            border: 0,
            margin: 0,
            padding: 0
        },
        menuAlign: 'tr'
    },
    viewModel: {
        data: {
            arr: [
                //{
                //    data:{
                //        allowDrag: true,
                //        allowDrop: true,
                //        checked: null,
                //        children: null,
                //        cls: "",
                //        depth: 2,
                //        expandable: true,
                //        expanded: false,
                //        glyph: "",
                //        href: "",
                //        hrefTarget: "",
                //        icon: "",
                //        iconCls: "",
                //        id: "demo",
                //        index: 0,
                //        isFirst: true,
                //        isLast: false,
                //        leaf: true,
                //        loaded: false,
                //        loading: false,
                //        parentId: "parent-tree-a",
                //        qshowDelay: 0,
                //        qtip: "",
                //        qtitle: "",
                //        root: false,
                //        text: "子菜单A",
                //        visible: true
                //    }
                //}

            ]
        }
    },

    initComponent: function () {
        debugger;
        var arr = this.getViewModel().get('arr');
        this.items = [];
        for (var i = 0; i < arr.length; i++) {
            var item = {};
            var menuItems = [];


            if (arr[i].data.children) {
                var children = arr[i].data.children;
                for (var j = 0; j < children.length; j++) {
                    var menuItem={
                        items:[]
                    }
                    //判断二级菜单是否叶子节点 从而准备不同的渲染组件
                    if(children[j].leaf){

                    }else{
                        var leafItems=[];
                        if(children[j].children){
                            var leafChild=children[j].children;
                            for(var k=0;k<leafChild.length;k++){
                                leafItems.push({
                                    itemId: leafChild[k].id,
                                    text:leafChild[k].text
                                })
                            }
                        }
                        menuItem.items.push({
                            width: 100,
                            html: children[j].text
                        });
                        menuItem.items.push( {
                            flex: 1,
                            layout: {
                                type: 'table',
                                columns: 5
                            },
                            defaults: {
                                xtype: 'button',
                                width: 70,
                                height: 40,
                                margin: 5,
                                text: '子菜单',
                                handler: "onMyMenuSelecte"
                            },
                            items: leafItems
                        })
                    }
                    menuItems.push(menuItem)
                }
            }
            var menus = [
                {
                    xtype: 'panel',
                    padding: 0,
                    margin: 0,
                    border: '1px solid #00f',
                    width: 500,
                    minHeight: 50,
                    layout: {
                        type: 'vbox',
                        align: 'stretch'
                    },
                    defaults: {
                        layout: {
                            type: 'hbox',
                            align: 'stretch'
                        }
                    },
                    items: menuItems
                }
            ];

            //一级菜单
            item.text = arr[i].data.text;
            //二级菜单
            item.menu = menus;
            this.items.push(item)
        }

        //this.items = [
        //    {
        //        text: '交易管理',
        //        menu: [
        //            {
        //                xtype: 'panel',
        //                padding: 0,
        //                margin: 0,
        //                border: '1px solid #00f',
        //                width: 500,
        //                minHeight: 50,
        //                layout: {
        //                    type: 'vbox',
        //                    align: 'stretch'
        //                },
        //                defaults: {
        //                    layout: {
        //                        type: 'hbox',
        //                        align: 'stretch'
        //                    }
        //                },
        //                items: [
        //                    {
        //                        items: [
        //                            {
        //                                width: 100,
        //                                html: '二级菜单'
        //                            },
        //                            {
        //                                flex: 1,
        //                                layout: {
        //                                    type: 'table',
        //                                    columns: 3
        //                                },
        //                                defaults: {
        //                                    xtype: 'button',
        //                                    width: 70,
        //                                    height: 40,
        //                                    margin: 5,
        //                                    text: '子菜单',
        //                                    handler: "onMyMenuSelecte"
        //                                },
        //                                items: [
        //                                    {
        //                                        itemId: 'menu-001'
        //                                    }
        //                                ]
        //                            }
        //                        ]
        //                    },
        //                    {
        //                        items: [
        //                            {
        //                                width: 100,
        //                                html: '二级菜单'
        //                            },
        //                            {
        //                                flex: 1,
        //                                layout: {
        //                                    type: 'table',
        //                                    columns: 3
        //                                },
        //                                defaults: {
        //                                    xtype: 'button',
        //                                    width: 70,
        //                                    height: 40,
        //                                    margin: 5,
        //                                    text: '子菜单',
        //                                    handler: "onMyMenuSelecte"
        //                                },
        //                                items: [
        //                                    {
        //                                        itemId: 'menu-0011'
        //                                    },
        //                                    {
        //                                        itemId: 'menu-0011'
        //                                    },
        //                                    {
        //                                        itemId: 'menu-0012'
        //                                    },
        //                                    {
        //                                        itemId: 'menu-0013'
        //                                    },
        //                                    {
        //                                        itemId: 'menu-0014'
        //                                    },
        //                                    {
        //                                        itemId: 'menu-0015'
        //                                    },
        //                                    {
        //                                        itemId: 'menu-0016'
        //                                    },
        //                                    {
        //                                        itemId: 'menu-0017'
        //                                    },
        //                                    {
        //                                        itemId: 'menu-0018'
        //                                    }
        //                                ]
        //                            }
        //                        ]
        //                    }
        //                ]
        //            }
        //        ]
        //    }
        //];
        this.callParent();
    }

})

Ext.define('app.view.main.MainController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.main',
    headerBtnClick: function () {
        debugger;
    },
    trueMenuRender:function(){
    },
    myselfMenuOver:function(btn){
        btn.showMenu();
    },

    routes: {
        ':id': {
            action: 'handleRoute',//执行跳转
            before: 'beforeHandleRoute'//路由跳转前操作
        }
    },

    /**
     * 路由跳转前的事件
     * @param id
     * @param action
     */
    beforeHandleRoute: function (id, action) {
//        var me = this,
//            treeNav = me.lookupReference('lefttreelistnav'),
//            store = treeNav.getStore(),
//            treeNavItem = store.getNodeById(id);
//        if (treeNavItem) {
        action.resume();
//        } else if (store.getCount() === 0) {
//            // store load事件中判断节点,避免store数据未加载情况
//            store.on('load', function () {
//                var rootNode = treeNav.getRootNode();
//                if (rootNode.hasChildNodes()) {
//                    rootNode.expand();
//                }
//                node = store.getNodeById(id);
//                if (node) {
//                    action.resume();
//                } else {
//                    //Ext.Msg.alert('路由跳转失败1', '找不到id' + id + ' 的组件');
//                    action.stop();
//                }
//            });
//            store.load();
//        } else {
         Ext.Msg.alert('路由跳转失败21', store.getCount());
         Ext.Msg.alert('路由跳转失败2', '找不到id' + id + ' 的组件');
//            action.stop();
//        }
    },

    /**
     * 执行路由
     * @param id
     */
    handleRoute: function (id) {
        var me = this,
        //    mainView = me.getView(),
        //    treeNav = me.lookupReference('lefttreelistnav'),
            centerContainer = me.lookupReference('centerContainer');
        //    store = treeNav.getStore(),
        //    treeNavItem = store.getNodeById(id),
        //    className, cmp, ViewClass;
        //
        响应路由,左侧树定位到相应节点
        var parentNode = treeNavItem.parentNode;
        treeNav.getSelectionModel().select(treeNavItem);
        treeNav.getView().expand(parentNode);
        treeNav.getView().focusNode(treeNavItem);
        //
        if (treeNavItem.isLeaf()&&treeNavItem.get('resLevel')==2) {
        //if (treeNavItem.isLeaf()) {
        me.addTabPanel(centerContainer, id, 'centerContainer');
        //}
    },

    /**
     * 根据点击的菜单显示相应内容页
     * @param targetPanel
     * @param treeNavItem
     * @param targetPanelStr
     */
    addTabPanel: function (targetPanel, treeNavItem, targetPanelStr) {
        var newTab = targetPanel.items.findBy(function (tab) {
            return tab.title === treeNavItem;
        });

        if (!newTab) {
            var tabObject = {
                xtype: 'panel',
                closable: true,
                title: treeNavItem
                //className: treeNavItem.get('id'),
                //resParams: treeNavItem.get('id'),
                //resId: treeNavItem.get('id')
            };
            //if (treeNavItem.get('resUri') === 'reportquery') {// 报表查询特殊处理
            //    tabObject.itemId = treeNavItem.get('id');
            //    tabObject.targetPanel = 'mainpanel';
            //}
            newTab = targetPanel.add(tabObject);
        }
        targetPanel.setActiveTab(newTab);
    },


    onMyMenuSelecte: function (selecteMenu) {
        this.redirectTo(selecteMenu.itemId);
    }


});

4,css

.my-menu-contanier,.myself-menu{
    background:#7b7b7b!important;
}
.myself-menu{
    border-bottom:1px solid #9b9b9b!important;
    font-size: 16px!important;
}
.myself-over-menu{
    background:rgba(0, 130, 223, 1)!important;
}

5,store 

/**
 * Created by Sukla on 2017/11/24.
 */
Ext.define('app.store.TrueMenuListStore', {
    extend: 'Ext.data.TreeStore',
    alias: 'store.trueMenuListStore',
    autoLoad:true,
    proxy: {
        type: 'ajax',
        url: 'resources/data/trueMenuListJson.json'
    },
    root: {
        text: 'Ext JS',
        id: 'src',
        expanded: true
    },
    folderSort: true,
    sorters: [{
        property: 'text',
        direction: 'ASC'
    }]
});
6,json

[
  {
    id:'jygl',
    text:"权限管理",
    expanded:false,
    iconCls: 'x-fa fa-home',
    children:[
      {
        id:'xhzy',
        text:"管理员",
        children:[
          {
            id:'spfb',
            text:"一级管理员",
            leaf:true
          }
        ]
      },
      {
        id:'xsdd',
        text:"维护",
        children:[
          {
            id:'xjdd',
            text:"A",
            leaf:true
          },
          {
            id:'ddgl',
            text:"B",
            leaf:true
          },
          {
            id:'ddgz',
            text:"C",
            leaf:true
          },
          {
            id:'ddsp',
            text:"D",
            leaf:true
          }
        ]

      },
      {
        id:'xsht',
        text:"Vip",
        children:[
          {
            id:'htgl',
            text:"Vip001",
            leaf:true
          },
          {
            id:'htgz',
            text:"Vip002",
            leaf:true
          },
          {
            id:'htsp',
            text:"Vip003",
            leaf:true
          },
          {
            id:'htqz',
            text:"Vip004",
            leaf:true
          },
          {
            id:'bgxygl',
            text:"Vip005",
            leaf:true
          }
        ]

      }
    ]
  },
  {
    id:'khgl',
    text:"角色管理",
    expanded:false,
    iconCls: 'x-fa fa-home',
    children:[
      {
        id:'khglc',
        text:"老师",
        children:[
          {
            id:'wdkk',
            text:"其它老师",
            leaf:true
          },
          {
            id:'khda',
            text:"体育老师",
            leaf:true
          }
        ]
      },
      {
        id:'lfgl',
        text:"学生",
        children:[
          {
            id:'lfsq',
            text:"小学生",
            leaf:true
          },
          {
            id:'lfkjsp',
            text:"中学生",
            leaf:true
          },
          {
            id:'lfbjsp',
            text:"大学生",
            leaf:true
          },
          {
            id:'lfbglr',
            text:"研究生",
            leaf:true
          },
          {
            id:'lfcx',
            text:"博士生",
            leaf:true
          }
        ]
      }
    ]
  }
]

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值