裝飾器模式在React中實(shí)際使用場景

首先簡要的介紹一下問題,我們公司大部分項目都是使用umi+Ant Design Pro 構(gòu)建(下面的Pro都指代它),因?yàn)閳鼍暗牟煌覀兛偸且鶕?jù)不同的場景區(qū)分和抽離布局組件,在Pro中的layouts文件夾里面已經(jīng)為我們提供了不同場景的布局組件。

大部分頁面包含了通用的導(dǎo)航、側(cè)邊欄、頂部通知、頁面標(biāo)題等元素,這時候我們會使用BasicLayout作為布局組件,使用如下:

 {
   path: '/org',
   component: '../layouts/SecurityLayout',
   routes: [
     {
       path: '/',
       component: '../layouts/BasicLayout',
       authority: [],
       routes: [
         {
           path: '/org/dashboard',
           name: 'dashboard',
           component: './dashboard'
         },
         {
           path: '/org/department',
           name: 'department',
           component: './department',
           hideInMenu: true
         },
         {
           path: '/org/user',
           name: 'user',
           component: './user/list'
         },
         {
           component: './404'
         }
       ]
     }
   ]
 },

這時候問題就出現(xiàn)了,/org/department頁面的布局不是BasicLayout,而是BlankLayout。那怎么辦?

剛開始這種頁面不多,直接就在BasicLayout中的render函數(shù)中判斷l(xiāng)ocation.pathname的值,直接return一個children,代碼如下:

    if (['/org/department'].indexOf(pathname) > -1) {
      return <div>{children}</div>
    }

從此不優(yōu)雅的代碼開始瘋狂的增長,想象一下當(dāng)有十幾個頁面出現(xiàn)這種情況的時候。

下面我們就用裝飾器模式,優(yōu)雅的解決這個問題。如果對裝飾器比較陌生的同學(xué)可以看這里Javascript 中的裝飾器

先實(shí)現(xiàn)一個裝飾器,一個高階組件ExcludeLayout

import React, { Component } from 'react';
import BlankLayout from './BlankLayout';

function ExcludeLayout(opt) {
  return function(WrappedComponent) {
    return class extends Component {
      render() {
        const {
          children,
          location = {
            pathname: '',
          },
        } = this.props;
        const { routes } = opt;
        const { pathname } = location;

        if (routes.indexOf(pathname) > -1) {
          return <BlankLayout {...this.props} />
        }

        return (
          <WrappedComponent {...this.props} />
        );
      }
    }
  }
}

export default ExcludeLayout;

上面這個高階函數(shù)其實(shí)就是進(jìn)行路由的挾持,如果pathname在我們傳入的opt.routes路由數(shù)組中,我們就使用BlankLayout布局組件。下面看一下ExcludeLayout裝飾器去裝飾BasicLayout組件:

@ExcludeLayout({
  routes: ['/org/department']
})
class BasicLayout extends Component {
  .......
  .......
}

// 非class定義的使用
BasicLayout = ExcludeLayout({
  routes: [`/org/department`]
})(BasicLayout);

以上就用裝飾模式,優(yōu)雅的解決上面的問題。

實(shí)際開發(fā)場景下還有很多地方可以用到裝飾器,當(dāng)代碼寫好看起來就討厭的時候,就可以思考思考是否有上面優(yōu)雅的實(shí)現(xiàn)方式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前端開發(fā)面試題 面試題目: 根據(jù)你的等級和職位的變化,入門級到專家級,廣度和深度都會有所增加。 題目類型: 理論知...
    怡寶丶閱讀 2,694評論 0 7
  • 【每日剽悍1003】 01 昔日幾位同窗好友,并沒有預(yù)想過這一次假期能見到,見一見挺好的。 三點(diǎn)印象深刻: 第一 ...
    青詞讀書看世界閱讀 327評論 0 1
  • 自定義IndeView 自定義的仿微信的IndexView。使用便捷,只需要設(shè)定indexArray即可。 圖示 ...
    Leven_W閱讀 285評論 0 0
  • import React, { Component } from 'react';import {Platform...
    WhyLingLei閱讀 3,293評論 0 1
  • 之前,看著街上女孩們穿著旗袍,裊裊娜娜,我羨慕極了,也從網(wǎng)上買了一件。 其實(shí),每到天氣暖和一點(diǎn),我都會想到一句詩:...
    鈴蘭萃語閱讀 212評論 0 1

友情鏈接更多精彩內(nèi)容