寫給初中級前端的高級進(jìn)階指南

前言

我曾經(jīng)一度很迷茫,在學(xué)了 Vue闸昨、React 的實戰(zhàn)開發(fā)和應(yīng)用以后遭赂,好像遇到了一些瓶頸茄猫,不知道該怎樣繼續(xù)深入下去僻弹。相信這也是很多一兩年經(jīng)驗的前端工程師所遇到共同問題芭毙,這篇文章,筆者想結(jié)合自己的一些成長經(jīng)歷整理出一些路線侈百,幫助各位初中級前端工程師少走一些彎路。

這篇文章會提到非常非常多的學(xué)習(xí)路線和鏈接,如果你還在初中級的階段织咧,不必太焦慮庆锦,可以把這篇文章作為一個進(jìn)階的路線圖绿渣,在未來的時日里朝著這個方向努力就好誉帅。
我也并不是說這篇文章是進(jìn)階高級工程師的唯一一條路線蚜锨,如果你在業(yè)務(wù)上做的精進(jìn)档插,亦或是能在溝通上八面玲瓏,配合各方面力量把項目做的漂漂亮亮亚再,那你也一樣可以擁有這個頭銜郭膛。本文只是我自己的一個成長路線總結(jié)。

本篇文章面對的人群是開發(fā)經(jīng)驗1到3年的初中級前端工程師氛悬,希望能和你們交個心调煎。

已經(jīng)晉升高級前端的同學(xué)戈稿,歡迎你在評論區(qū)留下你的心得敷存,補(bǔ)充我的一些缺失和不足彻亲。

筆者本人 17 年畢業(yè)于一所普通的本科學(xué)校令野,20 年 6 月在三年經(jīng)驗的時候順利通過面試進(jìn)入大廠,職級是高級前端開發(fā)强重。

我的 github 地址志鹃,歡迎 follow非竿,我會持續(xù)更新一些值得你關(guān)注的項目些侍。

我的 blog 地址芦缰,這里會持續(xù)更新,點個 star 不失聯(lián)柬批!?

基礎(chǔ)能力

我整理了一篇中級前端的必備技術(shù)棧能力产徊,寫給女朋友的中級前端面試秘籍 。這篇文章里的技術(shù)棧當(dāng)然都是需要扎實掌握的酝碳,(其實我自己也有一些漏缺,偷偷補(bǔ)一下)包颁。

當(dāng)然了瞻想,上進(jìn)心十足的你不會一直滿足于做中級前端,我們要繼續(xù)向上娩嚼,升職加薪蘑险,迎娶白富美!

JavaScript

原生 js 系列

冴羽大佬的這篇博客里岳悟,除了 undescore 的部分佃迄,你需要全部都能掌握。并且靈活的運(yùn)用到開發(fā)中去贵少。
JavaScript 深入系列呵俏、JavaScript 專題系列、ES6 系列

完全熟練掌握 eventLoop滔灶。

tasks-microtasks-queues-and-schedules

Promise

  1. 你需要閱讀 Promise A+規(guī)范普碎,注意其中的細(xì)節(jié),并且靈活的運(yùn)用到開發(fā)當(dāng)中去录平。
    Promise A+ 英文文檔

  2. 你需要跟著精品教程手寫一遍 Promise麻车,對里面的細(xì)節(jié)深入思考,并且把其中異步等待萄涯、錯誤處理等等細(xì)節(jié)融會貫通到你的開發(fā)思想里去绪氛。
    剖析 Promise 內(nèi)部結(jié)構(gòu),一步一步實現(xiàn)一個完整的涝影、能通過所有 Test case 的 Promise 類

  3. 最后枣察,對于 promise 的核心,異步的鏈?zhǔn)秸{(diào)用燃逻,你必須能寫出來簡化版的代碼序目。
    最簡實現(xiàn) Promise,支持異步鏈?zhǔn)秸{(diào)用(20 行)

題外話伯襟,當(dāng)時精煉這 20 行真的繞了我好久 ??猿涨,但是搞明白了會有種恍然大悟的感覺。這種異步隊列的技巧要融會貫通姆怪。

async await

對于 Promise 我們非常熟悉了叛赚,進(jìn)一步延伸到 async await澡绩,這是目前開發(fā)中非常非常常用的異步處理方式,我們最好是熟悉它的 babel 編譯后的源碼俺附。

手寫 async await 的最簡實現(xiàn)(20 行搞定)
babel 對于 async await 配合 generator 函數(shù)肥卡,做的非常巧妙,這里面的思想我們也要去學(xué)習(xí)事镣,如何遞歸的處理一個串行的 promise 鏈步鉴?

這個技巧在axios 的源碼里也有應(yīng)用。平常經(jīng)常用的攔截器璃哟,本質(zhì)上就是一串 promise 的串行執(zhí)行氛琢。

當(dāng)然,如果你還有余力的話随闪,也可以繼續(xù)深入的去看 generator 函數(shù)的 babel 編譯源碼阳似。不強(qiáng)制要求,畢竟 generator 函數(shù)在開發(fā)中已經(jīng)用的非常少了蕴掏。
ES6 系列之 Babel 將 Generator 編譯成了什么樣子

異常處理

你必須精通異步場景下的錯誤處理障般,這是高級工程師必備的技能,如果開發(fā)中的異常被你寫的庫給吞掉了盛杰,那豈不是可笑。
Callback Promise Generator Async-Await 和異常處理的演進(jìn)

插件機(jī)制

你需要大概理解前端各個庫中的插件機(jī)制是如何實現(xiàn)的藐石,在你自己開發(fā)一些庫的時候也能融入自己適合的插件機(jī)制即供。
Koa 的洋蔥中間件,Redux 的中間件于微,Axios 的攔截器讓你迷惑嗎逗嫡?實現(xiàn)一個精簡版的就徹底搞懂了。

設(shè)計模式

對于一些復(fù)雜場景株依,你的開發(fā)不能再是if else嵌套一把梭了驱证,你需要把設(shè)計模式好好看一遍,在合適的場景下選擇合適的設(shè)計模式恋腕。這里就推薦掘金小冊吧抹锄,相信這篇小冊會讓你的工程能力得到質(zhì)的飛躍,舉例來說荠藤,在 Vue 的源碼中就用到了觀察者模式伙单、發(fā)布訂閱模式策略模式哈肖、適配器模式吻育、發(fā)布訂閱模式工廠模式淤井、組合模式布疼、代理模式摊趾、門面模式等等。

而這些設(shè)計模式如果你沒學(xué)習(xí)過可能很難想到如何應(yīng)用在工程之中游两,但是如果你學(xué)習(xí)過严就,它就變成了你內(nèi)在的工程能力,往大了說器罐,也可以是架構(gòu)能力的一部分梢为。

在《設(shè)計模式》這本小冊中我們提到過,即使是在瞬息萬變的前端領(lǐng)域轰坊,也存在一些具備“一次學(xué)習(xí)铸董,終生受用”特性的知識。從工程的角度看肴沫,我推薦大家著重學(xué)習(xí)的是設(shè)計模式粟害。 -修言

這里推薦掘金修言的設(shè)計模式小冊

開發(fā)思想

有時候組合是優(yōu)于繼承的颤芬,不光是面向?qū)ο缶幊炭梢詫崿F(xiàn)復(fù)用悲幅,在某些場景下,組合的思想可能會更加簡潔優(yōu)雅站蝠。

https://medium.com/javascript-scene/master-the-javascript-interview-what-s-the-difference-between-class-prototypal-inheritance-e4cd0a7562e9

“…the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” ~ Joe Armstrong — “Coders at Work”

面向?qū)ο笳Z言的問題在于它們帶來了所有這些隱含的環(huán)境汰具。
你想要一個香蕉,但你得到的是拿著香蕉和整個叢林的大猩猩菱魔。

代碼規(guī)范

你需要熟讀 clean-code-javascript留荔,并且深入結(jié)合到日常開發(fā)中,結(jié)合你們小組的場景制定自己的規(guī)范澜倦。
clean-code-javascript

算法

算法這里我就不推薦各種小冊聚蝶,筆記,博文了藻治。因為從我自己學(xué)習(xí)算法的經(jīng)驗來看碘勉,在沒有太多的算法基礎(chǔ)的情況下,文章基本上是很難真正的看進(jìn)去并理解的桩卵,這里只推薦慕課網(wǎng) bobo 老師的 LeetCode 真題課程验靡,在這個課程里算法大牛 bobo 老師會非常細(xì)心的把各個算法做成動圖,由淺入深給你講解各種分類的 LeetCode 真題吸占。這是我最近學(xué)到的最有收獲的一門課程了晴叨。

由于這門課程是 C++ 為主要語言的(不影響理解課程),我也針對此課程維護(hù)了一個對應(yīng)的 JavaScript 版題解倉庫矾屯,在 Issue 里也根據(jù)標(biāo)簽分類整理了各個題型的講解兼蕊,歡迎 Star ?。

算法對于前端來說重要嗎件蚕?也許你覺得做題沒用孙技,但是我個人在做題后并且分門別類的整理好各個題型的思路和解法后产禾,是能真切的感覺到自己的代碼能力在飛速提高的。

對于很多覺得自己不夠聰明牵啦,不敢去學(xué)習(xí)算法的同學(xué)來說亚情,推薦 bobo 老師的這篇《天生不聰明》,也正是這篇文章激勵我開始了算法學(xué)習(xí)的旅程哈雏。

在這里列一下前端需要掌握的基礎(chǔ)算法知識楞件,希望能給你一個路線:

  1. 算法的復(fù)雜度分析。
  2. 排序算法裳瘪,以及他們的區(qū)別和優(yōu)化土浸。
  3. 數(shù)組中的雙指針、滑動窗口思想彭羹。
  4. 利用 Map 和 Set 處理查找表問題黄伊。
  5. 鏈表的各種問題。
  6. 利用遞歸和迭代法解決二叉樹問題派殷。
  7. 棧还最、隊列、DFS毡惜、BFS拓轻。
  8. 回溯法、貪心算法虱黄、動態(tài)規(guī)劃悦即。

算法是底層的基礎(chǔ),把地基打扎實后橱乱,會讓你在后續(xù)的職業(yè)生涯中大受裨益的。

框架篇

對于高級工程師來說粱甫,你必須要有一個你趁手的框架泳叠,它就像你手中的一把利劍,能夠讓你披荊斬棘茶宵,斬殺各種項目于馬下危纫。

下面我會分為VueReact兩個方面深入去講。

Vue

Vue 方面的話乌庶,我主要是師從黃軼老師种蝶,跟著他認(rèn)真走,基本上在 Vue 這方面你可以做到基本無敵瞒大。

熟練運(yùn)用

  1. 對于 Vue 你必須非常熟練的運(yùn)用螃征,官網(wǎng)的 api 你基本上要全部過一遍。并且你要利用一些高級的 api 去實現(xiàn)巧妙的封裝透敌。舉幾個簡單的例子盯滚。

  2. 你要知道怎么用slot-scope去做一些數(shù)據(jù)和 ui 分離的封裝踢械。
    vue-promised這個庫為例。
    Promised 組件并不關(guān)注你的視圖展示成什么樣魄藕,它只是幫你管理異步流程内列,并且通過你傳入的slot-scope,在合適的時機(jī)把數(shù)據(jù)回拋給你背率,并且?guī)湍闳フ故灸銈魅氲囊晥D话瞧。

<template>
  <Promised :promise="usersPromise">
    <!-- Use the "pending" slot to display a loading message -->
    <template v-slot:pending>
      <p>Loading...</p>
    </template>
    <!-- The default scoped slot will be used as the result -->
    <template v-slot="data">
      <ul>
        <li v-for="user in data">{{ user.name }}</li>
      </ul>
    </template>
    <!-- The "rejected" scoped slot will be used if there is an error -->
    <template v-slot:rejected="error">
      <p>Error: {{ error.message }}</p>
    </template>
  </Promised>
</template>
  1. 你需要熟練的使用Vue.extends,配合項目做一些命令式api的封裝寝姿。并且知道它為什么可以這樣用交排。(需要具備源碼知識)
    confirm 組件
export const confirm = function (text, title, onConfirm = () => {}) {
  if (typeof title === "function") {
    onConfirm = title;
    title = undefined;
  }
  const ConfirmCtor = Vue.extend(Confirm);
  const getInstance = () => {
    if (!instanceCache) {
      instanceCache = new ConfirmCtor({
        propsData: {
          text,
          title,
          onConfirm,
        },
      });
      // 生成dom
      instanceCache.$mount();
      document.body.appendChild(instanceCache.$el);
    } else {
      // 更新屬性
      instanceCache.text = text;
      instanceCache.title = title;
      instanceCache.onConfirm = onConfirm;
    }
    return instanceCache;
  };
  const instance = getInstance();
  // 確保更新的prop渲染到dom
  // 確保動畫效果
  Vue.nextTick(() => {
    instance.visible = true;
  });
};
  1. 你要開始使用JSX來編寫你項目中的復(fù)雜組件了,比如在我的網(wǎng)易云音樂項目中会油,我遇到了一個復(fù)雜的音樂表格需求个粱,支持搜索文字高亮、動態(tài)隱藏列等等翻翩。
    當(dāng)然對于現(xiàn)在版本的 Vue都许,JSX 還是不太好用,有很多屬性需要寫嵌套對象嫂冻,這會造成很多不必要的麻煩胶征,比如沒辦法像 React 一樣直接把外層組件傳入的 props 透傳下去,Vue3 的 rfc 中提到會把 vnode 節(jié)點的屬性進(jìn)一步扁平化桨仿,我們期待得到接近于 React 的完美 JSX 開發(fā)體驗吧睛低。

  2. 你要深入了解 Vue 中 nextTick 的原理姥芥,并且知道為什么要用微任務(wù)隊列優(yōu)于宏任務(wù)隊列仍稀,結(jié)合你的 eventloop 知識深度思考藏姐。最后融入到你的異步合并優(yōu)化的知識體系中去摆出。
    Vue 源碼詳解之 nextTick:MutationObserver 只是浮云咱娶,microtask 才是核心席函!

  3. 你要能理解 Vue 中的高階組件求摇。關(guān)于這篇文章中為什么 slot-scope 不生效的問題峰鄙,你不能看他的文章講解都一頭霧水灿椅。(需要你具備源碼知識)
    探索 Vue 高階組件 | HcySunYang

  4. 推薦一下我自己總結(jié)的 Vue 高階組件文章套蒂,里面涉及到了一些進(jìn)階的用法。
    Vue 進(jìn)階必學(xué)之高階組件 HOC

  5. 對于 Vuex 的使用必須非常熟練茫蛹,知道什么時候該用 Vuex操刀,知道怎么根據(jù)需求去編寫 Vuex 的 plugin,合理的去使用 Vuex 的 subscribe 功能完成一些全局維度的封裝婴洼,比如我對于 Vuex 中 action 的錯誤處理懶得一個個去try catch骨坑,就封裝了一個vuex-error-plugin。代碼很簡單窃蹋,重要的是去理解為什么能這樣做卡啰。這里用了 monkey patch 的做法静稻,并不是很好的實踐,僅以此作為引子匈辱。

  6. 對于 vue-router 的使用必須非常熟練振湾,知道什么需求需要利用什么樣的 router 鉤子,這樣才能 hold 住一個大型的項目亡脸,這個我覺得官方倉庫里的進(jìn)階中文文檔其實很好押搪,不知道為什么好像沒放在官網(wǎng)。
    vue-router-advanced

  7. 理解虛擬 DOM 的本質(zhì)浅碾,虛擬 DOM 一定比真實 DOM 更快嗎大州?這篇是尤雨溪的回答,看完這個答案垂谢,相信你會對虛擬 DOM 有更進(jìn)一步的認(rèn)識和理解厦画。
    網(wǎng)上都說操作真實 DOM 慢,但測試結(jié)果卻比 React 更快滥朱,為什么根暑?

源碼深入

  1. 你不光要熟練運(yùn)用 Vue,由于 Vue 的源碼寫的非常精美徙邻,而且閱讀難度不是非常大排嫌,很多人也選擇去閱讀 Vue 的源碼。視頻課這里推薦黃軼老師的 Vue 源碼課程缰犁。這里也包括了 Vuex 和 vue-router 的源碼淳地。
    Vue.js 源碼全方位深入解析 (含 Vue3.0 源碼分析)

  2. 推薦 HcySunYang 大佬的 Vue 逐行分析,需要下載 git 倉庫帅容,切到 elegant 分支自己本地啟動颇象。
    Vue 逐行級別的源碼分析

  3. 當(dāng)然,這個倉庫的 master 分支也是寶藏并徘,是這個作者的渲染器系列文章夯到,脫離框架講解了 vnode 和 diff 算法的本質(zhì)
    組件的本質(zhì)

Vue3 展望

  1. Vue3 已經(jīng)發(fā)布了 Beta 版本,你可以提前學(xué)習(xí)Hook相關(guān)的開發(fā)模式了饮亏。這里推薦一下我寫的這篇 Vue3 相關(guān)介紹:
    Vue3 究竟好在哪里?(和 React Hook 的詳細(xì)對比)

Vue3 源碼

對于響應(yīng)式部分阅爽,如果你已經(jīng)非常熟悉 Vue2 的響應(yīng)式原理了路幸,那么 Vue3 的響應(yīng)式原理對你來說應(yīng)該沒有太大的難度。甚至在學(xué)習(xí)之中你會相互比較付翁,知道 Vue3 為什么這樣做更好简肴,Vue2 還有哪部分需要改進(jìn)等等。

Vue3 其實就是把實現(xiàn)換成了更加強(qiáng)大的 Proxy百侧,并且把響應(yīng)式部分做的更加的抽象砰识,甚至可以能扒,不得不說,Vue3 的響應(yīng)式模型更加接近響應(yīng)式類庫的核心了辫狼,甚至react-easy-state等 React 的響應(yīng)式狀態(tài)管理庫初斑,也是用這套類似的核心做出來的。

再次強(qiáng)調(diào)膨处,非常非常推薦學(xué)習(xí) Vue3 的@vue/reactivity這個分包见秤。

推一波自己的文章吧,細(xì)致了講解了 Vue3 響應(yīng)式的核心流程真椿。

  1. 帶你徹底搞懂 Vue3 的 Proxy 響應(yīng)式原理鹃答!TypeScript 從零實現(xiàn)基于 Proxy 的響應(yīng)式庫。

  2. 帶你徹底搞懂 Vue3 的 Proxy 響應(yīng)式原理突硝!基于函數(shù)劫持實現(xiàn) Map 和 Set 的響應(yīng)式

  3. 深度解析:Vue3 如何巧妙的實現(xiàn)強(qiáng)大的 computed

在學(xué)習(xí)之后测摔,我把@vue/reactivity包輕松的集成到了 React 中,做了一個狀態(tài)管理的庫解恰,這也另一方面佐證了這個包的抽象程度:
40 行代碼把 Vue3 的響應(yīng)式集成進(jìn) React 做狀態(tài)管理

React

React 已經(jīng)進(jìn)入了 Hook 為主的階段锋八,社區(qū)的各個庫也都在積極擁抱 Hook,雖然它還有很多陷阱和不足修噪,但是這基本上是未來的方向沒跑了查库。這篇文章里我會減少 class 組件的開發(fā)技巧的提及,畢竟好多不錯的公司也已經(jīng)全面擁抱 Hook 了黄琼。

熟練應(yīng)用

  1. 你必須掌握官網(wǎng)中提到的所有技巧樊销,就算沒有使用過,你也要大概知道該在什么場景使用脏款。

  2. 推薦 React 小書围苫,雖然書中的很多 api 已經(jīng)更新了,但是核心的設(shè)計思想還是沒有變
    React.js 小書

  3. 關(guān)于熟練應(yīng)用撤师,其實掘金的小冊里有幾個寶藏

    1. 誠身大佬(悄悄告訴你剂府,他的職級非常高)的企業(yè)級管理系統(tǒng)小冊,這個項目里的代碼非常深入剃盾,而且在抽象和優(yōu)化方面也做的無可挑剔腺占,自己抽象了acl權(quán)限管理系統(tǒng)和router路由管理,并且引入了reselect做性能優(yōu)化痒谴,一年前我初次讀的時候衰伯,很多地方懵懵懂懂,這一年下來我也從無到有經(jīng)手了一套帶acl權(quán)限路由的管理系統(tǒng)后积蔚,才知道他的抽象能力有多強(qiáng)意鲸。真的是

      初聞不知曲中意,再聞已是曲中人。

      React 組合式開發(fā)實踐:打造企業(yè)管理系統(tǒng)五大核心模塊

    2. 三元大佬的 React Hooks 與 Immutable 數(shù)據(jù)流實戰(zhàn)怎顾,深入淺出的帶你實現(xiàn)一個音樂播放器读慎。三元大家都認(rèn)識吧?那是神槐雾,神帶你們寫應(yīng)用項目夭委,不學(xué)能說得過去嗎?
      React Hooks 與 Immutable 數(shù)據(jù)流實戰(zhàn)

  4. 深入理解 React 中的key
    understanding-reacts-key-prop

    react 中為何推薦設(shè)置 key

  5. React 官方團(tuán)隊成員對于派生狀態(tài)的思考:
    you-probably-dont-need-derived-state

React Hook

你必須熟練掌握 Hook 的技巧蚜退,除了官網(wǎng)文檔熟讀以外:

  1. 推薦 Dan 的博客闰靴,他就是 Hook 的代碼實際編寫者之一,看他怎么說夠權(quán)威了吧钻注?這里貼心的送上漢化版蚂且。
    useEffect 完整指南
    看完這篇以后,進(jìn)入dan 的博客主頁幅恋,找出所有和 Hook 有關(guān)的杏死,全部精讀!

  2. 推薦黃子毅大佬的精讀周刊系列
    096.精讀《useEffect 完全指南》.md
    注意捆交!不是只看這一篇淑翼,而是這個倉庫里所有有關(guān)于 React Hook 的文章都去看一遍,結(jié)合自己的思想分析品追。

  3. Hook 陷阱系列
    還是 Dan 老哥的文章玄括,詳細(xì)的講清楚了所謂閉包陷阱產(chǎn)生的原因和設(shè)計中的權(quán)衡。
    函數(shù)式組件與類組件有何不同肉瓦?

  4. 去找一些社區(qū)的精品自定義 hook遭京,看看他們的開發(fā)和設(shè)計思路,有沒有能融入自己的日常開發(fā)中去的泞莉。
    精讀《Hooks 取數(shù) - swr 源碼》
    Umi Hooks - 助力擁抱 React Hooks
    React Hooks 的體系設(shè)計之一 - 分層

React 性能優(yōu)化

React 中優(yōu)化組件重渲染哪雕,這里有幾個隱含的知識點。
optimize-react-re-renders

如何對 React 函數(shù)式組件進(jìn)行性能優(yōu)化鲫趁?這篇文章講的很詳細(xì)斯嚎,值得仔細(xì)閱讀一遍。
如何對 React 函數(shù)式組件進(jìn)行優(yōu)化

React 單元測試

  1. 使用@testing-library/react測試組件挨厚,這個庫相比起 enzyme 更好的原因在于堡僻,它更注重于站在用戶的角度去測試一個組件,而不是測試這個組件的實現(xiàn)細(xì)節(jié)疫剃。
    Introducing The React Testing Library
    Testing Implementation Details

  2. 使用@testing-library/react-hooks測試自定義 Hook
    how-to-test-custom-react-hooks

React 和 TypeScript 結(jié)合使用

  1. 這個倉庫非常詳細(xì)的介紹了如何把 React 和 TypeScript 結(jié)合苦始,并且給出了一些進(jìn)階用法的示例,非常值得過一遍慌申!
    react-typescript-cheatsheet

  2. 這篇文章是螞蟻金服數(shù)據(jù)體驗技術(shù)部的同學(xué)帶來的,其實除了這里面的技術(shù)文章以外,螞蟻金服的同學(xué)也由非常生動給我們講解了一個高級前端同學(xué)是如何去社區(qū)尋找方案蹄溉,如何思考和落地到項目中的咨油,由衷的佩服。
    React + Typescript 工程化治理實踐

  3. 微軟的大佬帶你寫一個類型安全的組件柒爵,非常深入役电,非常過癮...
    Writing Type-Safe Polymorphic React Components (Without Crashing TypeScript)

  4. React + TypeScript 10 個需要避免的錯誤模式。
    10-typescript-pro-tips-patterns-with-or-without-react

React 代碼抽象思考

  1. 何時應(yīng)該把代碼拆分為組件棉胀?
    when-to-break-up-a-component-into-multiple-components

  2. 仔細(xì)思考你的 React 應(yīng)用中法瑟,狀態(tài)應(yīng)該放在什么位置,是組件自身唁奢,提升到父組件霎挟,亦或是局部 context 和 redux,這會有益于提升應(yīng)用的性能和可維護(hù)性麻掸。
    state-colocation-will-make-your-react-app-faster

  3. 仔細(xì)思考 React 組件中的狀態(tài)應(yīng)該如何管理酥夭,優(yōu)先使用派生狀態(tài),并且在適當(dāng)?shù)臅r候利用 useMemo脊奋、reselect 等庫去優(yōu)化他們熬北。
    dont-sync-state-derive-it

  4. React Hooks 的自定義 hook 中,如何利用 reducer 的模式提供更加靈活的數(shù)據(jù)管理诚隙,讓用戶擁有數(shù)據(jù)的控制權(quán)讶隐。
    the-state-reducer-pattern-with-react-hooks

TypeScript

自從 Vue3 橫空出世以來,TypeScript 好像突然就火了久又。這是一件好事巫延,推動前端去學(xué)習(xí)強(qiáng)類型語言,開發(fā)更加嚴(yán)謹(jǐn)籽孙。并且第三方包的 ts 類型支持的加入烈评,讓我們甚至很多時候都不再需要打開文檔對著 api 擼了。

關(guān)于 TypeScript 學(xué)習(xí)犯建,其實幾個月前我還對于這門 JavaScript 的超集一竅不通讲冠,經(jīng)過兩三個月的靜心學(xué)習(xí),我能夠去理解一些相對復(fù)雜的類型了适瓦,

可以說 TypeScript 的學(xué)習(xí)和學(xué)一個庫或者學(xué)一個框架是完全不同的竿开,

入門

  1. 除了官方文檔以外,還有一些比較好的中文入門教程玻熙。
    TypeScript Handbook 入門教程

  2. TypeScript Deep Dive 非常高質(zhì)量的英文入門教學(xué)否彩。
    TypeScript Deep Dive

  3. 工具泛型在日常開發(fā)中都非常的常用,必須熟練掌握嗦随。
    TS 一些工具泛型的使用及其實現(xiàn)

  4. 視頻課程列荔,還是黃軼大佬的敬尺,并且這個課程對于單元測試、前端手寫框架贴浙、以及網(wǎng)絡(luò)請求原理都非常有幫助砂吞。
    基于 TypeScript 從零重構(gòu) axios

進(jìn)階

  1. 這五篇文章里借助非常多的案例,為我們講解了 ts 的一些高級用法崎溃,請務(wù)必反復(fù)在 ide 里嘗試蜻直,理解,不懂的概念及時回到文檔中補(bǔ)習(xí)袁串。
    巧用 TypeScript 系列 一共五篇

  2. TS 進(jìn)階非常重要的一點概而,條件類型,很多泛型推導(dǎo)都需要借助它的力量囱修。
    conditional-types-in-typescript

  3. 以及上面那個大佬博客中的所有 TS 文章赎瑰。
    https://mariusschulz.com

實戰(zhàn)

  1. 一個參數(shù)簡化的實戰(zhàn),涉及到的高級知識點非常多蔚袍。

    1. ??TypeScript 的高級類型(Advanced Type)
    2. ??Conditional Types (條件類型)
    3. ??Distributive conditional types (分布條件類型)
    4. ??Mapped types(映射類型)
    5. ?? 函數(shù)重載
      TypeScript 參數(shù)簡化實戰(zhàn)
  2. 實現(xiàn)一個簡化版的 Vuex乡范,同樣知識點結(jié)合滿滿。

    1. ??TypeScript 的高級類型(Advanced Type
    2. ??TypeScript 中利用泛型進(jìn)行反向類型推導(dǎo)啤咽。(Generics)
    3. ??Mapped types(映射類型)
    4. ??Distributive Conditional Types(條件類型分配)
    5. ??TypeScript 中 Infer 的實戰(zhàn)應(yīng)用(Vue3 源碼里 infer 的一個很重要的使用
      TS 實現(xiàn)智能類型推導(dǎo)的簡化版 Vuex

刻意訓(xùn)練

它幾乎是一門新的語言(在類型世界里來說)晋辆,需要你花費(fèi)很大的精力去學(xué)好它。

我對于 TypeScript 的學(xué)習(xí)建議其實就是一個關(guān)鍵詞:刻意訓(xùn)練宇整,在過基礎(chǔ)概念的時候瓶佳,不厭其煩的在vscode中敲擊,理解鳞青,思考霸饲。在基礎(chǔ)概念過完以后去尋找實踐文章,比如我上面進(jìn)階實戰(zhàn)部分推薦的幾篇臂拓,繼續(xù)刻意訓(xùn)練厚脉,一定要堆積代碼量,學(xué)習(xí)一門新的語言是不可能靠看文檔獲得成功的胶惰。

我會建立一個倉庫傻工,專門記錄我遇到的TypeScript 的有趣代碼,自己動手敲一遍孵滞,并且深入理解中捆。

能力分級

其實 TypeScript 的能力也是兩級分化的,日常寫業(yè)務(wù)來說坊饶,你定義一些 interface泄伪,配合 React.FC 這種官方內(nèi)置的類型也就跑通了,沒什么特別難的點匿级。

但是如果是造輪子呢蟋滴?如果你自己寫了一個工具庫染厅,并且類型比較復(fù)雜,你能保證推導(dǎo)出來嗎脓杉?亦或者就拿 Vue3 來說糟秘,ref 是一個很復(fù)雜的嵌套類型,

假如我們這樣定義一個值const value = ref(ref(2))球散,對于嵌套的 ref,Vue3 會做一層拆包散庶,也就是說其實ref.value會是 2蕉堰,

那么它是如何讓 ts 提示出 value 的類型是 number 的呢?

如果你看到源碼里的這段代碼悲龟,你只有基礎(chǔ)的話屋讶,保證懵逼。
Vue3 跟著尤雨溪學(xué) TypeScript 之 Ref 類型從零實現(xiàn)

// Recursively unwraps nested value bindings.
export type UnwrapRef<T> = {
  cRef: T extends ComputedRef<infer V> ? UnwrapRef<V> : T
  ref: T extends Ref<infer V> ? UnwrapRef<V> : T
  array: T
  object: { [K in keyof T]: UnwrapRef<T[K]> }
}[T extends ComputedRef<any>
  ? 'cRef'
  : T extends Array<any>
    ? 'array'
    : T extends Ref | Function | CollectionTypes | BaseTypes
      ? 'ref' // bail out on types that shouldn't be unwrapped
      : T extends object ? 'object' : 'ref']
業(yè)務(wù)開發(fā)人員

如果短期內(nèi)你對自己的要求是能上手業(yè)務(wù)须教,那么你理解 TypeScript 基礎(chǔ)的interfacetype編寫和泛型的普通使用(可以理解為類型系統(tǒng)里的函數(shù)傳參)也已經(jīng)足夠皿渗。

框架開發(fā)人員

但是長期來看,如果你的目的是能夠自己編寫一些類型完善的庫或框架轻腺,或者說你在公司扮演前端架構(gòu)師乐疆、輪子專家等等角色,經(jīng)常需要寫一些偏底層的庫給你的小伙伴們使用贬养,那么你必須深入學(xué)習(xí)挤土,這樣才能做到給你的框架使用用戶完美的類型體驗。

面試題

TypeScript 相關(guān)的面試題我見得不多误算,不過力扣中國的面試題算是難度偏高的仰美,其中有一道 TS 的面試題,可以說是實用性和難度都有所兼顧儿礼,簡單來說就是解包咖杂。

// 解開參數(shù)和返回值中的Promise
asyncMethod<T, U>(input: Promise<T>): Promise<Action<U>>
 ↓
asyncMethod<T, U>(input: T): Action<U>

// 解開參數(shù)中的Action
syncMethod<T, U>(action: Action<T>): Action<U>
 ↓
syncMethod<T, U>(action: T): Action<U>

我在高強(qiáng)度學(xué)習(xí)了兩三個月 TS 的情況下,已經(jīng)能把這道題目相對輕松的解出來蚊夫,相信這也是說明我的學(xué)習(xí)路線沒有走偏(題解就不放了诉字,尊重面試題,其實就是考察了映射類型infer的使用)这橙。
力扣面試題

代碼質(zhì)量

代碼風(fēng)格

  1. 在項目中集成 Prettier + ESLint + Airbnb Style Guide
    integrating-prettier-eslint-airbnb-style-guide-in-vscode

  2. 在項目中集成 ESLint with Prettier, TypeScript

高質(zhì)量架構(gòu)

  1. 如何重構(gòu)一個過萬 Star 開源項—BetterScroll奏窑,是由滴滴的大佬嵇智所帶來的,無獨(dú)有偶的是屈扎,這篇文章除了詳細(xì)的介紹一個合格的開源項目應(yīng)該做到的代碼質(zhì)量保證埃唯,測試流程,持續(xù)集成流程以外鹰晨,也體現(xiàn)了他的一些思考深度墨叛,非常值得學(xué)習(xí)止毕。
    如何重構(gòu)一個過萬 Star 開源項目—BetterScroll

Git 提交信息

  1. 很多新手在提交 Git 信息的時候會寫的很隨意,比如fix漠趁、test扁凛、修復(fù),這么糊弄的話是會被 leader 揍的闯传!

    [譯]如何撰寫 Git 提交信息

    Git-Commit-Log 規(guī)范(Angular 規(guī)范)

    commitizen規(guī)范流程的 commit 工具谨朝,規(guī)范的 commit 格式也會讓工具幫你生成友好的changelog

構(gòu)建工具

  1. webpack 基礎(chǔ)和優(yōu)化
    深入淺出 webpack
  2. 滴滴前端工程師的 webpack 深入源碼分析系列,非常的優(yōu)秀甥绿。
    webpack 系列之一總覽

性能優(yōu)化

  1. 推薦修言大佬的性能優(yōu)化小冊字币,這個真的是講的深入淺出,從webpack網(wǎng)絡(luò)dom操作共缕,全方位的帶你做一些性能優(yōu)化實戰(zhàn)洗出。這本小冊我當(dāng)時看的時候真的是完全停不下來,修言大佬的風(fēng)格既輕松又幽默图谷。但是講解的東西卻能讓你受益匪淺翩活。

  2. 谷歌開發(fā)者性能優(yōu)化章節(jié),不用多說了吧便贵?很權(quán)威了菠镇。左側(cè)菜單欄里還有更多相關(guān)內(nèi)容,可以按需選擇學(xué)習(xí)嫉沽。
    user-centric-performance-metrics

  3. 詳談合成層辟犀,合成層這個東西離我們忽遠(yuǎn)忽近,可能你的一個不小心的操作就造成層爆炸绸硕,當(dāng)然需要仔細(xì)關(guān)注啦堂竟。起碼,在性能遇到瓶頸的時候玻佩,你可以打開 chrome 的layer面板出嘹,看看你的頁面到底是怎么樣的一個層分布。
    詳談層合成(composite)

  4. 劉博文大佬的性能優(yōu)化指南咬崔,非常清晰的講解了網(wǎng)頁優(yōu)化的幾個重要的注意點税稼。
    讓你的網(wǎng)頁更絲滑

社區(qū)討論

作為一個合格的前端工程師,一定要積極的深入社區(qū)去了解最新的動向垮斯,比如在twitter上關(guān)注你喜歡的技術(shù)開發(fā)人員郎仆,如 Dan、尤雨溪兜蠕。

另外 Github 上的很多 issue 也是寶藏討論扰肌,我就以最近我對于 Vue3 的學(xué)習(xí)簡單的舉幾個例子。

為什么 Vue3 不需要時間切片熊杨?

尤雨溪解釋關(guān)于為什么在 Vue3 中不加入 React 時間切片功能曙旭?并且詳細(xì)的分析了 React 和 Vue3 之間的一些細(xì)節(jié)差別盗舰,狠狠的吹了一波 Vue3(愛了愛了)。
Why remove time slicing from vue3?

Vue3 的composition-api到底好在哪桂躏?

Vue3 的 functional-api 相關(guān)的 rfc钻趋,尤大舌戰(zhàn)群儒,深入淺出的為大家講解了 Vue3 的設(shè)計思路等等剂习。
Amendment proposal to Function-based Component API

Vue3composition-api的第一手文檔

vue-composition-api 的 rfc 文檔蛮位,在國內(nèi)資料還不齊全的情況下,我去閱讀了
vue-composition-api-rfc 英文版文檔鳞绕,對于里面的設(shè)計思路嘆為觀止土至,學(xué)到了非常非常多尤大的思想。

總之猾昆,對于你喜歡的倉庫,都可以去看看它的 issue 有沒有看起來感興趣的討論骡苞,你也會學(xué)到非常多的東西垂蜗。并且你可以和作者保持思路上的同步,這是非常難得的一件事情解幽。

關(guān)于 Hook 的一些收獲

我在狠狠的吸收了一波尤大對于 Vue3 composition-api的設(shè)計思路的講解贴见,新舊模式的對比以后,這篇文章就是我對 Vue3 新模式的一些見解躲株。
Vue3 Composition-Api + TypeScript + 新型狀態(tài)管理模式探索片部。

在 Vue2 里,可以通過plugin先體驗composition-api霜定,截取這篇文章對應(yīng)的實戰(zhàn)項目中的一小部分代碼吧:

<template>
  <Books :books="booksAvaluable" :loading="loading" />
</template>

<script lang="ts">
import { createComponent } from '@vue/composition-api';
import Books from '@/components/Books.vue';
import { useAsync } from '@/hooks';
import { getBooks } from '@/hacks/fetch';
import { useBookListInject } from '@/context';
export default createComponent({
  name: 'books',
  setup() {
    const { books, setBooks, booksAvaluable } = useBookListInject();
    const loading = useAsync(async () => {
      const requestBooks = await getBooks();
      setBooks(requestBooks);
    });
    return { booksAvaluable, loading };
  },
  components: {
    Books,
  },
});
</script>

<style>
.content {
  max-width: 700px;
  margin: auto;
}
</style>

本實戰(zhàn)對應(yīng)倉庫:

vue-bookshelf

并且由于它和React Hook在很多方面的思想也非常相近档悠,這甚至對于我在React Hook上的使用也大有裨益,比如代碼組織的思路上望浩,

在第一次使用Hook開發(fā)的時候辖所,大部分人可能還是會保留著以前的思想,把state集中起來定義在代碼的前一大段磨德,把computed集中定義在第二段缘回,把mutation定義在第三段,如果不看尤大對于設(shè)計思想的講解典挑,我也一直是在這樣做酥宴。

但是為什么 Logical Concerns 優(yōu)于 Vue2 和 React Class Component 的 Option Types?看完detailed-design這個章節(jié)你就全部明白了您觉,并且這會融入到你日常開發(fā)中去拙寡。

總之,看完這篇以后顾犹,我果斷的把公司里的首屏組件的一坨代碼直接抽成了 n 個自定義 hook倒庵,維護(hù)效率提升簡直像是坐火箭褒墨。

當(dāng)然,社區(qū)里的寶藏 issue 肯定不止這些擎宝,我只是簡單的列出了幾個郁妈,但就是這幾個都讓我的技術(shù)視野開闊了很多,并且是真正的融入到公司的業(yè)務(wù)實戰(zhàn)中去绍申,是具有業(yè)務(wù)價值的噩咪。希望你養(yǎng)成看 issue,緊跟英文社區(qū)的習(xí)慣极阅,Github issue 里單純的技術(shù)探討氛圍胃碾,真的是國內(nèi)很少有社區(qū)可以媲美的。

function AppInner({ children }) {
  const [menus, setMenus] = useState({});

  // 用戶信息
  const user = useUser();

  // 主題能力
  useTheme();

  // 權(quán)限獲取
  useAuth({
    setMenus,
  });

  // 動態(tài)菜單也需要用到菜單的能力
  useDynamicMenus({
    menus,
    setMenus,
  });

  return (
    <Context.Provider value={user}>
      <Layout routers={backgrounds}>{children}</Layout>
    </Context.Provider>
  );
}

可以看到筋搏,Hook在代碼組織的方面有著得天獨(dú)厚的優(yōu)勢仆百,甚至各個模塊之間值的傳遞都是那么的自然,僅僅是函數(shù)傳參而已奔脐。
總之俄周,社區(qū)推出一些新的東西,它總歸是解決了之前的一些痛點髓迎。我們跟著大佬的思路走峦朗,一定有肉吃。

Tree Shaking 的 Issue

相學(xué)長的文章你的 Tree-Shaking 并沒什么卵用中排龄,也詳細(xì)的描述了他對于副作用的一些探尋過程波势,在UglifyJS 的 Issue中找到了最終的答案,然后貢獻(xiàn)給中文社區(qū)橄维,這些內(nèi)容最開始不會在任何中文社區(qū)里出現(xiàn)尺铣,只有靠你去探尋和發(fā)現(xiàn)。

學(xué)習(xí)方法的轉(zhuǎn)變

從初中級前端開始往高級前端進(jìn)階挣郭,有一個很重要的點迄埃,就是很多情況下國內(nèi)社區(qū)能找到的資料已經(jīng)不夠用了,而且有很多優(yōu)質(zhì)資料也是從國外社區(qū)二手兑障、三手翻譯過來的侄非,翻譯質(zhì)量也不能保證。

這就引申出我們進(jìn)階的第一個點流译,開始接受英文資料逞怨。

這里很多同學(xué)說,我的英文能力不行啊福澡,看不懂叠赦。其實我想說,筆者的英語能力也很一般,從去年開始我立了個目標(biāo)除秀,就是帶著劃詞翻譯插件也要開始艱難的看英文文章和資料糯累,遇到不懂的單詞就劃出來看兩眼(沒有刻意去背),第五六次遇見這個單詞的時候册踩,就差不多記得它是什么意思了泳姐。

半年左右的時間下來,(大概保持每周 3 篇以上的閱讀量)能肉眼可見的感覺自己的英語能力在進(jìn)步暂吉,很多時候不用劃詞翻譯插件胖秒,也可以完整的閱讀下來一段文章。

這里是我當(dāng)時閱讀英文優(yōu)質(zhì)文章的一些記錄慕的,

英文技術(shù)文章閱讀

后面英文閱讀慢慢成了一件比較自然的事情阎肝,也就沒有再刻意去記錄,前期可以用這種方式激勵自己肮街。

推薦兩個英文站點吧风题,有很多高質(zhì)量的前端文章。

dev.to
medium

medium 可能需要借助一些科學(xué)工具才能查看嫉父,但是里面的會員付費(fèi)以及作者激勵機(jī)制使得文章非常的優(yōu)質(zhì)俯邓。登錄自己的谷歌賬號即可成為會員,前期可能首頁不會推薦一些前端相關(guān)的文章熔号,你可以自己去搜索關(guān)鍵字如VueReact鸟整、Webpack引镊,任何你興趣的前端技術(shù)棧,不需要過多久你的首頁就會出現(xiàn)前端的推薦內(nèi)容篮条。好好享受這個高質(zhì)量的英文社區(qū)吧弟头。

關(guān)于實踐

社區(qū)有很多大佬實力很強(qiáng),但是對新手寫的代碼嗤之以鼻涉茧,認(rèn)為有 any 的就不叫 TypeScript赴恨、認(rèn)為沒有單元測試就沒資格丟到 Github 上去。這種言論其實也不怪他們伴栓,他們也只是對開源軟件的要求高到偏執(zhí)而已伦连。但是對于新手學(xué)習(xí)來說,這種言論很容易對大家造成打擊钳垮,導(dǎo)致不敢寫 ts惑淳,寫的東西不敢放出來。其實大可不必饺窿,工業(yè)聚 對于這些觀點就發(fā)表了一篇很好的看法歧焦,讓我覺得深受打動,也就是這篇文章開始肚医,我慢慢的把舊項目用 ts 改造起來绢馍,慢慢的進(jìn)步向瓷。

Vue 3.0 公開代碼之后……

總結(jié)

本篇文章是我在這一年多的學(xué)習(xí)經(jīng)歷抽象中總結(jié)出來,還有很多東西我會陸續(xù)加入到這篇文章中去舰涌。

希望作為初中級前端工程師的你猖任,能夠有所收獲。如果能夠幫助到你就是我最大的滿足舵稠。

未完待續(xù)... 持續(xù)更新中超升。

?? 感謝大家

1.如果本文對你有幫助,就點個贊支持下吧哺徊,你的「贊」是我創(chuàng)作的動力室琢。

2.關(guān)注公眾號「前端從進(jìn)階到入院」即可加我好友,我拉你進(jìn)「前端進(jìn)階交流群」落追,大家一起共同交流和進(jìn)步盈滴。

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市轿钠,隨后出現(xiàn)的幾起案子巢钓,更是在濱河造成了極大的恐慌,老刑警劉巖疗垛,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件症汹,死亡現(xiàn)場離奇詭異,居然都是意外死亡贷腕,警方通過查閱死者的電腦和手機(jī)背镇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泽裳,“玉大人瞒斩,你說我怎么就攤上這事′套埽” “怎么了胸囱?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瀑梗。 經(jīng)常有香客問我烹笔,道長,這世上最難降的妖魔是什么抛丽? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任箕宙,我火速辦了婚禮,結(jié)果婚禮上铺纽,老公的妹妹穿的比我還像新娘柬帕。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布陷寝。 她就那樣靜靜地躺著锅很,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凤跑。 梳的紋絲不亂的頭發(fā)上爆安,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機(jī)與錄音仔引,去河邊找鬼扔仓。 笑死,一個胖子當(dāng)著我的面吹牛咖耘,可吹牛的內(nèi)容都是我干的翘簇。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼儿倒,長吁一口氣:“原來是場噩夢啊……” “哼版保!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起夫否,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤彻犁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后凰慈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汞幢,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年微谓,在試婚紗的時候發(fā)現(xiàn)自己被綠了急鳄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡堰酿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出张足,到底是詐尸還是另有隱情触创,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布为牍,位于F島的核電站哼绑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏碉咆。R本人自食惡果不足惜抖韩,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疫铜。 院中可真熱鬧茂浮,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至幌羞,卻和暖如春寸谜,著一層夾襖步出監(jiān)牢的瞬間读规,已是汗流浹背罩旋。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留咪橙,地道東北人聂宾。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓果善,卻偏偏與公主長得像,于是被迫代替她去往敵國和親亏吝。 傳聞我的和親對象是個殘疾皇子岭埠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361