亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

如何寫(xiě)出簡(jiǎn)潔、優(yōu)雅、可維護(hù)的組件。

MingjunYang / 839人閱讀

摘要:在里,通過(guò)的服務(wù)和依賴(lài)注入可以很輕松的實(shí)現(xiàn),這里是我集中功能的服務(wù)文件文件功能類(lèi)集合獲取短信驗(yàn)證碼這些功能需要用到的方法需要的地方只要注入這個(gè)服務(wù)就可以獲取想要的功能。寫(xiě)成組件會(huì)有樣式的限制,而這樣寫(xiě)沒(méi)有。

最近開(kāi)始維護(hù)項(xiàng)目,然后我發(fā)現(xiàn)每天的時(shí)間常常是花在修改幾個(gè)小功能上,改了問(wèn)題有出了另一個(gè)問(wèn)題,思考哪里不對(duì)?,然后這么一天就過(guò)去了。。然后我就開(kāi)始思考標(biāo)題好讓我的時(shí)間不總是花在修改上,下面的是我最近的一些總結(jié)。

功能分離

這個(gè)算是面向?qū)ο罄锏乃枷?,在組件里,有很多功能是獨(dú)立的,比如最常見(jiàn)的發(fā)送驗(yàn)證碼,確認(rèn)密碼等。把這些邏輯封裝成一個(gè)或幾個(gè)函數(shù)寫(xiě)在組件里的話,這在組件很小的時(shí)候沒(méi)有什么影響,但是當(dāng)組件功能比較復(fù)雜的時(shí)候,就會(huì)有些問(wèn)題:

組件邏輯區(qū)域會(huì)變的很大,各種方法混雜很難一眼辨識(shí)

因?yàn)槎x功能需要的變量和方法不在一起,導(dǎo)致修改麻煩

功能分離就是把這些功能抽離出來(lái),寫(xiě)出一個(gè)類(lèi),然后在組件里引入。

下面是一個(gè)簡(jiǎn)單的彈窗控制的功能的類(lèi)和這個(gè)類(lèi)的使用:

export class DialogCtrl {
  isVisible = false;

  open () {
    this.isVisible = true;
  }
  close () {
    this.isVisible = false;
  }
}

然后在需要的組件里引入并實(shí)例化:

DialogCtrl = new this.CommonService.DialogCtrl();  // 是否打開(kāi)彈窗

在html里可以直接這樣用:

這個(gè)nz-modal是一個(gè)彈窗,在組件里我們只有一個(gè)變量的聲明,如此簡(jiǎn)潔!而在html里DialogCtrl.isVisible,DialogCtrl.close()的形式也很容易理解它的作用和出處。

這樣做的另一個(gè)好處是利于實(shí)現(xiàn)復(fù)用。對(duì)于可以復(fù)用的功能,比如上面發(fā)送驗(yàn)證碼的邏輯,可以建一個(gè)全局的服務(wù)來(lái)提供。在angular里,通過(guò)angular的服務(wù)和依賴(lài)注入可以很輕松的實(shí)現(xiàn),這里是我集中功能的common.service.ts服務(wù)文件:

common.servide.ts文件:

@Injectable()
export class CommonService {
  // 功能類(lèi)集合
  public DialogCtrl = DialogCtrl;
  public MessageCodeCtrl = MessageCodeCtrl;
  public CheckPasswordCtrl = CheckPasswordCtrl;

  constructor(
    private http: HttpClient
  ) { }

  /* 獲取短信驗(yàn)證碼(這些功能需要用到的方法)
  -------------------------- */
  public getVerificationCode (phoneNum: string): Observable {
    return this.http.get("/account/short_message?phoneNumber=" + phoneNum);
  }
}

需要的地方只要注入這個(gè)服務(wù)就可以獲取想要的功能。相比較直接建立一個(gè)組件來(lái)實(shí)現(xiàn),我覺(jué)得這樣寫(xiě)有一些優(yōu)勢(shì):

靈活性更高。寫(xiě)成組件會(huì)有樣式的限制,而這樣寫(xiě)沒(méi)有。

更簡(jiǎn)潔。寫(xiě)成組件,與之溝通只能通過(guò)子父組件的傳入變量,監(jiān)聽(tīng)子組件事件的方法,你使用的組件不可避免的會(huì)多出這些變量和方法。

狀態(tài)管理

不知道大伙兒有沒(méi)有這樣的感覺(jué),自己寫(xiě)新項(xiàng)目的時(shí)候覺(jué)得邏輯清晰,代碼簡(jiǎn)練,功能也都實(shí)現(xiàn)了,但是過(guò)一段時(shí)間去看或者要改自己的代碼的時(shí)候...哇,看不懂。

前端復(fù)雜的地方源于數(shù)不清的狀態(tài),于是我為那些有復(fù)雜狀態(tài)的組件建立一個(gè)集中管理狀態(tài)的對(duì)象(這里我取名為Impure):

  /* 變量定義 -- 狀態(tài)
  -------------------------- */
  registerForm: FormGroup;  // 注冊(cè)賬號(hào)表單
  registerInfoForm: FormGroup; // 公司信息表單
  isSubmitting = false; // 表單是否正在提交
  nowForm = "registerForm";  // 當(dāng)前正在操作的表單
  MessageCodeCtrl = new this.CommonService.MessageCodeCtrl(this.Msg, this.CommonService); // 驗(yàn)證碼控制

  /* 變量定義 -- 定值
  -------------------------- */
  registerFormSubmitAttr = ["login", "password", "shortMessageCode", "roles", "langKey"];
  registerInfoFormFormSubmitAttr = ["simName", "contacter", "officeTel", "uid"];

  /* 改變狀態(tài)事件
  -------------------------- */
  Impure = {

    // 表單初始化
    RegisterFormInit: () => this.registerForm = this.registerFormInit(),
    RegisterInfoFormInit: () => this.registerInfoForm = this.registerInfoFormInit(),

    // 驗(yàn)證碼不合法
    MessageCodeInvalid: {
      notSend: () => this.Msg.error("您還未發(fā)送驗(yàn)證碼"),
      notRight: () => this.Msg.error("驗(yàn)證碼錯(cuò)誤")
    },

    // 表單提交
    FormSubmit: {
      invalid: () => this.Msg.error("表單填寫(xiě)有誤"),
      before: () => this.isSubmitting = true,
      registerOk: () => {
        this.Msg.success("賬號(hào)注冊(cè)成功");
        this.nowForm = "registerInfoForm";
      },
      registerInfoOk: () => {
        this.Msg.success("保存信息成功!請(qǐng)耐心等待管理員審核");
        this.Router.navigate(["/login"]);
      },
      fail: () => this.Msg.error("提交失敗,請(qǐng)重試"),
      after: () => this.isSubmitting = false
    }
  };

這是一個(gè)簡(jiǎn)單的有兩個(gè)表單的注冊(cè)組件,因?yàn)閮蓚€(gè)表單html耦合度很高,所以寫(xiě)在了一起。

在組件內(nèi)將變量分為狀態(tài)和定值的兩類(lèi),聲明了一個(gè)Impure對(duì)象來(lái)集中管理這些狀態(tài),原則上這個(gè)組件里所有狀態(tài)的改變都寫(xiě)在Impure里,而將事件觸發(fā)的判斷條件,數(shù)據(jù)處理寫(xiě)在Impure外面。

可以對(duì)比下這兩個(gè)使用Impure和不使用Impure的表單提交方法:

  /* 注冊(cè)賬號(hào)表單提交(Impure)
  -------------------------- */
  async register (form) {
    const _ = this.Fp._; // ramda庫(kù),用于數(shù)據(jù)處理
    const { MessageCodeInvalid, FormSubmit } = this.Impure;

    // 表單不合法
    if (form.invalid) { FormSubmit.invalid(); return; }

    // 驗(yàn)證碼不合法
    if (!this.MessageCodeCtrl.code) { MessageCodeInvalid.notSend(); return; }
    if (this.MessageCodeCtrl.code !== form.controls.shortMessageCode.value) { MessageCodeInvalid.notRight(); return; }

    // 表單提交
    FormSubmit.before();
    const data = _.compose(_.pick(this.registerFormSubmitAttr), _.map(_.prop("value")))(form.controls); // 數(shù)據(jù)處理
    const res = await this.AccountService.producerRegisterFirst(data).toPromise();
    if (!res) { FormSubmit.registerOk(); } else { FormSubmit.fail(); }
    FormSubmit.after();
  }

  /* 公司信息表單提交(非Impure)
  -------------------------- */
  async registerInfo ({ simName, contacter, officeTel }) {
    // 表單不合法
    if (this.registerInfoForm.invalid) { this.Msg.error("表單填寫(xiě)有誤"); return; }

    // 表單提交
    this.isSubmitting = true;
    const data = { // 數(shù)據(jù)處理
      simName: simName.value,
      contacter: contacter.value,
      officeTel: officeTel.value,
      uid: this.registerForm.controls.phone.value
    };
    const res = await this.AccountService.producerRegisterSecond(data).toPromise();
    if (!res) {
      this.Msg.success("保存信息成功!請(qǐng)耐心等待管理員審核");
      this.Router.navigate(["/login"]);
    } else {
      this.Msg.error("提交失敗,請(qǐng)重試");
    }
    this.isSubmitting = false;
  }

使用Impure管理狀態(tài)后,邏輯清晰,在提交表單時(shí)你只需要關(guān)注事件發(fā)生的條件就可以了,而第二個(gè)條件和狀態(tài)寫(xiě)在一起會(huì)很混亂,不能一眼清楚這個(gè)狀態(tài)改變發(fā)生在什么時(shí)候,特別是你一段時(shí)間再來(lái)看的時(shí)候。

其實(shí)這里的數(shù)據(jù)處理(這里面的data)應(yīng)該多帶帶拿出來(lái)寫(xiě)一個(gè)方法的,我只是來(lái)頂一下用純函數(shù)來(lái)處理數(shù)據(jù)的優(yōu)點(diǎn),這里的_是用了ramda這個(gè)庫(kù)。相比較第二個(gè)處理方式,第一種方式更加優(yōu)雅,簡(jiǎn)潔,很容易看出數(shù)據(jù)的源頭是什么(這里是form.controls),多帶帶抽離成數(shù)據(jù)處理函數(shù)也有很高的復(fù)用性。

假如某一天你要改下這里兩個(gè)表格的成功后的狀態(tài),不再需要到這兩個(gè)長(zhǎng)長(zhǎng)的提交函數(shù)里找到它們?nèi)缓笠粋€(gè)一個(gè)改,只要在Impure里面改就可以了,你甚至不需要看那兩個(gè)提交的方法。

這樣子,一個(gè)組件可以大致分為狀態(tài),狀態(tài)管理(impure),改變狀態(tài)的事件(狀態(tài)改變的判斷條件),和數(shù)據(jù)處理(純函數(shù))四部分,各司其職,很好維護(hù)。

結(jié)語(yǔ)

這些適合我但不一定適合所有人,每個(gè)人都有自己的風(fēng)格,各位看官感受下就好。以后我有其它方面的總結(jié)也會(huì)拿出來(lái)分享。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/88579.html

相關(guān)文章

  • 代碼整潔之道

    摘要:代碼寫(xiě)得是否整潔是客觀的,是的人或后期維護(hù)的人覺(jué)得好才是真的好。三代碼設(shè)計(jì)原則要想寫(xiě)出優(yōu)雅整潔的代碼,就要遵循特定的設(shè)計(jì)原則。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 最近在做一些項(xiàng)目重構(gòu)的工作,看了不少臟亂差的代碼,身心疲憊。本文將討論如何編寫(xiě)整潔的代碼,不求高效運(yùn)行,只求...

    stefan 評(píng)論0 收藏0
  • 我是如何將業(yè)務(wù)代碼寫(xiě)優(yōu)雅

    摘要:高內(nèi)聚低耦合高內(nèi)聚低耦合一直是軟件設(shè)計(jì)領(lǐng)域里亙古不變的話題,重構(gòu)的目標(biāo)是提高代碼的內(nèi)聚性,降低各功能間的耦合程度,降低后期維護(hù)成本,特別是寫(xiě)業(yè)務(wù)代碼,這一點(diǎn)相當(dāng)重要。0x00 前言 我是一名來(lái)自螞蟻金服-保險(xiǎn)事業(yè)群的前端工程師,在一線大廠的業(yè)務(wù)部門(mén)寫(xiě)代碼,非常辛苦但也非常充實(shí)。業(yè)務(wù)代碼不同于框架代碼、個(gè)人項(xiàng)目或者開(kāi)源項(xiàng)目,它的特點(diǎn)在于邏輯復(fù)雜、前后依賴(lài)多、可復(fù)用性差、迭代周期短,今天辛辛苦苦...

    voyagelab 評(píng)論0 收藏0
  • 阿里云前端周刊 - 第 31 期

    摘要:發(fā)布按照官方發(fā)布計(jì)劃,的發(fā)布意味著進(jìn)入階段,徹底退出舞臺(tái),的還有半年結(jié)束。為了應(yīng)對(duì)這個(gè)挑戰(zhàn),美團(tuán)點(diǎn)評(píng)境外度假前端研發(fā)團(tuán)隊(duì)自年月起啟動(dòng)了面向端用戶(hù)的赫爾墨斯項(xiàng)目。前端技術(shù)越來(lái)越復(fù)雜,有不低的技術(shù)門(mén)檻。 推薦 1. 利用 Dawn 工程化工具實(shí)踐 MobX 數(shù)據(jù)流管理方案 https://zhuanlan.zhihu.com/p/... 項(xiàng)目在最初應(yīng)用 MobX 時(shí),對(duì)較為復(fù)雜的多人協(xié)作項(xiàng)...

    madthumb 評(píng)論0 收藏0
  • 程序員筆記——如何編寫(xiě)優(yōu)雅Dockerfile

    摘要:導(dǎo)讀要從容器化開(kāi)始,而容器又需要從開(kāi)始,本文將介紹如何寫(xiě)出一個(gè)優(yōu)雅的文件。只要記住以上三點(diǎn)就能寫(xiě)出不錯(cuò)的。執(zhí)行完成項(xiàng)目的構(gòu)建。 導(dǎo)讀 Kubernetes要從容器化開(kāi)始,而容器又需要從Dockerfile開(kāi)始,本文將介紹如何寫(xiě)出一個(gè)優(yōu)雅的Dockerfile文件。 文章主要內(nèi)容包括: Docker容器 Dockerfile 使用多階構(gòu)建 感謝公司提供大量機(jī)器資源及時(shí)間讓我們可以實(shí)踐...

    曹金海 評(píng)論0 收藏0
  • JavaScript函數(shù)式編程,真香之組合(一)

    摘要:組合的概念是非常直觀的,并不是函數(shù)式編程獨(dú)有的,在我們生活中或者前端開(kāi)發(fā)中處處可見(jiàn)。其實(shí)我們函數(shù)式編程里面的組合也是類(lèi)似,函數(shù)組合就是一種將已被分解的簡(jiǎn)單任務(wù)組織成復(fù)雜的整體過(guò)程。在函數(shù)式編程的世界中,有這樣一種很流行的編程風(fēng)格。 JavaScript函數(shù)式編程,真香之認(rèn)識(shí)函數(shù)式編程(一) 該系列文章不是針對(duì)前端新手,需要有一定的編程經(jīng)驗(yàn),而且了解 JavaScript 里面作用域,閉...

    mengbo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<