Ant-design-pro: 新版本的菜单渲染

Created on 3 Jun 2019  ·  24Comments  ·  Source: ant-design/ant-design-pro

文档中的
(从服务器请求菜单#
只需在 models/menu 中发起 http 请求,menuData 是一个 json 数组。只需服务器返回类似格式的 json 即可。)
(菜单#
菜单根据 router.config.js 生成,具体逻辑在 src/models/menu.js 中的 formatter 方法实现。)
为什么在新版本中找不到menu.js文件

😸Documentation

Most helpful comment

目前我基本已经实现从后台获取menuData进行展示。
第一步:
在models中新建menu文件

import { getMenuData } from '@/services/menu'; // 通过后台返回特定的数组json或者mock模拟数据
import { Reducer } from 'redux';
import { Effect } from './connect';

export interface MenuModelState {
  menuData: any[];
}

export interface MenuModelType {
  namespace: 'menu';
  state: MenuModelState;
  effects: {
    getMenuData: Effect;
  };
  reducers: {
    save: Reducer<MenuModelState>;
  };
}

const MenuModel: MenuModelType = {
  namespace: 'menu',
  state: {
    menuData: [],
  },
  effects: {
    *getMenuData({ payload, callback }, { call, put }) {
      const response = yield call(getMenuData);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback(response);
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        menuData: action.payload || [],
      };
    },
  },
};
export default MenuModel;

第二步:
在layout页面中加载

dispatch({
  type: 'menu/getMenuData',
});

最后一步:不要忘记

export default connect(({ global, settings, menu }: ConnectState) => ({
  collapsed: global.collapsed,
  settings,
  menuData: menu.menuData, // 不要忘记在这里注入
}))(BasicLayout);

目前使用后设置语言就不起作用了,还没找到原因。

All 24 comments

我也在寻找动态加载路由的方式,我尝试在models中新建menu.js,但是失败了,在layout组件中获取不到menuData数组,如果你实现了,希望分享一下,谢谢。

可以看一下这里
https://github.com/ant-design/ant-design-pro-layout#prolayout

layout 支持手工传入 menuData. 想怎么玩怎么玩

手动传入,通过哪个方法传入呢?

可以看一下这里
https://github.com/ant-design/ant-design-pro-layout#prolayout

layout 支持手工传入 menuData. 想怎么玩怎么玩

有没有示例给我们看一下,你说的是menuRender这个属性还是menuItemRender属性

目前我基本已经实现从后台获取menuData进行展示。
第一步:
在models中新建menu文件

import { getMenuData } from '@/services/menu'; // 通过后台返回特定的数组json或者mock模拟数据
import { Reducer } from 'redux';
import { Effect } from './connect';

export interface MenuModelState {
  menuData: any[];
}

export interface MenuModelType {
  namespace: 'menu';
  state: MenuModelState;
  effects: {
    getMenuData: Effect;
  };
  reducers: {
    save: Reducer<MenuModelState>;
  };
}

const MenuModel: MenuModelType = {
  namespace: 'menu',
  state: {
    menuData: [],
  },
  effects: {
    *getMenuData({ payload, callback }, { call, put }) {
      const response = yield call(getMenuData);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback(response);
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        menuData: action.payload || [],
      };
    },
  },
};
export default MenuModel;

第二步:
在layout页面中加载

dispatch({
  type: 'menu/getMenuData',
});

最后一步:不要忘记

export default connect(({ global, settings, menu }: ConnectState) => ({
  collapsed: global.collapsed,
  settings,
  menuData: menu.menuData, // 不要忘记在这里注入
}))(BasicLayout);

目前使用后设置语言就不起作用了,还没找到原因。

目前我基本已经实现从后台获取menuData进行展示。
第一步:
在models中新建menu文件

import { getMenuData } from '@/services/menu'; // 通过后台返回特定的数组json或者mock模拟数据
import { Reducer } from 'redux';
import { Effect } from './connect';

export interface MenuModelState {
  menuData: any[];
}

export interface MenuModelType {
  namespace: 'menu';
  state: MenuModelState;
  effects: {
    getMenuData: Effect;
  };
  reducers: {
    save: Reducer<MenuModelState>;
  };
}

const MenuModel: MenuModelType = {
  namespace: 'menu',
  state: {
    menuData: [],
  },
  effects: {
    *getMenuData({ payload, callback }, { call, put }) {
      const response = yield call(getMenuData);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback(response);
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        menuData: action.payload || [],
      };
    },
  },
};
export default MenuModel;

第二步:
在layout页面中加载

dispatch({
  type: 'menu/getMenuData',
});

最后一步:不要忘记

export default connect(({ global, settings, menu }: ConnectState) => ({
  collapsed: global.collapsed,
  settings,
  menuData: menu.menuData, // 不要忘记在这里注入
}))(BasicLayout);

目前使用后设置语言就不起作用了,还没找到原因。

你那第二步里面的代码可以截图下给我看么,

目前我基本已经实现从后台获取menuData进行展示。
第一步:
在models中新建menu文件

import { getMenuData } from '@/services/menu'; // 通过后台返回特定的数组json或者mock模拟数据
import { Reducer } from 'redux';
import { Effect } from './connect';

export interface MenuModelState {
  menuData: any[];
}

export interface MenuModelType {
  namespace: 'menu';
  state: MenuModelState;
  effects: {
    getMenuData: Effect;
  };
  reducers: {
    save: Reducer<MenuModelState>;
  };
}

const MenuModel: MenuModelType = {
  namespace: 'menu',
  state: {
    menuData: [],
  },
  effects: {
    *getMenuData({ payload, callback }, { call, put }) {
      const response = yield call(getMenuData);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback(response);
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        menuData: action.payload || [],
      };
    },
  },
};
export default MenuModel;

第二步:
在layout页面中加载

dispatch({
  type: 'menu/getMenuData',
});

最后一步:不要忘记

export default connect(({ global, settings, menu }: ConnectState) => ({
  collapsed: global.collapsed,
  settings,
  menuData: menu.menuData, // 不要忘记在这里注入
}))(BasicLayout);

目前使用后设置语言就不起作用了,还没找到原因。

你那第二步里面的代码可以截图下给我看么,
WX20190604-133734@2x

to 楼上:

目前我基本已经实现从后台获取menuData进行展示。
第一步:
在models中新建menu文件

目前使用后设置语言就不起作用了,还没找到原因。

.....



后台返回字段中添加一个 locale字段,为对应的语言key即可

或者修改函数:

effects: {
    *getMenuData({ payload, callback }, { call, put }) {
    },
  },

为:

interface MenuItem {
  name: string;
  path: string;
  icon?: string;
  children?: MenuItem[];
  locale?: string;
}
*getMenuData({ payload, callback }, { call, put }) {
      const response = yield call(getMenuData);
     const localeFunc = (menuList: MenuItem[]): MenuItem[] => {
        menuList.map((item: MenuItem): MenuItem => {
          item.locale = `menu${item.path.replace(RegExp('/', 'g'), '.')}`;
          if (item.children) {
            item.children = localeFunc(item.children);
          }
          return item;
        });
        return menuList;
      };
      yield put({
        type: 'save',
        payload:  localeFunc(response),
      });
      if (callback) callback(response);
    },

坐等开发嵌套菜单API,自己玩翻了还要等 official release

目前我基本已经实现从后台获取menuData进行展示。
第一步:
在models中新建menu文件

import { getMenuData } from '@/services/menu'; // 通过后台返回特定的数组json或者mock模拟数据
import { Reducer } from 'redux';
import { Effect } from './connect';

export interface MenuModelState {
  menuData: any[];
}

export interface MenuModelType {
  namespace: 'menu';
  state: MenuModelState;
  effects: {
    getMenuData: Effect;
  };
  reducers: {
    save: Reducer<MenuModelState>;
  };
}

const MenuModel: MenuModelType = {
  namespace: 'menu',
  state: {
    menuData: [],
  },
  effects: {
    *getMenuData({ payload, callback }, { call, put }) {
      const response = yield call(getMenuData);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback(response);
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        menuData: action.payload || [],
      };
    },
  },
};
export default MenuModel;

第二步:
在layout页面中加载

dispatch({
  type: 'menu/getMenuData',
});

最后一步:不要忘记

export default connect(({ global, settings, menu }: ConnectState) => ({
  collapsed: global.collapsed,
  settings,
  menuData: menu.menuData, // 不要忘记在这里注入
}))(BasicLayout);

目前使用后设置语言就不起作用了,还没找到原因。

老哥 可以看下你ProLayout 里绑定 menuDataRender 怎么绑定的嘛 我按照你的思路把menuData丢进 menuDataRender 会报错 menuDataRender is not a function 似乎他就是需要传入一个方法 而 menuData 是已经处理好的数据
image

menuDataRender对应的渲染函数不变,还是原来BasicLayout的渲染函数menuDataRender.
你这里menuData只是数据,不是函数哇。menuData是BasicLayout自带的props

menuDataRender对应的渲染函数不变,还是原来BasicLayout的渲染函数menuDataRender.
你这里menuData只是数据,不是函数哇。menuData是BasicLayout自带的props

那么我怎么把自带的 props 给截胡掉哇 menuDataRender里的参数我试着自己传也不行

在BasicLayout 里面
const { dispatch } = props;
useState(()=> {
if (dispatch) {
dispatch({
type: 'menu/getMenuData',
});
}
});

在BasicLayout 里面
const { dispatch } = props;
useState(()=> {
if (dispatch) {
dispatch({
type: 'menu/getMenuData',
});
}
});

这个操作我做过了 并且数据已经拿到了 现在我不懂怎么把数据绑定上去😣
image

@Hansuku 标注的地方不需要,如果props中存在menuData就会优先使用这个数据渲染
111

@Hansuku 标注的地方不需要,如果props中存在menuData就会优先使用这个数据渲染
111

emmmm 我按照这个来错是不报了 但是菜单啥都不显示了 我再挣扎一下 不行我用 menuRender 直接写一个了

@Hansuku 看看你menuData输出的数据

@2233322 哈哈哈 你提醒我了 就是数据问题 我的 mock 数据出来不是 json 是字符串

目前我基本已经实现从后台获取menuData进行展示。
第一步:
在models中新建menu文件

import { getMenuData } from '@/services/menu'; // 通过后台返回特定的数组json或者mock模拟数据
import { Reducer } from 'redux';
import { Effect } from './connect';

export interface MenuModelState {
  menuData: any[];
}

export interface MenuModelType {
  namespace: 'menu';
  state: MenuModelState;
  effects: {
    getMenuData: Effect;
  };
  reducers: {
    save: Reducer<MenuModelState>;
  };
}

const MenuModel: MenuModelType = {
  namespace: 'menu',
  state: {
    menuData: [],
  },
  effects: {
    *getMenuData({ payload, callback }, { call, put }) {
      const response = yield call(getMenuData);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback(response);
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        menuData: action.payload || [],
      };
    },
  },
};
export default MenuModel;

第二步:
在layout页面中加载

dispatch({
  type: 'menu/getMenuData',
});

最后一步:不要忘记

export default connect(({ global, settings, menu }: ConnectState) => ({
  collapsed: global.collapsed,
  settings,
  menuData: menu.menuData, // 不要忘记在这里注入
}))(BasicLayout);

目前使用后设置语言就不起作用了,还没找到原因。

好像直接connect menudata之后还得 menuDataRender={ () => menuData } 才可以 不然还是默认走路由生成

方案不成立

menuDataRender={ () => menuData }

对的,需要这一步才可以

事实证明 issue 应该是倒序看 调试半天发现 最后一步才是最关键的

目前我基本已经实现从后台获取menuData进行展示。
第一步:
在models中新建menu文件

import { getMenuData } from '@/services/menu'; // 通过后台返回特定的数组json或者mock模拟数据
import { Reducer } from 'redux';
import { Effect } from './connect';

export interface MenuModelState {
  menuData: any[];
}

export interface MenuModelType {
  namespace: 'menu';
  state: MenuModelState;
  effects: {
    getMenuData: Effect;
  };
  reducers: {
    save: Reducer<MenuModelState>;
  };
}

const MenuModel: MenuModelType = {
  namespace: 'menu',
  state: {
    menuData: [],
  },
  effects: {
    *getMenuData({ payload, callback }, { call, put }) {
      const response = yield call(getMenuData);
      yield put({
        type: 'save',
        payload: response,
      });
      if (callback) callback(response);
    },
  },

  reducers: {
    save(state, action) {
      return {
        ...state,
        menuData: action.payload || [],
      };
    },
  },
};
export default MenuModel;

第二步:
在layout页面中加载

dispatch({
  type: 'menu/getMenuData',
});

最后一步:不要忘记

export default connect(({ global, settings, menu }: ConnectState) => ({
  collapsed: global.collapsed,
  settings,
  menuData: menu.menuData, // 不要忘记在这里注入
}))(BasicLayout);

目前使用后设置语言就不起作用了,还没找到原因。

请问这个方法的服务器菜单支持默认全展开吗?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lvzheng0404 picture lvzheng0404  ·  3Comments

happier2 picture happier2  ·  3Comments

Yoping picture Yoping  ·  3Comments

952425340 picture 952425340  ·  3Comments

yaoleiroyal picture yaoleiroyal  ·  3Comments