前端技術(shù):React詳解

1.RN簡介

React Native (簡稱RN)是Facebook于2015年4月開源的跨平臺移動應(yīng)用開發(fā)框架,是Facebook早先開源的JS框架 React 在原生移動應(yīng)用平臺的衍生產(chǎn)物,目前支持iOS和安卓兩大平臺。RN使用Javascript語言,類似于HTMLJSX,以及CSS來開發(fā)移動應(yīng)用,因此熟悉Web前端開發(fā)的技術(shù)人員只需很少的學(xué)習(xí)就可以進(jìn)入移動應(yīng)用開發(fā)領(lǐng)域。

React Native 看起來很像 React,只不過其基礎(chǔ)組件是原生組件而非 web 組件。要理解 React Native 應(yīng)用的基本結(jié)構(gòu),首先需要了解一些基本的 React 的概念,比如 JSX語法、組件、state狀態(tài)以及props屬性。

圖解

React Native開發(fā)特點:

  • 一次學(xué)習(xí),隨處編寫:使用React Native可以為iOS和Android操作系統(tǒng)開發(fā)應(yīng)用程序,不同平臺上的代碼根據(jù)平臺會有一些微小的區(qū)別。
  • 混合開發(fā):React Native代碼開發(fā)的模塊與原生代碼開發(fā)的模塊可以雙向通信、無縫銜接;
  • 高效的移動應(yīng)用開發(fā):

(1)獨特的UI實現(xiàn)框架
(2)組件化開發(fā)
(3)跨平臺移植代碼迅速
(4)自動匹配不同屏幕大小的手機(jī)

  • 高效的移動應(yīng)用開發(fā)調(diào)試
  • 高效的應(yīng)用熱更新
  • 有效降低移動應(yīng)用安裝包體積
  • 學(xué)習(xí)門檻低、開發(fā)難度低

使用React Native開發(fā)的代價
為了得到React Native開發(fā)的優(yōu)點,使用React Native開發(fā)的APP也需要付出一定的代價。

  • (1)內(nèi)存消耗大
    使用React Native開發(fā)的程序運(yùn)行所需的內(nèi)存比原生代碼開發(fā)的程序略多。
  • (2)運(yùn)行速度
    使用React Native開發(fā)的代碼運(yùn)行速度比原生代碼略慢。

React 與 React Native 除了在編碼表現(xiàn)層都使用 JSX 語法外,在 React 與 React Native 的底層都有 Virtual DOM 與 DOM 之間的映射與轉(zhuǎn)換,以實現(xiàn)了頁面組件高效更新的前端表現(xiàn)。


image.png

現(xiàn)在最新版本是0.59React Native中文網(wǎng)

React NativeReact的關(guān)系及特點:React是基礎(chǔ)框架,是一套基礎(chǔ)設(shè)計實現(xiàn)理念,開發(fā)者不能直接使用它來開發(fā)移動應(yīng)用或網(wǎng)頁。在React之上發(fā)展出了React.js框架用來開發(fā)網(wǎng)頁,發(fā)展出來React Native用來開發(fā)移動應(yīng)用。底層原理是相同的,都是使用js實現(xiàn)虛擬dom樹來驅(qū)動頁面的渲染,react是驅(qū)動HTML dom的渲染,react native是驅(qū)動原生組件的渲染。

React.js:目的 是為了使前端的V層更具組件化,能更好的復(fù)用,它能夠使用簡單的html標(biāo)簽創(chuàng)建更多的自定義組件標(biāo)簽,內(nèi)部綁定事件,同時可以讓你從操作dom中解脫出來,只需要操作數(shù)據(jù)就會改變相應(yīng)的dom。

二者都是基于組件(component)開發(fā),然后組件和組件之間通過props傳遞方法,每個組件都有一個狀態(tài)(state),當(dāng)某個方法改變了這個狀態(tài)值時,整個組件就會重繪,從而達(dá)到刷新。另外,說到重繪就要提到虛擬dom了,就是用js模擬dom結(jié)構(gòu),等整個組件的dom更新完畢,它會有一個diff的過程,對比出哪些組件發(fā)生了變化,然后才渲染到頁面,簡單來說只更新了相比之前改變了的部分,而不是全部刷新,所以效率很高。

虛擬DOM(Virtual DOM)的機(jī)制:在瀏覽器端用Javascript實現(xiàn)了一套DOM API。基于React進(jìn)行開發(fā)時所有的DOM構(gòu)造都是通過虛擬DOM進(jìn)行,每當(dāng)數(shù)據(jù)變化時,React都會重新構(gòu)建整個DOM樹,然后React將當(dāng)前整個DOM樹和上一次的DOM樹進(jìn)行對比,得到DOM結(jié)構(gòu)的區(qū)別,然后僅僅將需要變化的部分進(jìn)行實際的瀏覽器DOM更新。而且React能夠批處理虛擬DOM的刷新,在一個事件循環(huán)(Event Loop)內(nèi)的兩次數(shù)據(jù)變化會被合并。


2.React詳解

生態(tài)介紹

Vue生態(tài):Vue + Vue-Router + Vuex + Axios + Babel + Webpack
React生態(tài):React + React-Router + Redux + Axios + Babel + Webpack


2.1.React 簡介

React

React 是一個聲明式,高效且靈活的用于構(gòu)建用戶界面的 JavaScript 庫。使用 React 可以將一些簡短、獨立的代碼片段組合成復(fù)雜的 UI 界面,這些代碼片段被稱作“組件”。

React特點

  • 1.聲明式設(shè)計 ?React采用聲明范式,可以輕松描述應(yīng)用。
  • 2.高效 ?React通過對DOM的模擬,最大限度地減少與DOM的交互。
  • 3.靈活 ?React可以與已知的庫或框架很好地配合。
  • 4.JSX ? JSXJavaScript 語法的擴(kuò)展。React 開發(fā)不一定使用 JSX ,但我們建議使用它。
  • 5.組件 ? 通過 React 構(gòu)建組件,使得代碼更加容易得到復(fù)用,能夠很好的應(yīng)用在大項目的開發(fā)中。
  • 6.單向響應(yīng)的數(shù)據(jù)流 ? React 實現(xiàn)了單向響應(yīng)的數(shù)據(jù)流,從而減少了重復(fù)代碼,這也是它為什么比傳統(tǒng)數(shù)據(jù)綁定更簡單。

2.2 React使用

1.React 環(huán)境配置安裝
  • 使用 React CDN 庫
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生產(chǎn)環(huán)境中不建議使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<!-- 官方提供的CDN-->
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 生產(chǎn)環(huán)境中不建議使用 -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  • 通過 npm 使用 React
  • 使用 create-react-app 快速構(gòu)建 React 開發(fā)環(huán)境

2.3React render 渲染

屏幕輸出:Hello, React

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 使用cdn 上的React CDN庫-->
    <!-- react.min.js - React 的核心庫 -->
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <!-- react-dom.min.js - 提供與 DOM 相關(guān)的功能 -->
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <!-- babel.min.js - Babel 可以將 ES6 代碼轉(zhuǎn)為 ES5 代碼 -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>

<div id="root"></div>

<!-- React render 渲染-->
<script type="text/babel">
    ReactDOM.render(<h1>Hello, React </h1>,
    document.getElementById('root')
    );

</script>
</body>
</html>

3.React JSX

React 使用 JSX 來替代常規(guī)的 JavaScript。

1.React JSX簡介

JSX:JavaScript XML,一種類似于XML的JS擴(kuò)展語法。也可以理解成:符合 XML 規(guī)范的 JS 語法。

JSX語法的本質(zhì):以 React.createElement 的形式來實現(xiàn)的,并沒有直接把 用戶寫的 HTML代碼,渲染到頁面上。使用babel轉(zhuǎn)換工具將 JSX語法 轉(zhuǎn)換為 JS語法。

我們不需要一定使用 JSX,但它有以下優(yōu)點:

  • JSX 執(zhí)行更快,因為它在編譯為 JavaScript 代碼后進(jìn)行了優(yōu)化。
  • 它是類型安全的,在編譯過程中就能發(fā)現(xiàn)錯誤。
  • 使用 JSX 編寫模板更加簡單快速。
const element = <h1>Hello, world!</h1>;

這種看起來可能有些奇怪的標(biāo)簽語法既不是字符串也不是 HTML。
它被稱為 JSX, 一種 JavaScript 的語法擴(kuò)展。 我們推薦在 React 中使用 JSX 來描述用戶界面。
JSX 是在 JavaScript 內(nèi)部實現(xiàn)的。

2.JSX的基本語法

(1)在 JSX內(nèi)部 寫 JS代碼:如果要在 JSX 語法內(nèi)部,書寫 JS 代碼,那么,所有的JS代碼必須寫到 {} 的內(nèi)部。在{}內(nèi)部,可以寫任何符合JS規(guī)范的代碼。

例如:

    var myTitle = '這是使用變量定義的 tilte 值'

    // 使用JSX語法 創(chuàng)建虛擬DOM對象
    var vDom = (
    <div>
      Hello, React!
      <h2 title={myTitle + 'vae'}>這是標(biāo)題</h2>
    </div>
    );

(2)當(dāng)編譯引擎在編譯JSX代碼的時候,如果遇到了<,會把它當(dāng)作 HTML代碼 去編譯;如果遇到了 {}, 會把方括號里面的代碼當(dāng)作 普通JS代碼 去編譯。

(3)在JSX中,如果要為元素添加class屬性,則必須寫成className,因為 class在ES6中是一個關(guān)鍵字;和class類似,label標(biāo)簽的 for 屬性需要替換為 htmlFor。

代碼舉例:

  // 使用JSX語法 創(chuàng)建虛擬DOM對象
  var vDom = (
    <div>
      Hello, React!
      <p className="qianguyihao">千古壹號</p>
      <label htmlFor="" />
    </div>
  );

(4)在JSX創(chuàng)建DOM的時候,所有的節(jié)點,必須有唯一的根元素進(jìn)行包裹。

(5)如果要寫注釋,注釋必須放到 {} 內(nèi)部。例如:

    // 使用JSX語法 創(chuàng)建虛擬DOM對象
    var vDom = (
    // 這一行是注釋
    <div>
      Hello, React!
      <p className="qianguyihao">千古壹號</p>
      {/*這一行也是注釋 */}
    </div>
    );

最后,再舉個例子:

<!DOCTYPE html>
<html lang="">
  <head>
    <meta />
    <meta />
    <meta />
    <title>Document</title>
  </head>
  <body>
    <!-- 引入React相關(guān)的js庫 -->
    <script type="text/javascript" src="./libs/react.js"></script>
    <script type="text/javascript" src="./libs/react-dom.js"></script>
    <script type="text/javascript" src="./libs/babel.min.js"></script>

    <div id="app"></div>

    <!-- 注意,這一行的 type 是寫 "text/babel",而不是 "text/javascript" -->
    <script type="text/babel">
      //頁面中的真實容器元素
      var containDiv = document.getElementById("app");

      var arr = []
      for (var i = 0; i < 6; i++) {
        var p = <p className="myp" key={i}>這個是p標(biāo)簽</p>  // 注意這個地方的寫法: key = {i}
        arr.push(p)
      }

      //1、使用JSX語法 創(chuàng)建虛擬DOM對象
      var vDom = (
        <div>
          Hello, React!
            {arr}
        </div>
      );

      //2、渲染虛擬DOM對象
      ReactDOM.render(vDom, containDiv); // 參數(shù)1:虛擬DOM對象;參數(shù)2:頁面中的容器
    </script>
  </body>
</html>

4.React 組件 狀態(tài)(State&props) 生命周期詳解

React 把組件看成是一個狀態(tài)機(jī)(State Machines)。通過與用戶的交互,實現(xiàn)不同狀態(tài),然后渲染 UI,讓用戶界面和數(shù)據(jù)保持一致。

React 里,只需更新組件的 state,然后根據(jù)新的 state 重新渲染用戶界面(不要操作 DOM)。

  • 創(chuàng)建組件的第一種方式:在React中,構(gòu)造函數(shù)就是一個最基本的組件。如果想要把組件放到頁面中,可以把構(gòu)造函數(shù)的名稱當(dāng)作組件的名稱,以 HTML標(biāo)簽形式引入頁面中即可。
  • 創(chuàng)建組件的第二種方式:使用 class 關(guān)鍵字
    使用 function 創(chuàng)建的組件,叫做【無狀態(tài)組件】;使用 class 創(chuàng)建的組件,叫做【有狀態(tài)組件】。
    本質(zhì)區(qū)別:

有狀態(tài)組件和無狀態(tài)組件,最本質(zhì)的區(qū)別,就是有無 state 屬性。同時, class 創(chuàng)建的組件,有自己的生命周期函數(shù),但是,function 創(chuàng)建的 組件,沒有自己的生命周期函數(shù)。

state 和 props 主要的區(qū)別在于 props 是不可變的,而 state 可以根據(jù)與用戶交互來改變。這就是為什么有些容器組件需要定義 state 來更新和修改數(shù)據(jù)。 而子組件只能通過 props 來傳遞數(shù)據(jù)。

組件API

設(shè)置狀態(tài):setState
替換狀態(tài):replaceState
設(shè)置屬性:setProps
替換屬性:replaceProps
強(qiáng)制更新:forceUpdate
獲取DOM節(jié)點:findDOMNode
判斷組件掛載狀態(tài):isMounted
組件的生命周期可分成三個狀態(tài)

在組件創(chuàng)建、到加載到頁面上運(yùn)行、以及組件被銷毀的過程中,總是伴隨著各種各樣的事件,這些在組件特定時期,觸發(fā)的事件統(tǒng)稱為組件的生命周期。

  • Mounting:已插入真實 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真實 DOM

生命周期的方法有:

  • componentWillMount 在渲染前調(diào)用,在客戶端也在服務(wù)端。
  • componentDidMount : 在第一次渲染后調(diào)用,只在客戶端。之后組件已經(jīng)生成了對應(yīng)的DOM結(jié)構(gòu),可以通過this.getDOMNode()來進(jìn)行訪問。 如果你想和其他JavaScript框架一起使用,可以在這個方法中調(diào)用setTimeout, setInterval或者發(fā)送AJAX請求等操作(防止異步操作阻塞UI)。
  • componentWillReceiveProps 在組件接收到一個新的 prop (更新后)時被調(diào)用。這個方法在初始化render時不會被調(diào)用。
  • shouldComponentUpdate 返回一個布爾值。在組件接收到新的props或者state時被調(diào)用。在初始化時或者使用forceUpdate時不被調(diào)用。
    可以在你確認(rèn)不需要更新組件時使用。
  • componentWillUpdate在組件接收到新的props或者state但還沒有render時被調(diào)用。在初始化時不會被調(diào)用。
  • componentDidUpdate 在組件完成更新后立即調(diào)用。在初始化時不會被調(diào)用。
  • componentWillUnmount在組件從 DOM 中移除之前立刻被調(diào)用。

1.組件創(chuàng)建階段

組件創(chuàng)建階段的生命周期函數(shù),有一個顯著的特點:創(chuàng)建階段的生命周期函數(shù),在組件的一輩子中,只執(zhí)行一次。

  • getDefaultProps

初始化 props 屬性默認(rèn)值。

  • getInitialState

初始化組件的私有數(shù)據(jù)。因為 state 是定義在組件的 constructor 構(gòu)造器當(dāng)中的,只要new 了 class類,必然會調(diào)用 constructor構(gòu)造器。

  • componentWillMount()

組件將要被掛載。此時還沒有開始渲染虛擬DOM。

在這個階段,不能去操作DOM元素,但可以操作屬性、狀態(tài)、function。相當(dāng)于 Vue 中的Create()函數(shù)。

  • render()

第一次開始渲染真正的虛擬DOM。當(dāng)render執(zhí)行完,內(nèi)存中就有了完整的虛擬DOM了。

意思是,此時,虛擬DOM在內(nèi)存中創(chuàng)建好了,但是還沒有掛在到頁面上。

在這個函數(shù)內(nèi)部,不能去操作DOM元素,因為還沒return之前,虛擬DOM還沒有創(chuàng)建;當(dāng)return執(zhí)行完畢后,虛擬DOM就創(chuàng)建好了,但是還沒有掛在到頁面上。

  • componentDidMount()

當(dāng)組件(虛擬DOM)掛載到頁面之后,會進(jìn)入這個生命周期函數(shù)

只要進(jìn)入到這個生命周期函數(shù),則必然說明,頁面上已經(jīng)有可見的DOM元素了。此時,組件已經(jīng)顯示到了頁面上,state上的數(shù)據(jù)、內(nèi)存中的虛擬DOM、以及瀏覽器中的頁面,已經(jīng)完全保持一致了。

當(dāng)這個方法執(zhí)行完,組件就進(jìn)入都了 運(yùn)行中 的狀態(tài)。所以說,componentDidMount 是創(chuàng)建階段的最后一個函數(shù)。

在這個函數(shù)中,我們可以放心的去 操作 頁面上你需要使用的 DOM 元素了。如果我們想操作DOM元素,最早只能在 componentDidMount 中進(jìn)行。相當(dāng)于 Vue 中的 mounted() 函數(shù)

2、組件運(yùn)行階段

有一個顯著的特點,根據(jù)組件的state和props的改變,有選擇性的觸發(fā)0次或多次。

  • componentWillReceiveProps()

組件將要接收新屬性。只有當(dāng)父組件中,通過某些事件,重新修改了 傳遞給 子組件的 props 數(shù)據(jù)之后,才會觸發(fā)這個鉤子函數(shù)。

  • shouldComponentUpdate()

判斷組件是否需要被更新。此時,組件尚未被更新,但是,state 和 props 肯定是最新的。

  • componentWillUpdate()

組件將要被更新。此時,組件還沒有被更新,在進(jìn)入到這個生命周期函數(shù)的時候,內(nèi)存中的虛擬DOM還是舊的,頁面上的 DOM 元素也是舊的。(也就是說,此時操作的是舊的 DOM元素)

  • render

此時,又要根據(jù)最新的 state 和 props,重新渲染一棵內(nèi)存中的 虛擬DOM樹。當(dāng) render 調(diào)用完畢,內(nèi)存中的舊DOM樹,已經(jīng)被新DOM樹替換了!此時,虛擬DOM樹已經(jīng)和組件的 state 保持一致了,都是最新的;但是頁面還是舊的。

  • componentDidUpdate

此時,組件完成更新,頁面被重新渲染。此時,state、虛擬DOM 和 頁面已經(jīng)完全保持同步。

3、組件銷毀階段

一輩子只執(zhí)行一次。

  • componentWillUnmount: 組件將要被卸載。此時組件還可以正常使用。

生命周期對比:

vue生命周期

React-Native生命周期
組件生命周期的執(zhí)行順序總結(jié)

1、Mounting

  • constructor()

  • componentWillMount()

  • render()

  • componentDidMount()

2、Updating

  • componentWillReceiveProps(nextProps):接收父組件傳遞過來的屬性

  • shouldComponentUpdate(nextProps, nextState):一旦調(diào)用 setState,就會觸發(fā)這個方法。方法默認(rèn) return true;如果 return false,后續(xù)的方法就不會走了。

  • componentWillUpdate(nextProps, nextState)

  • render()

  • componentDidUpdate(prevProps, prevState)

3、Unmounting

  • componentWillUnmount()

5.React 事件處理

React 元素的事件處理和 DOM 元素類似。但是有一點語法上的不同:

React 事件綁定屬性的命名采用駝峰式寫法,而不是小寫。
如果采用 JSX 的語法你需要傳入一個函數(shù)作為事件處理函數(shù),而不是一個字符串(DOM 元素的寫法)

//HTML 通常寫法是:
<button onclick="activateLasers()">
  激活按鈕
</button>

//React 中寫法為:
<button onClick={activateLasers}>
  激活按鈕
</button>

參考文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,016評論 2 375

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