深入學(xué)習(xí)Vue SSR服務(wù)端渲染 用Nuxt.js打造CNode社區(qū)

“學(xué)而不思則惘,思而不學(xué)則殆”

# 服務(wù)端渲染(SSR)

> SSR意為 server-side rendering(服務(wù)端渲染),目的是為了解決單頁面應(yīng)用的SEO的問題劲阎。

## 服務(wù)器端渲染(SSR)和客戶端渲染(CSR)

![ssr_csr](https://user-gold-cdn.xitu.io/2019/1/22/1687452f5f28db2e?w=1498&h=820&f=jpeg&s=155084)

### 服務(wù)器端渲染(SSR)

瀏覽器先請求HTML文檔崭放,服務(wù)器端先將html頁面(或頁面組件)熟尉,生成為html字符串汰寓,再返回給瀏覽器菊碟,最后直接渲染到頁面上裕照。

### 客戶端渲染(CSR)

? 瀏覽器先請求HTML文檔攒发,在瀏覽器端加載html頁面中的JS腳本。通過JS(vue/react)的能力晋南,將虛擬DOM最終渲染填充到頁面中惠猿。

### 兩者本質(zhì)的區(qū)別是什么?

#### SSR

服務(wù)端生成好的html頁面內(nèi)容负间,直接返回給瀏覽器渲染偶妖。

server

```

const express = require('express')

const app = express()

app.get('/ssr', (req, res) => {

? res.send(`

? ? <html>

? ? ? <head>

? ? ? ? <meta charset='utf-8'>

? ? ? ? <title>SSR 服務(wù)端渲染</title>

? ? ? </head>

? ? ? <body>

? ? ? ? <h3>SSR 服務(wù)端渲染</h3>

? ? ? ? <p>SSR意為 Server Side Rendering(服務(wù)端渲染),目的是為了解決單頁面應(yīng)用的SEO的問題。</p>

? ? ? </body>

? ? </html>

? `)

})

app.listen(7200)

```

客戶端訪問頁面localhost:7200/ssr

```

? <html>

? ? ? <head>

? ? ? ? <meta charset='utf-8'>

? ? ? ? <title>SSR 服務(wù)端渲染</title>

? ? ? </head>

? ? ? <body>

? ? ? ? <h3>SSR 服務(wù)端渲染</h3>

? ? ? ? <p>SSR意為 Server Side Rendering(服務(wù)端渲染),目的是為了解決單頁面應(yīng)用的SEO的問題政溃。</p>

? ? ? </body>

? ? </html>

```

#### CSR

頁面首先直接輸出一個空的div#root趾访,再由客戶端加載編譯打包好的react代碼(bundle.js chunk.js等js腳本),最終將頁面組件渲染到頁面中玩祟。

```

npx create-react-app my-app

cd my-app

yarn start

```

瀏覽器訪問http://localhost:3000/

```

? <body>

? ? <noscript>You need to enable JavaScript to run this app.</noscript>

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

? <script src="/static/js/bundle.js"></script><script src="/static/js/0.chunk.js"></script><script src="/static/js/main.chunk.js"></script></body>

```

客戶端渲染和服務(wù)器端渲染的最重要的區(qū)別就是究竟是誰來完成html文件的完整拼接腹缩,如果是在服務(wù)器端完成的,然后返回給客戶端空扎,就是服務(wù)器端渲染藏鹊,而如果是前端做了更多的工作完成了html的拼接,則就是客戶端渲染转锈。

#### 前后端拆分核心理念

前后端拆分盘寡,后端專注于數(shù)據(jù)接口服務(wù),前端專注接口調(diào)用撮慨,頁面渲染竿痰,雙劍合璧脆粥,相得益彰。

#### 服務(wù)器端渲染的優(yōu)缺點是怎樣的影涉?

優(yōu)點:


? - **更好的SEO 首屏加載快**

? 由于搜索引擎爬蟲抓取工具可以直接查看完全渲染的頁面变隔。

? - **首屏加載快**

? ? 快速地看到完整渲染的頁面,從而提高用戶體驗蟹倾。

? - **后端生成靜態(tài)化文件**

? ? 即解析模板的工作完全交由后端來做匣缘,客戶端只要解析標(biāo)準(zhǔn)的html頁面即可。

缺點:

? - **開發(fā)條件受限**

? 在服務(wù)端渲染中鲜棠,created和beforeCreate之外的生命周期鉤子不可用

? - **占用服務(wù)端資源**

? - **學(xué)習(xí)成本相對較高**

? 除了對webpack肌厨、Vue要熟悉,還需要掌握node豁陆、Express相關(guān)技術(shù)柑爸。相對于客戶端渲染,項目構(gòu)建盒音、部署過程更加復(fù)雜表鳍。

#### 客戶端渲染的優(yōu)缺點是怎樣的?

優(yōu)點:

? - **前后端分離**

? 前端專注于前端UI里逆,后端專注于api開發(fā)进胯,且前端有更多的選擇性,而不需要遵循后端特定的模板原押。

? - **體驗更好**

缺點:

? - **首屏加載緩慢**

? - **不利于SEO**

? 除了 Google 和 Bing 比較完美地實現(xiàn)了對于 SPA(Single-Page Application)的爬蟲渲染及內(nèi)容抓取,大多數(shù)搜索引擎包括百度都沒有支持偎血。因而诸衔,包含豐富內(nèi)容的產(chǎn)品并需要 SEO 流量的產(chǎn)品也就自然需要 SSR 實現(xiàn)。

### 是否應(yīng)該使用服務(wù)端渲染

- **首屏加載慢**

針對于首屏加載颇玷,可以做服務(wù)端渲染笨农。但要有覺悟,一旦這樣做帖渠,后期維護(hù)是個很痛苦的事情谒亦。相比于做服務(wù)端渲染,更推薦通過應(yīng)用拆分空郊、code spliting 來完成優(yōu)化首屏加載的過程(先前做過一次首屏優(yōu)化份招,優(yōu)化前首屏加載每次都在 5s+,code spliting 之后直接變成 2s+狞甚,性價比高)锁摔。

- **SEO優(yōu)化**

如果是為了主頁網(wǎng)站被搜索引擎收錄,可以使用服務(wù)端渲染哼审。但更好的建議新開引導(dǎo)項目谐腰,在該項目上靜態(tài)資源或服務(wù)端渲染顯示頁面孕豹,作為主要網(wǎng)站的搜索引擎引流作用。

## Vue服務(wù)端渲染

這里我們先從Vue的vue-server-renderer來聊聊服務(wù)端渲染十气,暫先不說那些ssr框架(Nuxt.js Next.js)

vue-server-renderer 是官方提供給我們用來實現(xiàn)服務(wù)端渲染的npm包

### 基本用法

安裝

```

npm install vue vue-server-renderer --save

```

### 渲染一個Vue實例

1.創(chuàng)建一個 Vue 實例

```

const Vue = require('vue')

const app = new Vue({

? template: `<div>hello zhufeng</div>`

})

```

2.創(chuàng)建一個 renderer對象

```

const renderer = require('vue-server-renderer').createRenderer()

```

3.將 Vue 實例渲染為 HTML

```

renderer.renderToString(app, (err, html) => {

? if (err) throw err

? console.log(html)

? // <div data-server-rendered="true">hello zhufeng</div>

})

// 在 2.5.0+励背,如果沒有傳入回調(diào)函數(shù),則會返回 Promise:

renderer.renderToString(app).then(html => {

? console.log(html)

}).catch(err => {

? console.error(err)

})

```

#### Vue實例渲染 完整示例代碼

Node.js 服務(wù)器作為中間層

```

npm i express --save

```

```

const Vue = require('vue')

const server = require('express')()

// 創(chuàng)建一個 renderer對象

const renderer = require('vue-server-renderer').createRenderer()

// 創(chuàng)建一個后端路由

server.get('/', (req, res) => {

? // 創(chuàng)建一個 Vue 實例

? const app = new Vue({

? ? data: {

? ? ? title: 'hello zhufeng'

? ? },

? ? template: `<h3>{{ title }}</h3>`

? })

? // 通過renderToString方法 將Vue實例轉(zhuǎn)換成HTML

? renderer

? ? .renderToString(app)

? ? .then(html => {

? ? ? console.log(html)

? ? ? // '<h3 data-server-rendered="true">hello zhufeng</h3>'

? ? ? // 最終將拼接好的html頁面內(nèi)容 返回給瀏覽器

? ? ? res.send(`

? ? ? ? <!DOCTYPE html>

? ? ? ? <html lang="en">

? ? ? ? ? <head><title>Hello</title></head>

? ? ? ? ? <body>${html}</body>

? ? ? ? </html>

? ? ? `)

? ? })

? ? .catch(err => {

? ? ? res.status(500).end('Internal Server Error')

? ? })

})

server.listen(7300)

```

#### 使用html頁面模板

創(chuàng)建一個html模板頁面砸西,用一個額外的HTML頁面包裹容器叶眉,來包裹生成的HTML標(biāo)記(markup)。

html模板

```

<!DOCTYPE html>

<html lang="en">

<head>

? <meta charset="UTF-8">

? <meta name="viewport" content="width=device-width, initial-scale=1.0">

? <meta http-equiv="X-UA-Compatible" content="ie=edge">

? <title>服務(wù)端渲染SSR</title>

</head>

<body>

? <!--vue-ssr-outlet-->

</body>

</html>

```

> 注意 \<!--vue-ssr-outlet--> 注釋 -- 這里將是應(yīng)用程序 HTML 標(biāo)記注入的地方籍胯。

server端

```

const Vue = require('vue')

const fs = require('fs')

const server = require('express')()

const { createRenderer } = require('vue-server-renderer')

// 創(chuàng)建一個 renderer對象 并指定渲染模板

const renderer = createRenderer({

? template: fs.readFileSync('./template/index1.html', 'utf-8')

})

// 創(chuàng)建一個后端路由

server.get('/', (req, res) => {

? // 創(chuàng)建一個 Vue 實例

? const app = new Vue({

? ? data: {

? ? ? title: 'hello zhufeng'

? ? },

? ? template: `<h3>{{ title }}</h3>`

? })

? // 通過renderToString方法 將Vue實例轉(zhuǎn)換成HTML

? renderer

? ? .renderToString(app)

? ? .then(html => {

? ? ? // 最終將拼接好的html頁面內(nèi)容 返回給瀏覽器

? ? ? res.send(html)

? ? })

? ? .catch(err => {

? ? ? res.status(500).end('Internal Server Error')

? ? })

})

server.listen(7300)

```

#### 動態(tài)注入title 和 meta標(biāo)簽

html模板設(shè)置插值變量

```

<!DOCTYPE html>

<html lang="en">

<head>

? {{{meta}}}

? <title>{{title}}</title>

</head>

<body>

? <!--vue-ssr-outlet-->

</body>

</html>

```

我們可以通過傳入一個"渲染上下文對象"竟闪,作為 renderToString 函數(shù)的第二個參數(shù),來提供插值數(shù)據(jù):

```

? // 動態(tài)注入title 和 meta標(biāo)簽

? const context = {

? ? title: '珠峰前端培訓(xùn)',

? ? meta: `

? ? <meta charset="UTF-8">

? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">

? ? <meta http-equiv="X-UA-Compatible" content="ie=edge">

? ? <meta name="keywords" content="HTML, CSS, Vue, React, Node, JavaScript" />

? ? `

? }

? // 通過renderToString方法 將Vue實例轉(zhuǎn)換成HTML

? renderer

? ? .renderToString(app, context)

? ? .then(html => {

? ? ? // 最終將拼接好的html頁面內(nèi)容 返回給瀏覽器

? ? ? res.send(html)

? ? })

? ? .catch(err => {

? ? ? res.status(500).end('Internal Server Error')

? ? })

```

### 參考源碼

https://github.com/Lwenli1224/ssr_csr

## 編寫通用代碼

> "通用"代碼 - 即運行在服務(wù)器和客戶端的代碼杖狼。由于用例和平臺 API 的差異炼蛤,當(dāng)運行在不同環(huán)境中時,我們的代碼將不會完全相同蝶涩。所以這里我們將會闡述你需要理解的關(guān)鍵事項理朋。

### SSR開發(fā)需要注意的問題

- 服務(wù)端渲染只會執(zhí)行 vue 的兩個鉤子函數(shù) beforeCreate 和 created

- 服務(wù)端渲染無法訪問 window 和 document等只有瀏覽器才有的全局對象。

通用API

例如绿聘,axios 是一個 HTTP 客戶端嗽上,可以向服務(wù)器和客戶端都暴露相同的 API。

## webpack工程構(gòu)建

![webpack](https://user-gold-cdn.xitu.io/2019/1/22/168713bb0c0b3934?w=1946&h=892&f=png&s=125906)

服務(wù)端和客戶端各自都需要提供Vue應(yīng)用程序熄攘。為了做到這一點兽愤,我們需要使用 webpack 來打包我們的 Vue 應(yīng)用程序。事實上挪圾,我們可能需要在服務(wù)器上使用 webpack 打包 Vue 應(yīng)用程序浅萧,因為:

- 通常 Vue 應(yīng)用程序是由 webpack 和 vue-loader 構(gòu)建,并且許多 webpack 特定功能不能直接在 Node.js 中運行(例如通過 file-loader 導(dǎo)入文件哲思,通過 css-loader 導(dǎo)入 CSS)洼畅。

- 盡管 Node.js 最新版本能夠完全支持 ES2015 特性,我們還是需要轉(zhuǎn)譯客戶端代碼以適應(yīng)老版瀏覽器棚赔。這也會涉及到構(gòu)建步驟

然后我們的服務(wù)端代碼和客戶端代碼通過webpack分別打包帝簇,生成Server Bundle和Client Bundle

? - 服務(wù)器需要「服務(wù)器 bundle」然后用于服務(wù)器端渲染(SSR)

? - 客戶端 bundle」會發(fā)送給瀏覽器,用于混合靜態(tài)標(biāo)記靠益。

## 從零搭建Vue開發(fā)環(huán)境(SSR)

利用vue-server-renderer 搭建Vue SSR開發(fā)環(huán)境

#### Git倉庫源碼

從零大家vue ssr環(huán)境比較費勁

https://github.com/Lwenli1224/webpack4-vue-loader/tree/vue-ssr1.0

從零搭建vue環(huán)境 可以參考我這篇文章(從零搭建Vue開發(fā)環(huán)境:webpack4 + vue-loader + babel-loader v8 + Babel v7 + eslint + git hooks + editorconfig)

https://juejin.im/post/5c48981ee51d4567680e44a9

## 服務(wù)端渲染應(yīng)用框架-Nuxt.js

> Nuxt.js 是一個基于 Vue.js 的服務(wù)端渲染應(yīng)用框架丧肴。

你可以基于它初始化新項目的基礎(chǔ)結(jié)構(gòu)代碼,或者在已有 Node.js 項目中使用 Nuxt.js捆毫。

Nuxt.js 預(yù)設(shè)了利用Vue.js開發(fā)服務(wù)端渲染的應(yīng)用所需要的各種配置闪湾。

#### create-nuxt-app

Nuxt.js團(tuán)隊創(chuàng)建的腳手架工具

創(chuàng)建一個nuxt工程

```

npx create-nuxt-app nuxt-app

```

它會讓你進(jìn)行一些集成選擇, 如服務(wù)器端框架(express koa)和 UI框架绩卤。

啟動項目

```

npm run dev

```

現(xiàn)在我們的應(yīng)用運行在 http://localhost:3000 上運行途样。

> 注意:Nuxt.js 會監(jiān)聽 pages 目錄中的文件更改江醇,因此在添加新頁面時無需重新啟動應(yīng)用程序。

目錄結(jié)構(gòu)

```

├── README.md? ? ? ? # 說明文檔

├── assets? ? ? ? ? ? # 資源目錄 用于組織未編譯的靜態(tài)資源如 LESS何暇、SASS 或 JavaScript

├── components? ? ? ? # 組件目錄 用于組織應(yīng)用的 Vue.js 組件

├── layouts? ? ? ? ? # 布局目錄 用于組織應(yīng)用的布局組件

├── middleware? ? ? ? # 中間件目錄 用于存放應(yīng)用的中間件陶夜。

├── nuxt.config.js? ? # nuxt配置文件 用于組織Nuxt.js 應(yīng)用的個性化配置,以便覆蓋默認(rèn)配置裆站。

├── pages? ? ? ? ? ? # 頁面目錄 用于組織應(yīng)用的路由及視圖

├── plugins? ? ? ? ? # 插件目錄 用于組織那些需要 在根vue.js應(yīng)用實例化之前需要運行的Javascript插件

├── server? ? ? ? ? ? # 服務(wù)端 用于組織node中間層服務(wù)代碼

├── static? ? ? ? ? ? # 靜態(tài)文件目錄 用于存放應(yīng)用的靜態(tài)文件

├── store? ? ? ? ? ? # store目錄 用于組織應(yīng)用的 Vuex 狀態(tài)樹 文件条辟。

```

目錄結(jié)構(gòu)詳情說明

https://zh.nuxtjs.org/guide/directory-structure

### 異步數(shù)據(jù)

#### asyncData

asyncData方法會在組件(限于頁面組件)每次加載之前被調(diào)用。它可以在服務(wù)端或路由更新之前被調(diào)用宏胯。你可以利用 asyncData方法來獲取數(shù)據(jù)羽嫡,Nuxt.js 會將 asyncData 返回的數(shù)據(jù)融合組件 data 方法返回的數(shù)據(jù)一并返回給當(dāng)前組件。

#### fetch

fetch 方法用于在渲染頁面前填充應(yīng)用的狀態(tài)樹(store)數(shù)據(jù)肩袍, 與 asyncData 方法類似杭棵,不同的是它不會設(shè)置組件的數(shù)據(jù)。

### Nuxt.js開發(fā)實戰(zhàn)(打造CNode社區(qū))

![CNode](https://user-gold-cdn.xitu.io/2019/1/22/168713ceef76efd8?w=750&h=1334&f=png&s=244880)

#### 路由創(chuàng)建

> Nuxt.js 依據(jù) pages 目錄結(jié)構(gòu)自動生成 vue-router 模塊的路由配置氛赐。

![router](https://user-gold-cdn.xitu.io/2019/1/22/168713d3bcd12295?w=298&h=264&f=png&s=21255)

#### Vuex配置

> Nuxt.js 會嘗試找到應(yīng)用根目錄下的 store 目錄魂爪,如果該目錄存在,它將做以下的事情:

> - 引用vuex模塊

> - 將vuex模塊加到vendors構(gòu)建配置中去

> - 設(shè)置Vue根實例的store配置項

![Vuex](https://user-gold-cdn.xitu.io/2019/1/22/168713da1f446570?w=294&h=226&f=png&s=17939)

#### middleware中間件配置

> 每一個中間件應(yīng)放置在 middleware/ 目錄艰管。文件名的名稱將成為中間件名稱(middleware/auth.js將成為 auth 中間件)滓侍。

![middleware](https://user-gold-cdn.xitu.io/2019/1/22/168713dda5651867?w=300&h=174&f=png&s=14722)

#### node服務(wù)配置

![server](https://user-gold-cdn.xitu.io/2019/1/22/168713e11c95a436?w=272&h=214&f=png&s=15581)

#### nuxt.config.js

> Nuxt.js 默認(rèn)的配置涵蓋了大部分使用情形,可通過 nuxt.config.js 來覆蓋默認(rèn)的配置牲芋。

https://zh.nuxtjs.org/api/configuration-build

https://github.com/Lwenli1224/Nuxt.js-CNode/blob/master/nuxt.config.js

### Nuxt.js CNode社區(qū)項目源碼

更多詳情請看我倉庫源碼

https://github.com/Lwenli1224/Nuxt.js-CNode

未完待續(xù) 持續(xù)更新撩笆。。缸浦。

## 論文檔資料的重要性

越來越覺得平時學(xué)習(xí)工作 看文檔很重要浇衬,特別是官方文檔 一手的資料,英語好的話最好是看英文文檔一手資料比較多餐济。

- 看官方文檔 如:


? Nuxt.js https://zh.nuxtjs.org/?

? webpack https://webpack.js.org/?

? babel https://babeljs.io/

- 通過npm搜包了解

? https://www.npmjs.com/


- 去github看源碼?

? https://github.com/

- 查問題去stackoverflow (科學(xué)上網(wǎng))

? https://stackoverflow.com/


? https://segmentfault.com/


? https://www.google.com/?gws_rd=ssl


- 逛技術(shù)社區(qū) MDN 掘金 CSDN 博客園等

![珠峰公眾號](https://user-gold-cdn.xitu.io/2018/12/11/1679c4ea744a4727?w=1050&h=620&f=jpeg&s=97754)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市胆剧,隨后出現(xiàn)的幾起案子絮姆,更是在濱河造成了極大的恐慌,老刑警劉巖秩霍,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篙悯,死亡現(xiàn)場離奇詭異,居然都是意外死亡铃绒,警方通過查閱死者的電腦和手機(jī)鸽照,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颠悬,“玉大人矮燎,你說我怎么就攤上這事定血。” “怎么了诞外?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵澜沟,是天一觀的道長。 經(jīng)常有香客問我峡谊,道長茫虽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任既们,我火速辦了婚禮濒析,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘啥纸。我一直安慰自己号杏,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布脾拆。 她就那樣靜靜地躺著馒索,像睡著了一般。 火紅的嫁衣襯著肌膚如雪名船。 梳的紋絲不亂的頭發(fā)上绰上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音渠驼,去河邊找鬼蜈块。 笑死,一個胖子當(dāng)著我的面吹牛迷扇,可吹牛的內(nèi)容都是我干的百揭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蜓席,長吁一口氣:“原來是場噩夢啊……” “哼器一!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起厨内,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤祈秕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后雏胃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體请毛,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年瞭亮,在試婚紗的時候發(fā)現(xiàn)自己被綠了方仿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖仙蚜,靈堂內(nèi)的尸體忽然破棺而出此洲,到底是詐尸還是另有隱情,我是刑警寧澤鳍征,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布黍翎,位于F島的核電站,受9級特大地震影響艳丛,放射性物質(zhì)發(fā)生泄漏匣掸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一氮双、第九天 我趴在偏房一處隱蔽的房頂上張望碰酝。 院中可真熱鬧,春花似錦戴差、人聲如沸送爸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袭厂。三九已至,卻和暖如春球匕,著一層夾襖步出監(jiān)牢的瞬間纹磺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工亮曹, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留橄杨,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓照卦,卻偏偏與公主長得像式矫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子役耕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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