ant-design / ant-design-pro

👨🏻‍💻👩🏻‍💻 Use Ant Design like a Pro!
https://pro.ant.design
MIT License
36.35k stars 8.14k forks source link

Ant Design Pro V5 已经支持预览 #6605

Closed chenshuai2144 closed 3 years ago

chenshuai2144 commented 4 years ago

在经过了很长时间的准备下,Pro V5 已经基本完成, 但是仍然有很多地方不是很完善,在新版本中我们进行了很多预设,对于数据流和布局更是进行了大刀阔斧的改进。虽然底层仍然基于 umi@3 来实现的,但是在应用层做了很多改动,接下来我们会展示一下我们的主要改动。

🦚 Layout 的更新

layout 是这次的最大改动,首先是进行了样式上的更新,支持混合模式来期望适应更多的场景。新的风格仍然会以科技的风格为主,在原来的基础上优化尺寸和体验细节,设计更加简洁,匹配更多业务场景,具体的改动可以看这里

img

对于开发者也迎来了很多改动,

对于  SettingDrawer,为了方便集成和部署,我们开发了 umi-plugin-setting-drawer ,只要在项目中安装这个即可快速使用。

umi-plugin-setting-drawer 依赖  @umijs/plugin-initial-state@umijs/plugin-layout, 如果要自己实现需要自动绑定 @umijs/plugin-initial-state 中的数据。

🏟  架构改动

Pro V5 中的架构做了全新的改动,全部修改为全新的 umi@3 架构, 对于数据流,权限,布局都进行了内置,修改为了全新的插件。这些改进都是渐进式的,只要你升级为 umi@3 ,是可以兼容两种开发模式的。

🌊 数据流方案

我们在过去尝试了很多数据流方案,并且随着 dva 的出现稳定了下来,但是在 hooks 到来之后我们看到了机会来解决 dva 实践中遇到的问题。在一个标准的 dva 应用中我们需要写很多的样板文件,做了很多重复劳动。尤其是 它有很多概念,effectsstate , reducers ,为了解决异步的问题又带了很多的新的 api,构建了一个非常复杂的体系,但是在很多应用中其实是不需要这个复杂的功能,而且即使是很大的项目,他对 TypeScript 不友好的问题也导致我们在使用时各种链路不同,并且没有良好的类型指示,在重构时经常需要搜来搜去而不能的跳转。 @umijs/plugin-model 解决了上述的 dva 的问题,同时也足够小,使用者书写的就是一个普通的自定义 hooks,但 @umijs/plugin-model 把其中的状态变成了『全局状态』,多个组件中使用该 model 时,拿到的同一份状态。没有更多的心智负担。使用起来就像定义一个 state 那么简单。我们可以在新建一个 src/models/user.ts  文件。

import { useState, useCallback } from 'react';

export default function useAuthModel() {
  const [user, setUser] = useState(null);

  const signout = useCallback(() => {
    // signout implementation
    setUser(null);
  }, []);

  return {
    user,
    signout,
  };
}

在使用时也会非常简单,使用应用 hooks 即可, 这样使用包含了所有的 TypeScript 信息, useModel  的 key 就是在 models  中的文件名。

import { useModel } from 'umi';

const { user, signout } = useModel('user');

对于轻量级的数据流我们都推荐这种方案。

🔐 权限方案

权限一直时 Pro 的弱项,在 Pro 中我们自研了一个权限组件但是表现不尽如人意。趁着这次机会我们升级了权限组件,无论使用方式和 API 都变得更加的简单,并且和我们的插件结合的更加完美。光商业吹捧是没有意义的,我们来看看代码。

// src/access.ts
export default function (initialState: { currentUser?: API.CurrentUser | undefined }) {
  const { currentUser } = initialState || {};
  return {
    canAdmin: currentUser && currentUser.access === 'admin',
    canDeleteFoo: (foo) => {
      return foo.ownerId === currentUser.userId;
    },
  };
}

我们可以看到这个是非常简单的,initialState  是一个默认的 model , 每次  initialState  的改变都会触发权限的重新计算,我们可以像 setState 一样触发它。在使用上我们使用了 umi@3 的能力让我们用起来更加的简单,只要在 root 中做如下配置,对于不能访问的页面,插件会将其替换为 403 页面,而无需手动支持。

export const routes = [
  {
    path: '/pageA',
    component: 'PageA',
    access: 'canAdmin', // 权限定义返回值的某个 key
  },
];

对于运行时的代码,我们提供了两个 API 来帮助我们自定义任何形态的 UI 和逻辑, 这里有个一看就懂的 demo。

import React from 'react';
import { useAccess, Access } from 'umi';

const PageA = (props) => {
  const { foo } = props;
  const access = useAccess(); // access 的成员: canAdmin

  if (access.canReadFoo) {
    // 如果可以读取 Foo,则...
  }

  return (
    <div>
      <Access accessible={access.canAdmin} fallback={<div>Can not read foo content.</div>}>
        Foo content.
      </Access>
      <Access accessible={access.canDeleteFoo(foo)} fallback={<div>Can not delete foo.</div>}>
        Delete foo.
      </Access>
    </div>
  );
};

🎯  网络请求

request 是新架构中的大改变之一,我们可以从 umi 中 import request 使用方式与原来相同,各种配置可以在 src/app.tsx 中进行配置。代码示例如下:

import { RequestConfig } from 'umi';

export const request: RequestConfig = {
  timeout: 1000,
  errorConfig: {},
  middlewares: [],
  requestInterceptors: [],
  responseInterceptors: [],
  errorHandler,
};

在一个中后台中很多页面并不需要跨页面的信息流,也不需要把信息放入 model 中,所以我们提供了  useRequest  hooks, useRequest 提供了一些快捷的操作和状态,可以大大的节省我们的代码。

🛫  如何升级到 umi@3 架构

既然新的架构这么优秀,那么怎么才能升级到新的架构呢,我们是支持渐进的,只要升级到 umi@3 即可使用这些特性,新的数据流虽然简单高效但是并不能满足所有的场景,我们可以混合适应,慢慢迁移。当然我们希望可以尽早迁移来减少历史债务。详细步骤可以参阅官网的迁移指南

详细的代码改动

🗽 Q&A

📮  为什么不发正式版

Pro v5 中使用了全新的架构,更加标准化并且自带了很多内部的最佳实践,无论代码量还是使用难度都降低了。但是标准化同时意味着失去了个性化的空间,我们希望在正式发布之前,收集一些信息,在标准化和个性化之前取得一个平衡。

📮 Pro 与 umi 是什么关系

Pro 与 umi 的关系有点像  react-scripts  与 create-react-app ,umi 提供了基础能力,而 Pro 在上层提供了更多用法,并且加入了我们对中后台项目的实践。

📮 Pro V5 不能满足我的需求怎么办

作为一个开源项目,如果你觉得某个功能不满意或者功能缺失,你可以提 issue 来参与讨论,如果得到了官方的认可,那么这个功能就会被实现。这个流程一般会很长,所以推荐你直接提 PR 来实现功能,同时可以帮助到更多同学,成为一名光荣的  contributors,走向名望程序员第一步。

如何使用

使用 yarn create umi 0.24.x 版本。出现 🧙 Be the first to experience the new umi@3 ? 时选择 PRO V5 image

参考资料

官网 https://beta-pro.ant.design umi 插件文档 https://umijs.org/plugins/plugin-access

chz102 commented 4 years ago

@chenshuai2144 左侧菜单和右侧头部的分割线shadow没有出来,连载一块儿了,不太美观 另外,本地如何把切换主题的功能放出来?

joesdu commented 4 years ago

@chenshuai2144 左侧菜单和右侧头部的分割线shadow没有出来,连载一块儿了,不太美观 另外,本地如何把切换主题的功能放出来? 本地切换主题的那个插件我试用了一下,感觉效果很不理想.官方估计还在修.

yikyo commented 4 years ago

最近刚开的项目,不小心用到了V5版本(没显示测试版!!!!),已经上线了,有个问题请帮忙解决下,histroy hash模式下,菜单选中状态及二级标题显示不正确。

@chenshuai2144 大佬。。。产品那边我交待不过去。。

admiao commented 4 years ago

PRO 就是 蚂蚁前端圈的集合, 如果跳出来做可能对他们的意义就不大了吧 , 起初写一些小练习 觉得dva 是非常棒的 但随着业务的增加,越来越觉得难用,至于umi 从来就没看出有什么好处

chz102 commented 4 years ago

@chenshuai2144 大神,这个版本有没有个正式发布时间的预期啊,现在有个新的项目,有点纠结要不要用V5

joesdu commented 4 years ago

@chenshuai2144 大神,这个版本有没有个正式发布时间的预期啊,现在有个新的项目,有点纠结要不要用V5

感觉可以上,但是要留意官方的改动,及时跟进应该问题就不大.

joesdu commented 4 years ago

PRO 就是 蚂蚁前端圈的集合, 如果跳出来做可能对他们的意义就不大了吧 , 起初写一些小练习 觉得dva 是非常棒的 但随着业务的增加,越来越觉得难用,至于umi 从来就没看出有什么好处

umi的话主要是帮忙处理了大量webpack的东西.我反正不会用webpack,整的头昏脑胀的.

quoyi commented 4 years ago

我就说怎么感觉就像个菜鸡作品,完全不符合 stars 该有的代码质量,都打算退回 create-react-app 了,原来是打开方式错了(选的 V4 ,手动泪奔~)一个配置文件全被 routes 占了,独立出来很难吗?就用了 uniq 和 groupBy 有必要在 dependencies 引入整个 lodash ?

joesdu commented 4 years ago

我就说怎么感觉就像个菜鸡作品,完全不符合 stars 该有的代码质量,都打算退回 create-react-app 了,原来是打开方式错了(选的 V4 ,手动泪奔~)一个配置文件全被 routes 占了,独立出来很难吗?

官方只是自己写了个简单的例子,自己弄出来就好了.

kaoding commented 4 years ago

我就说怎么感觉就像个菜鸡作品,完全不符合 stars 该有的代码质量,都打算退回 create-react-app 了,原来是打开方式错了(选的 V4 ,手动泪奔~)一个配置文件全被 routes 占了,独立出来很难吗?

如果不好,你可以提PR?开源你免费使用,没有一点开源精神,还说风凉话的,你牛,你自己写一个不是菜鸡的东西出来啊!早退回早好,走好,不送。

quoyi commented 4 years ago

我就说怎么感觉就像个菜鸡作品,完全不符合 stars 该有的代码质量,都打算退回 create-react-app 了,原来是打开方式错了(选的 V4 ,手动泪奔~)一个配置文件全被 routes 占了,独立出来很难吗?

官方只是自己写了个简单的例子,自己弄出来就好了.

嗯,已经自己切割出来 import [].concat(routes) 了,就是表述了一下直观感觉。也不是说要贬低作者,没有精益求精的精神还叫高手吗?个人从不盲目崇拜,谢谢。

quoyi commented 4 years ago

我就说怎么感觉就像个菜鸡作品,完全不符合 stars 该有的代码质量,都打算退回 create-react-app 了,原来是打开方式错了(选的 V4 ,手动泪奔~)一个配置文件全被 routes 占了,独立出来很难吗?

如果不好,你可以提PR?开源你免费使用,没有一点开源精神,还说风凉话的,你牛,你自己写一个不是菜鸡的东西出来啊!早退回早好,走好,不送。

哟,还有人来咬嗦?我不是高手,但是起码有良好的编码习惯,以及独立思考的能力。不好的地方还不让人指出来了?已经弃坑,谢谢。

kaoding commented 4 years ago

image

kaoding commented 4 years ago

感觉 v5 可以正式发布了,让用户早点使用起来才是王道。

admiao commented 4 years ago

@chenshuai2144 在dark 主题下有点丑,异步数据写到数据流中怎么写啊,权限方案的和V4没多大区别啊 ,当角色是用户自定义的话...

kaoding commented 4 years ago

关于 layout="mix" 的建议

liujiayii commented 4 years ago

关于 layout="mix" 的建议

  • 问题:现有的 mix 还是和 side 模式差不多,只是将 title 和 logo 放到 header 上,在menu留了一块可以自定义的块(menuExtraRender),还存在不太灵活的问题(如:在dark模式下,左侧和顶部都是暗黑颜色,在light模式下,顶部还是暗黑颜色)。
  • 想法:既然是叫 mix 模式,更多是将 side 和 top 模式结合现来,才能体现出mix的强大和更加实际的用途。我的想法是,使用 mix 模式是由业务模式来决定的,解决的是复杂业务(按菜单业务分类)的情况才摧荐使用的一种模式,希望可以在 top 上有菜单 ,在 side 上也有菜单,其中 top 的 菜单是主控菜单,side 的 菜单是根据 top 的菜单来变化的被控菜单(或者叫子菜单)。
  • 实现:在config.ts里的routes里做文章,现在已经加了一个menu:{name="",...},是否可以再加一个mode,mode=top、mode=side代表顶部菜单、左侧菜单。默认显示top菜单、side菜单默认是不显示(可以选择一组为默认显示),选择了top菜单后,side的菜单相应变化。(注:top和side同时存在菜单,现有的做法是layout内再套一个layout)

还有个问题mix模式下展开的菜单页面刷新后菜单被折叠了

infinityboy commented 4 years ago

+1 表示已经上v5了,antd4.x、umi 3.x 、pro-layout6.x

请教一下 ts的request 拦截器部分 怎么做的?

joesdu commented 4 years ago

+1 表示已经上v5了,antd4.x、umi 3.x 、pro-layout6.x

请教一下 ts的request 拦截器部分 怎么做的?

import { RequestConfig, history } from 'umi';
import Cookies from 'js-cookie';
import React from 'react';
import { notification } from 'antd';
//#region Request配置
/**
 * CodeMessage
 */
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  405: '请求方法不被允许。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。'
};

/**
 * 运行时request配置
 */
export const request: RequestConfig = {
  timeout: 10000,
  // 当接口规范时,采用配置errorHandler的方式来实现错误提示.
  errorHandler: (error: { response: Response }) => {
    const { response } = error;
    if (response && response.status) {
      const errorText = codeMessage[response.status] || response.statusText;
      const { status, url } = response;
      notification.error({ message: `请求错误 ${status}: ${url}`, description: errorText });
    }
    if (!response) {
      notification.error({ description: '您的网络发生异常,无法连接服务器', message: '网络异常' });
    }
    throw error;
  },
  // 当接口不规范时,采用配置errorConfig的方式来实现错误提示.
  errorConfig: {
    adaptor: (res: any) => {
      return {
        ...res,
        success: res.ok || res.Success || res.success,
        errorMessage: res.message || res.msg || res.Message
      };
    },
    errorPage: '1'
  },
  prefix: 'http://localhost:5000/api/',
  // 中间件
  middlewares: [],
  // 请求拦截器
  requestInterceptors: [
    (url: string, options) => {
      options.headers = { Authorization: `Bearer ${Cookies.get('accessToken') ?? ''}` };
      return { url, options };
    }
  ],
  // 响应拦截器
  responseInterceptors: []
};
//#endregion
admiao commented 4 years ago

哪位大佬说一下useModel如何替换dva的

infinityboy commented 4 years ago

+1 表示已经上v5了,antd4.x、umi 3.x 、pro-layout6.x

请教一下 ts的request 拦截器部分 怎么做的?

import { RequestConfig, history } from 'umi';
import Cookies from 'js-cookie';
import React from 'react';
import { notification } from 'antd';
//#region Request配置
/**
 * CodeMessage
 */
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  405: '请求方法不被允许。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。'
};

/**
 * 运行时request配置
 */
export const request: RequestConfig = {
  timeout: 10000,
  // 当接口规范时,采用配置errorHandler的方式来实现错误提示.
  errorHandler: (error: { response: Response }) => {
    const { response } = error;
    if (response && response.status) {
      const errorText = codeMessage[response.status] || response.statusText;
      const { status, url } = response;
      notification.error({ message: `请求错误 ${status}: ${url}`, description: errorText });
    }
    if (!response) {
      notification.error({ description: '您的网络发生异常,无法连接服务器', message: '网络异常' });
    }
    throw error;
  },
  // 当接口不规范时,采用配置errorConfig的方式来实现错误提示.
  errorConfig: {
    adaptor: (res: any) => {
      return {
        ...res,
        success: res.ok || res.Success || res.success,
        errorMessage: res.message || res.msg || res.Message
      };
    },
    errorPage: '1'
  },
  prefix: 'http://localhost:5000/api/',
  // 中间件
  middlewares: [],
  // 请求拦截器
  requestInterceptors: [
    (url: string, options) => {
      options.headers = { Authorization: `Bearer ${Cookies.get('accessToken') ?? ''}` };
      return { url, options };
    }
  ],
  // 响应拦截器
  responseInterceptors: []
};
//#endregion

感谢感谢,更新之后umi-request就不用引进来写了。。

joesdu commented 4 years ago

+1 表示已经上v5了,antd4.x、umi 3.x 、pro-layout6.x

请教一下 ts的request 拦截器部分 怎么做的?

import { RequestConfig, history } from 'umi';
import Cookies from 'js-cookie';
import React from 'react';
import { notification } from 'antd';
//#region Request配置
/**
 * CodeMessage
 */
const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  405: '请求方法不被允许。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。'
};

/**
 * 运行时request配置
 */
export const request: RequestConfig = {
  timeout: 10000,
  // 当接口规范时,采用配置errorHandler的方式来实现错误提示.
  errorHandler: (error: { response: Response }) => {
    const { response } = error;
    if (response && response.status) {
      const errorText = codeMessage[response.status] || response.statusText;
      const { status, url } = response;
      notification.error({ message: `请求错误 ${status}: ${url}`, description: errorText });
    }
    if (!response) {
      notification.error({ description: '您的网络发生异常,无法连接服务器', message: '网络异常' });
    }
    throw error;
  },
  // 当接口不规范时,采用配置errorConfig的方式来实现错误提示.
  errorConfig: {
    adaptor: (res: any) => {
      return {
        ...res,
        success: res.ok || res.Success || res.success,
        errorMessage: res.message || res.msg || res.Message
      };
    },
    errorPage: '1'
  },
  prefix: 'http://localhost:5000/api/',
  // 中间件
  middlewares: [],
  // 请求拦截器
  requestInterceptors: [
    (url: string, options) => {
      options.headers = { Authorization: `Bearer ${Cookies.get('accessToken') ?? ''}` };
      return { url, options };
    }
  ],
  // 响应拦截器
  responseInterceptors: []
};
//#endregion

感谢感谢,更新之后umi-request就不用引进来写了。。

对request可以通过umi直接引入

joesdu commented 4 years ago

哪位大佬说一下useModel如何替换dva的

我空了给你弄一个

ChenWeihua123 commented 4 years ago

点赞 支持!!

joesdu commented 4 years ago

哪位大佬说一下useModel如何替换dva的

https://github.com/joesdu/destiny-admin-flow-umi 可以看一下

GUEThe commented 4 years ago

想问一下 v5 怎么关闭默认的layout,然后使用自定义 layout

joesdu commented 4 years ago

不去config里边写layout就好了

已从 Outlook Mobilehttps://aka.ms/blhgte 发送


From: guetHe notifications@github.com Sent: Tuesday, May 26, 2020 4:00:16 PM To: ant-design/ant-design-pro ant-design-pro@noreply.github.com Cc: Joe Du dygood@outlook.com; Comment comment@noreply.github.com Subject: Re: [ant-design/ant-design-pro] Ant Design Pro V5 已经支持预览 (#6605)

想问一下 v5 怎么关闭默认的layout,然后使用自定义 layout

― You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/ant-design/ant-design-pro/issues/6605#issuecomment-633872005, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ADETYSMNPJEC2YHVVNWSUYTRTNZJBANCNFSM4NDVTI7Q.

admiao commented 4 years ago

哪位大佬说一下useModel如何替换dva的

https://github.com/joesdu/destiny-admin-flow-umi 可以看一下

大佬 你是如何解决 编辑页面 ID不同 Form 的数据 没更新的问题的

zoeykk commented 4 years ago

请问 V5 版本下 ant-design-pro/src/app.tsx 这个路径下 export const layout = ({ initialState, }: { initialState: { settings?: LayoutSettings }; }): BasicLayoutProps => { return { rightContentRender: () => <RightContent />, disableContentMargin: false, footerRender: () => <Footer />, menuHeaderRender: undefined, ...initialState?.settings, }; }; 这段代码里的 ...initialState?.settings 这个是啥意思?

joesdu commented 4 years ago

请问 V5 版本下 ant-design-pro/src/app.tsx 这个路径下 export const layout = ({ initialState, }: { initialState: { settings?: LayoutSettings }; }): BasicLayoutProps => { return { rightContentRender: () => <RightContent />, disableContentMargin: false, footerRender: () => <Footer />, menuHeaderRender: undefined, ...initialState?.settings, }; }; 这段代码里的 ...initialState?.settings 这个是啥意思?

这个是TS的语法,意思就是若是initialState不为空就取他的settings属性并展开

joesdu commented 4 years ago

哪位大佬说一下useModel如何替换dva的

https://github.com/joesdu/destiny-admin-flow-umi 可以看一下

大佬 你是如何解决 编辑页面 ID不同 Form 的数据 没更新的问题的

什么意思?

admiao commented 4 years ago

哪位大佬说一下useModel如何替换dva的

https://github.com/joesdu/destiny-admin-flow-umi 可以看一下

大佬 你是如何解决 编辑页面 ID不同 Form 的数据 没更新的问题的

什么意思?

已经解决 我一直都用Form 的initialValues 来做回填 所有有一些困扰 现在解决了 感谢

joesdu commented 4 years ago

哪位大佬说一下useModel如何替换dva的

https://github.com/joesdu/destiny-admin-flow-umi 可以看一下

大佬 你是如何解决 编辑页面 ID不同 Form 的数据 没更新的问题的

什么意思?

已经解决 我一直都用Form 的initialValues 来做回填 所有有一些困扰 现在解决了 感谢

哦,回填的话新版Form得用setxxx那个函数

admiao commented 4 years ago

为什么 路由做不到按 component来加载呢,比如 image 这样的路由布局不是很普遍吗?按路由路径对应的component来渲染不是思路更清楚明了吗

netcore-jroger commented 4 years ago

为什么 路由做不到按 component来加载呢,比如 image 这样的路由布局不是很普遍吗?按路由路径对应的component来渲染不是思路更清楚明了吗

同问

lf7817 commented 4 years ago

想问一下 v5 怎么关闭默认的layout,然后使用自定义 layout

默认的布局关不掉,你可以这样试试 image

kaoding commented 4 years ago

自定义 layout

看到一些说不想使用默认的 layout,在v5之前很方便的可以使用自定义的 layout,v5也应该给一个这样的解决方案。

joesdu commented 4 years ago

自定义 layout

看到一些说不想使用默认的 layout,在v5之前很方便的可以使用自定义的 layout,v5也应该给一个这样的解决方案。

image V5本身就支持这样的方案,同样是在layouts文件夹下写好layout,然后在Umi的config文件中不配置layout属性就可以支持如图去掉红框中的内容.我在从V4完全升级到V5之前就是这样的.

joesdu commented 4 years ago

同样,在新版Layout中若是某些页面不希望使用默认的layout,可以使用这种方式实现部分页面不使用layout image

zhengjf1988 commented 4 years ago

更新到V5了,看了一下权限的模块,感觉和V4差不多呀,还是绑定角色名称。 image 不能动态的创建角色,然后设置相关的菜单或者按钮权限吗?

zhengjf1988 commented 4 years ago

还有一个就是右边的全局设置的浮动按钮没有了,现在不支持动态修改主题了吗?

zhengjf1988 commented 4 years ago

image 还有一个问题是左边的菜单收缩起来后无法打开一级菜单

已提有 Issue 了 https://github.com/ant-design/ant-design-pro/issues/6644

kaoding commented 4 years ago

同样,在新版Layout中若是某些页面不希望使用默认的layout,可以使用这种方式实现部分页面不使用layout image

如果这种方案可以,你提一个自定义 layout 的PR(文档)就行了,这就是用户想要的解决方案。没有写出来,就各有各的用法,写出来了就是一个最佳实践。

joesdu commented 4 years ago

更新到V5了,看了一下权限的模块,感觉和V4差不多呀,还是绑定角色名称。 image 不能动态的创建角色,然后设置相关的菜单或者按钮权限吗?

权限很简单的,我s是用的数字来实现的,其他类型的数据都可以,只要你能判断true,false就行.至于按钮级别的权限肯定是需要你自己去判断并且做渲染了.框架层面不可能去做按钮级别的权限的. image

joesdu commented 4 years ago

image 还有一个问题是左边的菜单收缩起来后无法打开一级菜单

这个bug,大佬们估计还在修.

已提有 Issue 了 https://github.com/ant-design/ant-design-pro/issues/6644

joesdu commented 4 years ago

同样,在新版Layout中若是某些页面不希望使用默认的layout,可以使用这种方式实现部分页面不使用layout image

如果这种方案可以,你提一个自定义 layout 的PR(文档)就行了,这就是用户想要的解决方案。没有写出来,就各有各的用法,写出来了就是一个最佳实践。

这个其实就是V4的写法.这两天我空了可以去提个V5的Pr

joesdu commented 4 years ago

还有一个就是右边的全局设置的浮动按钮没有了,现在不支持动态修改主题了吗?

动态改主题需要安装两个插件umi-plugin-antd-theme和umi-plugin-setting-drawer,并且在app.tsx的函数中导出

export const getInitialState = async (): Promise<{
  currentUser?: Types.CurrentUser;
  settings?: LayoutSettings;
  settingDrawer?: SettingDrawerProps;
}> => {
  // 如果是登录页面,不执行
  if (history.location.pathname !== '/login') {
    return {
      currentUser,
      settings: defaultSettings,
      settingDrawer: { hideCopyButton: true, hideHintAlert: true }
    };
  } 
zhengjf1988 commented 4 years ago

更新到V5了,看了一下权限的模块,感觉和V4差不多呀,还是绑定角色名称。 image 不能动态的创建角色,然后设置相关的菜单或者按钮权限吗?

权限很简单的,我s是用的数字来实现的,其他类型的数据都可以,只要你能判断true,false就行.至于按钮级别的权限肯定是需要你自己去判断并且做渲染了.框架层面不可能去做按钮级别的权限的. image

现在还是在config.ts中提前配置了access: 'canAdmin', 实际上在使用的时候,都是在添加角色时选择可以打开的菜单。登录成功后,根据当前角色配置的可以打开的菜单,动态的加载菜单,而不是提前把能打开菜单的角色配置好吧。

joesdu commented 4 years ago

更新到V5了,看了一下权限的模块,感觉和V4差不多呀,还是绑定角色名称。 image 不能动态的创建角色,然后设置相关的菜单或者按钮权限吗?

权限很简单的,我s是用的数字来实现的,其他类型的数据都可以,只要你能判断true,false就行.至于按钮级别的权限肯定是需要你自己去判断并且做渲染了.框架层面不可能去做按钮级别的权限的. image

现在还是在config.ts中提前配置了access: 'canAdmin', 实际上在使用的时候,都是在添加角色时选择可以打开的菜单。登录成功后,根据当前角色配置的可以打开的菜单,动态的加载菜单,而不是提前把能打开菜单的角色配置好吧。

权限是组合的,但是你配置的只是某个路由的权限.这些是可以确定的,比如用户A可以访问E,F,D3个页面的路由,用户B可以访问F路由.你用户A和B均存在F路由,所以F路由就都能访问,在B登陆的时候,E和D路由的菜单就不会被渲染.所以B无法访问.若是强行更改地址栏路由,就会出现403页面.

zhengjf1988 commented 4 years ago

更新到V5了,看了一下权限的模块,感觉和V4差不多呀,还是绑定角色名称。 image 不能动态的创建角色,然后设置相关的菜单或者按钮权限吗?

权限很简单的,我s是用的数字来实现的,其他类型的数据都可以,只要你能判断true,false就行.至于按钮级别的权限肯定是需要你自己去判断并且做渲染了.框架层面不可能去做按钮级别的权限的. image

现在还是在config.ts中提前配置了access: 'canAdmin', 实际上在使用的时候,都是在添加角色时选择可以打开的菜单。登录成功后,根据当前角色配置的可以打开的菜单,动态的加载菜单,而不是提前把能打开菜单的角色配置好吧。

权限是组合的,但是你配置的只是某个路由的权限.这些是可以确定的,比如用户A可以访问E,F,D3个页面的路由,用户B可以访问F路由.你用户A和B均存在F路由,所以F路由就都能访问,在B登陆的时候,E和D路由的菜单就不会被渲染.所以B无法访问.若是强行更改地址栏路由,就会出现403页面.

image

角色可以打开那些菜单是动态的,每个角色配置可以打开的菜单是不同的。 角色和资源关联 登录成功后,根据角色设置菜单。而不是先设置好所有菜单可以由哪些角色打开。