阿里出品的Umi框架,你看懂了嗎美澳?

背景

image.png

之前GMTC 全球大前端技術大會上销部,公開了這張阿里前端框架的時間線,我們可以看到制跟,在2017.8和2017.12舅桩,阿里兩個不同的業(yè)務部門曾接連推出了兩款前端框架,Umi和Bigfish雨膨。但是在2018.6擂涛,阿里對兩個部門進行了整合,產(chǎn)出了Umi+Bigfish這樣的整合框架聊记。在2019.11月撒妈,Umi這款框架才算最終落地,經(jīng)過了兩年的整合甥雕,我們來看看這個Umi框架到底是個什么黑科技產(chǎn)品

它是什么

image.png

從大會上放出的另一張圖我們看到了踩身,我們在“刀耕火種”的時代做前端開發(fā)的時候胀茵,總是會考慮我們選擇在項目里使用 React 庫來開發(fā)的時候社露,項目的數(shù)據(jù)流方案應該怎么選擇(redux, mobx, redux-saga, redux-router,dva,等),組件庫 的選擇(antd, material design)琼娘,以及webpack打包的復雜配置等峭弟,這里的 Bigfish&um看起來像是把以前我們項目中通常會用到的一些庫整合到了一起附鸽。
既然Umi是一個框架,那就有很多“約定”的規(guī)則瞒瘸,需要我們遵守坷备,不管是在路由配置,還是在mock數(shù)據(jù)情臭,以及數(shù)據(jù)和頁面交互方面省撑,我們都能夠感受到這種潛在的“約定”

它有什么

Umi概述

幕布版鏈接
之前用幕布整理了一個其中大概的內(nèi)容俯在,而且2.x與3.x版本差別還比較大竟秫,這張圖片整理的大部分是基于2.x的版本,可以粗略的看看跷乐,也可以點擊鏈接去官網(wǎng)查看肥败,Umi官網(wǎng)

它怎么用

我這里用Umi做了一個很簡陋的應用,不過基本需要包括的路由愕提,異步請求馒稍,頁面跳轉和mock數(shù)據(jù)都用到了,這里就拆分一下給大家做個演示浅侨。

登陸

image.png

這是一個很正常的登陸表單纽谒,表單的UI和驗證部分都是直接從Umi提供的工作臺上找到的基于antd的區(qū)塊,添加進項目就可以用如输,非常方便佛舱,只需要修改表單登陸事件處理的函數(shù):

const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    this.props.form.validateFields((err: any, values: any) => {
      if (!err) {
        this.props.dispatch({
          type: 'users/login',
          payload: values,
        });
      }
    });
  };

這里就要提到Umi推薦使用的數(shù)據(jù)流方案Dva,它封裝并簡化了redux、redux-router挨决、redux-saga的使用難度请祖,具體想了解更多Dva的更多內(nèi)容,可以訪問Dva官網(wǎng)脖祈。
在代碼中肆捕,可以看到這里使用了redux常用的dispatch action的方式來發(fā)起登錄請求。所以我們需要有一個地方能夠handle這個action的執(zhí)行盖高,接下來看對應的modal是如何實現(xiàn)的:

export default {
  namespace: 'users',
  state: {
    id: '',
    userName: '',
    friends: [],
  },

  reducers: {
    save: (state: UserState, { payload }: { payload: UserState }) => {
      return { ...state, ...payload };
    },
  },

  effects: {
    *login({ payload }: { payload: LoginRequestParams }, { call, put }: EffectsCommandMap) {
      const response = yield call(loginApi, payload)
      yield put({ type: 'save', payload: response });
      router.push('/users');
    }
  },
};

在modal中我們定義了這個modal的namespace叫做users慎陵,里面存放的數(shù)據(jù)包含id,userNamefriends,定義了一個叫做savereducer來保存相關數(shù)據(jù)喻奥,還定義了一個叫做login的方法來做含有副作用的操作席纽,可以看到方法中接收到payload以后調(diào)用了call方法來執(zhí)行了一個loginApi,數(shù)據(jù)獲取成功后撞蚕,發(fā)起save操作來保存返回的數(shù)據(jù)润梯,然后通過router.push來更改路由。其中有很多Dva相關的知識,感興趣的朋友可以去了解下纺铭。再貼上loginApi中做的事情:

export const loginApi = (payload: LoginRequestParams) => {
    return fetch("http://localhost:8000/api/users", {
        method: "POST",
        body: JSON.stringify(payload)
    }).then((response: Response) => response.json())
};

這里直接請求了localhost接口的原因是我并沒有做后端Api寇钉,所以是用了Umi本身提供的mock功能使用mock數(shù)據(jù)來模擬應用的后端訪問。至此舶赔,一個完整的login登錄流程就出來了扫倡。當我們點擊login的時候,打開Chrome的redux插件

redux插件

store變化

可以看到這里有我們完整的action flow竟纳,以及我們的state的變化撵溃。

當我們將數(shù)據(jù)存儲起來以后,我們在組件中如何使用store中的數(shù)據(jù)的方式和redux類似锥累,通過dva提供的connect方法征懈,傳入mapStateToProps參數(shù)即可,如:

const mapStateToProps = ({ users }: { users: UserState }) => ({
  userName: users?.userName,
  friends: users?.friends,
});

export default connect(mapStateToProps)(WelcomePage);
路由

在上面的代碼已經(jīng)看到了我們路由跳轉的一種方法是通過Umi提供的router.push(url)揩悄,官方還提供一種是通過鏈接跳轉卖哎,<Link to="/user">這種方式。
在Umi中有兩種方式來定義路由删性,一種是約定式亏娜,一種是配置式。接下來就說一下這兩種的區(qū)別:

約定式

src目錄結構

我們在使用腳手架生成Umi項目后可以看到src的目錄里面包含了一個pages的文件夾蹬挺,umi打包的時候會將目錄之間的關系映射成路由關系维贺,如:

  • src/pages/users/index.tsx 會成為 /users
  • src/pages/users/$id.tsx 會成為 /users/:id
  • src/pages/users/[id]/settings.tsx 會成為 /users/:id/settings
    以此類推。umi打包后生成的pages/.umi/router.js文件也可以看出來它們之間的關系巴帮,如圖:
...,
routes: [
      {
        path: '/404',
        exact: true,
        component: __IS_BROWSER
          ? _dvaDynamic({
              component: () => import('../404.tsx'),
            })
          : require('../404.tsx').default,
        _title: 'umi-js',
        _title_default: 'umi-js',
      },
      {
        path: '/',
        exact: true,
        component: __IS_BROWSER
          ? _dvaDynamic({
              component: () => import('../index.tsx'),
            })
          : require('../index.tsx').default,
        _title: 'umi-js',
        _title_default: 'umi-js',
      },
配置式

如果項目路由足夠復雜溯泣,有很多權限校驗的東西,那么Umi也提供了配置化修改榕茧。在項目中會有一個.umirc.ts的文件垃沦,這個文件就是項目的配置文件,也可以通過config/config.ts文件來配置用押。


const config: IConfig = {
  routes: [
    { path: '/', component: './index' },
    {
      path: '/users',
      component: './users/index',
    },
    {
      path: 'users/detail',
      component: './users/detail',
    },
    { path: 'users/:id', component: './users/$id.tsx' },
  ],
  ...,
};

在配置文件里我們可以更靈活的定義我們路由肢簿,也可以添加權限路由和嵌套路由,這里就不贅述了蜻拨,有興趣可以訪問官網(wǎng)查看池充。

mock數(shù)據(jù)

當我們做前后端分離項目的時候,前后端通常不會一直都以相同速率開發(fā)缎讼,總是會有一方等待另一方集成的問題收夸。在umi中針對這種情況給了mock數(shù)據(jù)的解決方案,如圖:


根目錄

在根目錄中有一個叫做mock的文件夾血崭,Umi約定在這個文件夾下的文件都被視作mock數(shù)據(jù)卧惜。當前端訪問本地接口的時候厘灼,就會到這里面來對應的查找有沒有和請求的url能夠匹配的數(shù)據(jù),如果有就直接返回序苏。
比如我的api.js文件中:

import mockjs from 'mockjs';
export default {
  'POST /api/users': mockjs.mock({
    userName: '@name',
    id: '@id',
    'friends|5-10': [{ id: '@id', userName: '@name' }],
  }),
};

這里使用了mockjs來生成對應格式的mock數(shù)據(jù)手幢,這樣可以最大限度的保證數(shù)據(jù)的有效性捷凄。

Umi-UI

這里有一個Umi的工作臺覺得需要提出來說一下忱详,因為個人覺得這個工作臺很大程度上減少了前端開發(fā)的門檻。


配置模塊

任務模塊

資產(chǎn)模塊

從上面的圖可以看出跺涤,如果你不熟悉webpack匈睁,不熟悉配置式路由,不熟悉npm script桶错,在這個工作臺都能夠可視化修改航唆。甚至你可以直接把區(qū)塊和模板里的東西直接引入到你自己的項目中,無須做太多改動就可用院刁,極大減輕了UI開發(fā)的壓力糯钙。

結語

以上就是對Umi框架的一些簡單的介紹,可能大家覺得Umi 2.x有點臃腫退腥,包含的東西太多任岸。沒關系,可以嘗試Umi 3.0狡刘,更加的精簡和插件化享潜。

最后附上項目的github地址

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嗅蔬,一起剝皮案震驚了整個濱河市剑按,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌澜术,老刑警劉巖艺蝴,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鸟废,居然都是意外死亡吴趴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門侮攀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锣枝,“玉大人,你說我怎么就攤上這事兰英∑踩” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵畦贸,是天一觀的道長陨闹。 經(jīng)常有香客問我楞捂,道長,這世上最難降的妖魔是什么趋厉? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任寨闹,我火速辦了婚禮,結果婚禮上君账,老公的妹妹穿的比我還像新娘繁堡。我一直安慰自己,他們只是感情好乡数,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布椭蹄。 她就那樣靜靜地躺著,像睡著了一般净赴。 火紅的嫁衣襯著肌膚如雪绳矩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天玖翅,我揣著相機與錄音翼馆,去河邊找鬼。 笑死金度,一個胖子當著我的面吹牛应媚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播审姓,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼珍特,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了魔吐?” 一聲冷哼從身側響起扎筒,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎酬姆,沒想到半個月后嗜桌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡辞色,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年骨宠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片相满。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡层亿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出立美,到底是詐尸還是另有隱情匿又,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布建蹄,位于F島的核電站碌更,受9級特大地震影響裕偿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜痛单,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一嘿棘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧旭绒,春花似錦鸟妙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垃瞧。三九已至蔫劣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間个从,已是汗流浹背脉幢。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嗦锐,地道東北人嫌松。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像奕污,于是被迫代替她去往敵國和親萎羔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容