在通過了很長時間的準備下,Pro V5 已經基本完成, 可是仍然有不少地方不是很完善,在新版本中咱們進行了不少預設,對於數據流和佈局更是進行了大刀闊斧的改進。雖然底層仍然基於 umi@3 來實現的,可是在應用層作了不少改動,接下來咱們會展現一下咱們的主要改動。react
layout 是此次的最大改動,首先是進行了樣式上的更新,支持混合模式來指望適應更多的場景。新的風格仍然會以科技的風格爲主,在原來的基礎上優化尺寸和體驗細節,設計更加簡潔,匹配更多業務場景,具體的改動能夠看這裏。git
對於開發者也迎來了不少改動,程序員
layout
屬性變爲 'side' | 'top' | 'mix'
headerTitleRender
和 headerContentRender
用於自定義混合模式下的頭信息menuExtraRender
來自定義 標題和菜單之間的區域。對於 SettingDrawer,爲了方便集成和部署,咱們開發了 umi-plugin-setting-drawer ,只要在項目中安裝這個便可快速使用。github
umi-plugin-setting-drawer 依賴 @umijs/plugin-initial-state 和 @umijs/plugin-layout, 若是要本身實現須要自動綁定 @umijs/plugin-initial-state 中的數據。typescript
Pro V5 中的架構作了全新的改動,所有修改成全新的 umi@3 架構, 對於數據流,權限,佈局都進行了內置,修改成了全新的插件。這些改進都是漸進式的,只要你升級爲 umi@3 ,是能夠兼容兩種開發模式的。api
咱們在過去嘗試了不少數據流方案,而且隨着 dva 的出現穩定了下來,可是在 hooks 到來以後咱們看到了機會來解決 dva 實踐中遇到的問題。在一個標準的 dva 應用中咱們須要寫不少的樣板文件,作了不少重複勞動。markdown
尤爲是 它有不少概念,effects
,state
, 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
中的文件名。app
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 便可使用這些特性,新的數據流雖然簡單高效可是並不能知足全部的場景,咱們能夠混合適應,慢慢遷移。固然咱們但願能夠儘早遷移來減小歷史債務。詳細步驟能夠參閱官網的遷移指南。
Pro v5 中使用了全新的架構,更加標準化而且自帶了不少內部的最佳實踐,不管代碼量仍是使用難度都下降了。可是標準化同時意味着失去了個性化的空間,咱們但願在正式發佈以前,收集一些信息,在標準化和個性化以前取得一個平衡。
Pro 與 umi 的關係有點像 react-scripts
與 create-react-app
,umi 提供了基礎能力,而 Pro 在上層提供了更多用法,而且加入了咱們對中後臺項目的實踐。
做爲一個開源項目,若是你以爲某個功能不滿意或者功能缺失,你能夠提 issue 來參與討論,若是獲得了官方的承認,那麼這個功能就會被實現。這個流程通常會很長,因此推薦你直接提 PR 來實現功能,同時能夠幫助到更多同窗,成爲一名光榮的 contributors,走向名望程序員第一步。