Umi: @umijs/plugin-initial-state初始数据怎么更改

Created on 5 Mar 2020  ·  17Comments  ·  Source: umijs/umi

比如

// src/app.ts
export async function getInitialState() {
  return {
     isLogin: false
  };
}

用户登录后 怎么把isLogin 改为true

type(question)

Most helpful comment

@tli4 非常感谢你的回答,能提供一个简单的demo来参考学习吗?

可以参考这个逻辑,如果 getUser 失败就跳转登陆页。登陆成功后返回 getUser 就会成功.
https://codesandbox.io/s/competent-elion-5ewgv

All 17 comments

同求,用于判断路由权限该怎么处理

比如

// src/app.ts
export async function getInitialState() {
  return {
     isLogin: false
  };
}

用户登录后 怎么把isLogin 改为true

getInitialState 在首次返回之前会阻止页面的渲染。
通常可以这样写:

export async function getInitialState() {
  return fetch('/api/user')
}

在使用的时候通过 useModel('@@initialState') 可以拿到 { initialState, loading, refresh } 三个参数。其中 initialState 就是 user 接口返回的值。可以根据后端返回的状态,来确定当前用户是否登陆

@tli4 我明白你的意思。那么首次登录失败, 用户跳转到login页面重新登录, 怎么把数据更新到initialstate里面?

@tli4 我明白你的意思。那么首次登录失败, 用户跳转到login页面重新登录, 怎么把数据更新到initialstate里面?

登陆之后会在 cookie 里写上一些信息,后端要提供一个查询用户的接口。根据 cookie 里的内容返回当前用户的 信息,比如 name, id, avatar 等。前端再根据 id 是否存在来判断该用户是否登陆,如果未登陆跳转到登陆页

@tli4 非常感谢你的回答,能提供一个简单的demo来参考学习吗?

同求,用于判断路由权限该怎么处理

可以在 access 文件中配置所有的权限项,然后在为需要的路由配置相应的权限 key 即可。

  1. 第一步:新建 src/access.ts ,在该文件中定义用户所有的权限。返回一个 function,返回的 function 会在应用初始化阶段被执行,执行后返回的对象将会被作为用户所有权限的定义。对象的每个 key 对应一个 boolean 值,只有 true 和 false,代表用户是否有该权限。

其中的 initialState 来自于全局初始化数据,你可以基于这些数据来初始化用户权限。

//  src/access.ts
export default function(initialState) {
  return {
    canLogin: true,
  };
}
  1. 第二部:你可以把 access 中的每个 key 配置到 routeItem 上,如下,如果 canLogin 为 false,layout 插件会展示默认的无权访问的 UI。
//config/route.ts
export const routes =  [
  {
    path: '/welcome',
    component: 'IndexPage',
    menu: {
      name: '欢迎', 
      icon: 'testicon',
    },
    layout:{
      hideNav: true,
    },
    access: 'canLogin',  // 这个
  }
]

@Ariel-Cheng 刚刚测试了一下,用户A,重新登录B,权限canReadA变化了,但是路由权限并没有变化。

同求,用于判断路由权限该怎么处理

可以在 access 文件中配置所有的权限项,然后在为需要的路由配置相应的权限 key 即可。

  1. 第一步:新建 src/access.ts ,在该文件中定义用户所有的权限。返回一个 function,返回的 function 会在应用初始化阶段被执行,执行后返回的对象将会被作为用户所有权限的定义。对象的每个 key 对应一个 boolean 值,只有 true 和 false,代表用户是否有该权限。

其中的 initialState 来自于全局初始化数据,你可以基于这些数据来初始化用户权限。

//  src/access.ts
export default function(initialState) {
  return {
    canLogin: true,
  };
}
  1. 第二部:你可以把 access 中的每个 key 配置到 routeItem 上,如下,如果 canLogin 为 false,layout 插件会展示默认的无权访问的 UI。
//config/route.ts
export const routes =  [
  {
    path: '/welcome',
    component: 'IndexPage',
    menu: {
      name: '欢迎', 
      icon: 'testicon',
    },
    layout:{
      hideNav: true,
    },
    access: 'canLogin',  // 这个
  }
]

嗯这个我知道 目前我的问题是 我用户第一次进来是未登录状态,这个initState肯定是空的 然后我用户登录了之后我需要咋去更新这个access呢?

嗯这个我知道 目前我的问题是 我用户第一次进来是未登录状态,这个initState肯定是空的 然后我用户登录了之后我需要咋去更新这个access呢?

我也是这个想法,难道全局initState第一次初化后,就不能更改了么。
有个refreshapi,但是在refresh的时候,initState会变为undefined。

@tli4 非常感谢你的回答,能提供一个简单的demo来参考学习吗?

可以参考这个逻辑,如果 getUser 失败就跳转登陆页。登陆成功后返回 getUser 就会成功.
https://codesandbox.io/s/competent-elion-5ewgv

可以再登陆后 用window.location.repalce 做跳转 这样会重新触发getInitialState执行

請問這個問題有解嗎,我通過 window.location.replace 來進行跳轉,也不會觸發getInitialState 重新執行

@Ariel-Cheng 刚刚测试了一下,用户A,重新登录B,权限canReadA变化了,但是路由权限并没有变化。

我也遇到了这个问题:登录成功进入的页面的菜单是上一次退出的权限菜单(若清空缓存,菜单不会渲染)。
个人觉得是登录成功后,权限改变,但菜单没有重新渲染,只有手动刷新路由才会渲染出正确的权限菜单。
目前的解决方法是,进入页面后使用window.location.reload()手动刷新当前路由。
但是,会有一个明显的问题:该页面被加载了两次。

对照中台助手,检查和你们的实现哪里不同。

@lichangchao15442 , @jarvisaoieong

对照中台助手,检查和你们的实现哪里不同。

@lichangchao15442 , @jarvisaoieong
我看了一下文档,实现的方式不一样,文档中是在页面里面配置的权限,我是按照umi的插件文档进行配置的(在路由中配置权限)

对照中台助手,检查和你们的实现哪里不同。
@lichangchao15442 , @jarvisaoieong
我看了一下文档,实现的方式不一样,文档中是在页面里面配置的权限,我是按照umi的插件文档进行配置的(在路由中配置权限)

中台助手里是约定式路由配置,你说你用的是配置式路由,这俩只是路由配置手段的区别,不影响最终结果。你应该对照登录部分,app.ts, access.ts , 以及布局里的处理方式的差异。找找看为什么你的项目里不工作

Was this page helpful?
0 / 5 - 0 ratings