Vue3知識點(diǎn)

簡介

  • 2020年9月18日發(fā)布Vue3正式版本V3.0.0亏镰,命名為One Piece衔瓮。
  • Vue 的組件可以按兩種不同的風(fēng)格書寫:選項(xiàng)式 API 和組合式 API收厨。

該選哪一個(gè)缓溅?

  • 兩種 API 風(fēng)格都能夠覆蓋大部分的應(yīng)用場景洒沦。它們只是同一個(gè)底層系統(tǒng)所提供的兩套不同的接口。實(shí)際上钳榨,選項(xiàng)式 API 是在組合式 API 的基礎(chǔ)上實(shí)現(xiàn)的舰罚!關(guān)于 Vue 的基礎(chǔ)概念和知識在它們之間都是通用的。

  • 選項(xiàng)式 API 以“組件實(shí)例”的概念為中心 (即上述例子中的 this)薛耻,對于有面向?qū)ο笳Z言背景的用戶來說营罢,這通常與基于類的心智模型更為一致。同時(shí),它將響應(yīng)性相關(guān)的細(xì)節(jié)抽象出來饲漾,并強(qiáng)制按照選項(xiàng)來組織代碼蝙搔,從而對初學(xué)者而言更為友好。

  • 組合式 API 的核心思想是直接在函數(shù)作用域內(nèi)定義響應(yīng)式狀態(tài)變量考传,并將從多個(gè)函數(shù)中得到的狀態(tài)組合起來處理復(fù)雜問題吃型。這種形式更加自由,也需要你對 Vue 的響應(yīng)式系統(tǒng)有更深的理解才能高效使用僚楞。相應(yīng)的勤晚,它的靈活性也使得組織和重用邏輯的模式變得更加強(qiáng)大。

[圖片上傳失敗...(image-a9c136-1660454836197)]

Vue3帶來的變化

1. 性能提升1.3~2.x

  • 核心代碼 + Composition API :13.5kb泉褐,最小可以到11.75kb
  • 所有的Runtime:22.5kb(Vue2是32kb)
    為什么會(huì)有這么大的性能提升呢赐写? 這里就要說到 Compiler 的原理:
  • 靜態(tài)Node不再做更新處理
  • 靜態(tài)綁定的class和id不再做更新處理
  • vue在mount的過程中會(huì)編譯成ast語法樹, 會(huì)給動(dòng)態(tài)的內(nèi)容打上一個(gè)標(biāo)記PatchFlag膜赃,進(jìn)行更新分析(動(dòng)態(tài)綁定)挺邀,會(huì)區(qū)分哪些是靜態(tài)內(nèi)容哪些是動(dòng)態(tài)內(nèi)容,然后對動(dòng)態(tài)內(nèi)容去做更新處理
  • 事件監(jiān)聽器Cache緩存處理(cacheHandlers)跳座,組件創(chuàng)建的過程中不會(huì)去重復(fù)的多次實(shí)例化端铛,對內(nèi)存的優(yōu)化是非常好的,減少創(chuàng)建對象的數(shù)量疲眷,從而減少內(nèi)存占用提高性能
  • hoistStatich自動(dòng)針對多靜態(tài)節(jié)點(diǎn)進(jìn)行優(yōu)化禾蚕,輸出字符串
    測試地址:https://vue-next-template-explorer.netlify.app

2. Ts支持,新增:Fragment咪橙、Teleport夕膀、Suspense

  • Fragment不受根節(jié)點(diǎn)限制,渲染函數(shù)可接收Array美侦。意思就是我們在temeplate中不再受根節(jié)點(diǎn)限制产舞,可以任意的插入多個(gè)文本,字符串或者圖片
  • Teleport--類似Portal菠剩,隨用隨取比如:彈窗易猫、Actions,比如我們有可能需要在app節(jié)點(diǎn)之外比如body中控制一個(gè)彈窗的顯示或者隱藏具壮,可以用到它
  • Suspense 從框架層面的一個(gè)異步組件准颓,可以支持嵌套加載的一個(gè)場景,比如樹形組件我們要加載多層加的組織架構(gòu)棺妓,我們希望把下面所有的組織架構(gòu)都加載完成以后再顯示整個(gè)組件攘已,這個(gè)時(shí)候就需要用到它。例如:async setup()

3. 按需加載(配合vite)& 組合Api

Vue2和Vue3的比較

1. 為什么要用 Composition API怜跑?

(1) Vue2對于復(fù)雜邏輯的組件样勃,后期變得無法維護(hù)
下面是vue2實(shí)現(xiàn)加減的代碼:

<template>
  <div class="homePage">
    <p>count: {{ count }}</p>   
    <p>倍數(shù): {{ multiple }}</p>        
    <div>
      <button style="margin-right: 10px" @click="increase">加1</button>
      <button @click="decrease">減一</button>    
    </div>      
  </div>
</template>
<script>
export default {
  data() {
    return { count: 0 };
  },
  computed: {
    multiple() {
      return 2 * this.count;
    },
  },
  methods: {
    increase() {
      this.count++;
    },
    decrease() {
      this.count--;
    },
  },
};
</script>

上面代碼只是實(shí)現(xiàn)了對 count 的加減以及顯示倍數(shù)吠勘, 就需要分別在data、methods峡眶、computed中進(jìn)行操作剧防,當(dāng)我們增加一個(gè)需求,就會(huì)出現(xiàn)下圖的情況:

[圖片上傳失敗...(image-7fc1e4-1660454836197)]
當(dāng)我們業(yè)務(wù)復(fù)雜了就會(huì)大量出現(xiàn)上面的情況辫樱, 隨著復(fù)雜度上升峭拘,就會(huì)出現(xiàn)這樣一張圖:

[圖片上傳失敗...(image-43cb6f-1660454836197)]
當(dāng)這個(gè)組件的代碼超過幾百行時(shí),這時(shí)增加或者修改某個(gè)需求狮暑, 就要在data鸡挠、methods、computed以及mounted中反復(fù)的跳轉(zhuǎn)
如果可以按照邏輯進(jìn)行分割心例,將上面這張圖變成下邊這張圖宵凌,是不是就清晰很多了呢, 這樣的代碼可讀性和可維護(hù)性都更高:

[圖片上傳失敗...(image-6d6040-1660454836197)]

那么vue2.x版本給出的解決方案就是Mixin, 但是使用Mixin會(huì)有缺陷:

  • 命名空間沖突
  • 不清楚暴露出來的變量的作用
  • 邏輯重用到其他 component 經(jīng)常遇到問題(不易復(fù)用)
    Vue3.x就推出了 Composition API 主要就是為了解決上面的問題,將零散分布的邏輯組合在一起來維護(hù)止后,并且還可以將單獨(dú)的功能邏輯拆分成單獨(dú)的文件。

(2)scoped slot作用域插槽(配置項(xiàng)多溜腐、代碼分裂译株、性能差)
(3) Vue2對Ts支持不充分
(4)Vue3使復(fù)雜組件邏輯進(jìn)行分離,組件間的邏輯共享
(5)Vue3組合式API + 函數(shù)式編程

組合式 API (Composition API)

  • 通過組合式 API挺益,我們可以使用導(dǎo)入的 API 函數(shù)來描述組件邏輯歉糜。在單文件組件中,組合式 API 通常會(huì)與 <script setup> 搭配使用望众。這個(gè) setup attribute 是一個(gè)標(biāo)識匪补,告訴 Vue 需要在編譯時(shí)進(jìn)行一些處理,讓我們可以更簡潔地使用組合式 API烂翰。比如夯缺,<script setup> 中的導(dǎo)入和頂層變量/函數(shù)都能夠在模板中直接使用。
    [圖片上傳失敗...(image-fcfc2-1660454836197)]

1. setup

  • setup是 Vue3.x 新增的一個(gè)選項(xiàng)甘耿, 他是組件內(nèi)使用 Composition API的入口踊兜。
export default defineComponent({
  beforeCreate() {
    console.log("----beforeCreate----");
  },
  created() {
    console.log("----created----");
  },
  setup() {
    console.log("----setup----");
  },
})

[圖片上傳失敗...(image-cf7909-1660454836197)]

  • 通過代碼打印結(jié)果,setup 執(zhí)行時(shí)機(jī)是在 beforeCreate 之前執(zhí)行
setup 參數(shù)
  • 使用setup時(shí)佳恬,它接受兩個(gè)參數(shù):
  1. props: 組件傳入的屬性
  2. context
  • setup 中接受的props是響應(yīng)式的捏境, 當(dāng)傳入新的 props 時(shí),會(huì)及時(shí)被更新毁葱。由于是響應(yīng)式的垫言, 所以不可以使用 ES6 解構(gòu),解構(gòu)會(huì)消除它的響應(yīng)式倾剿。
  • 錯(cuò)誤代碼示例筷频, 這段代碼會(huì)讓 props 不再支持響應(yīng)式:
export default defineComponent ({
    setup(props, context) {
        const { name } = props
        console.log(name)
    },
})
  • 開發(fā)中我們想要使用解構(gòu),還能保持props的響應(yīng)式,需要用到后面的toRefs來解決
  • setup中不能訪問 Vue2 中最常用的this對象,所以context中就提供了this中最常用的三個(gè)屬性:attrs截驮、slotemit分別對應(yīng) Vue2.x 中的 $attr屬性笑陈、slot插槽 和$emit發(fā)射事件。并且這幾個(gè)屬性都是自動(dòng)同步最新的值葵袭,所以我們每次使用拿到的都是最新值涵妥。

2. reactive、ref 與 toRefs

  • 在 vue2.x 中坡锡, 定義數(shù)據(jù)都是在data中蓬网, 但是 Vue3.x 可以使用reactive和ref來進(jìn)行數(shù)據(jù)定義。
import { ref } from 'vue'

const count = ref(0)

reactive函數(shù)可以代理一個(gè)對象鹉勒, 但是不能代理基本類型帆锋,例如字符串、數(shù)字禽额、boolean 等

<template>
  <div class="homePage">
    <p>第 {{ year }} 年</p>
    <p>姓名: {{ nickname }}</p>
    <p>年齡: {{ age }}</p>
  </div>
</template>

<script>
import { defineComponent, reactive, ref } from "vue";
export default defineComponent({
  setup() {
    const year = ref(0);
    const user = reactive({ nickname: "xiaofan", age: 26, gender: "女" });
    setInterval(() => {
      year.value++;
      user.age++;
    }, 1000);
    return {
      year,
      user
    };
  },
});
</script>

上面的代碼中锯厢,我們綁定到頁面是通過user.name, user.age;這樣寫感覺很繁瑣脯倒,我們能不能直接將user中的屬性解構(gòu)出來使用呢? 答案是不能直接對user進(jìn)行結(jié)構(gòu)实辑, 這樣會(huì)消除它的響應(yīng)式, 這里就和上面我們說props不能使用 ES6 直接解構(gòu)就呼應(yīng)上了藻丢。那我們就想使用解構(gòu)后的數(shù)據(jù)怎么辦剪撬,解決辦法就是使用toRefs
toRefs 用于將一個(gè) reactive 對象轉(zhuǎn)化為屬性全部為 ref 對象的普通對象悠反。具體使用方式如下:

<template>
  <div class="homePage">
    <p>第 {{ year }} 年</p>
    <p>姓名: {{ nickname }}</p>
    <p>年齡: {{ age }}</p>
  </div>
</template>

<script>
import { defineComponent, reactive, ref, toRefs } from "vue";
export default defineComponent({
  setup() {
    const year = ref(0);
    const user = reactive({ nickname: "xiaofan", age: 26, gender: "女" });
    setInterval(() => {
      year.value++;
      user.age++;
    }, 1000);
    return {
      year,
      // 使用reRefs
      ...toRefs(user),
    };
  },
});
</script>

生命周期鉤子

[圖片上傳失敗...(image-e57ed6-1660454836197)]

從圖中我們可以看到 Vue3.0 新增了setup残黑,這個(gè)在前面我們也詳細(xì)說了, 然后是將 Vue2.x 中的beforeDestroy名稱變更成beforeUnmount; destroyed 表更為 unmounted斋否,作者說這么變更純粹是為了更加語義化梨水,因?yàn)橐粋€(gè)組件是一個(gè)mountunmount的過程。其他 Vue2 中的生命周期仍然保留如叼。
上邊 生命周期圖 中并沒包含全部的生命周期鉤子冰木, 還有其他的幾個(gè), 全部生命周期鉤子如圖所示:
[圖片上傳失敗...(image-e1eadd-1660454836197)]

我們可以看到 beforeCreatecreatedsetup 替換了(但是Vue3中你仍然可以使用笼恰, 因?yàn)閂ue3是向下兼容的踊沸, 也就是你實(shí)際使用的是vue2的)。其次社证,鉤子命名都增加了 on ; Vue3.x還新增用于調(diào)試的鉤子函數(shù) onRenderTriggeredonRenderTricked

自定義 Hooks

開篇的時(shí)候我們使用 Vue2.x 寫了一個(gè)實(shí)現(xiàn)加減的例子逼龟, 這里可以將其封裝成一個(gè) hook, 我們約定這些「自定義 Hook」以 use 作為前綴,和普通的函數(shù)加以區(qū)分追葡。 useCount.ts 實(shí)現(xiàn):

import { ref, Ref, computed } from "vue";

type CountResultProps = {
  count: Ref<number>;
  multiple: Ref<number>;
  increase: (delta?: number) => void;
  decrease: (delta?: number) => void;
};

export default function useCount(initValue = 1): CountResultProps {
  const count = ref(initValue);

  const increase = (delta?: number): void => {
    if (typeof delta !== "undefined") {
      count.value += delta;
    } else {
      count.value += 1;
    }
  };
  const multiple = computed(() => count.value * 2);

  const decrease = (delta?: number): void => {
    if (typeof delta !== "undefined") {
      count.value -= delta;
    } else {
      count.value -= 1;
    }
  };

  return {
    count,
    multiple,
    increase,
    decrease,
  };
}

接下來看一下在組件中使用useCount這個(gè) hook:

<template>
  <p>count: {{ count }}</p>
  <p>倍數(shù): {{ multiple }}</p>
  <div>
    <button @click="increase()">加1</button>
    <button @click="decrease()">減一</button>
  </div>
</template>

<script lang="ts">
import useCount from "../hooks/useCount";
 setup() {
    const { count, multiple, increase, decrease } = useCount(10);
        return {
            count,
            multiple,
            increase,
            decrease,
        };
    },
</script>

簡單對比 vue2.x 與 vue3.x 響應(yīng)式

Vue3.x 將使用 Proxy 取代 Vue2.x 版本的 Object.defineProperty
這里就簡單對比一下:

  • Object.defineProperty只能劫持對象的屬性腺律, 而 Proxy 是直接代理對象

由于Object.defineProperty只能劫持對象屬性奕短,需要遍歷對象的每一個(gè)屬性,如果屬性值也是對象匀钧,就需要遞歸進(jìn)行深度遍歷翎碑。但是 Proxy 直接代理對象, 不需要遍歷操作

  • Object.defineProperty對新增屬性需要手動(dòng)進(jìn)行Observe

因?yàn)?code>Object.defineProperty劫持的是對象的屬性之斯,所以新增屬性時(shí)日杈,需要重新遍歷對象, 對其新增屬性再次使用Object.defineProperty進(jìn)行劫持佑刷。也就是 Vue2.x 中給數(shù)組和對象新增屬性時(shí)莉擒,需要使用set才能保證新增的屬性也是響應(yīng)式的,set內(nèi)部也是通過調(diào)用Object.defineProperty去處理的

Teleport

Teleport 就像是哆啦 A 夢中的「任意門」,任意門的作用就是可以將人瞬間傳送到另一個(gè)地方瘫絮。有了這個(gè)認(rèn)識涨冀,我們再來看一下為什么需要用到 Teleport 的特性呢,看一個(gè)小例子:

  • 在子組件Header中使用到Dialog組件麦萤,我們實(shí)際開發(fā)中經(jīng)常會(huì)在類似的情形下使用到 Dialog 鹿鳖,此時(shí)Dialog就被渲染到一層層子組件內(nèi)部,處理嵌套組件的定位壮莹、z-index和樣式都變得困難栓辜。
  • Dialog從用戶感知的層面,應(yīng)該是一個(gè)獨(dú)立的組件垛孔,從 dom 結(jié)構(gòu)應(yīng)該完全剝離 Vue 頂層組件掛載的 DOM;同時(shí)還可以使用到 Vue 組件內(nèi)的狀態(tài)(data或者props)的值施敢。簡單來說就是,即希望繼續(xù)在組件內(nèi)部使用Dialog, 又希望渲染的 DOM 結(jié)構(gòu)不嵌套在組件的 DOM 中周荐。
  • 此時(shí)就需要 Teleport 上場,我們可以用<Teleport>包裹Dialog, 此時(shí)就建立了一個(gè)傳送門僵娃,可以將Dialog渲染的內(nèi)容傳送到任何指定的地方概作。
  • 接下來就舉個(gè)小例子,看看 Teleport 的使用方式:

我們希望 Dialog 渲染的 dom 和頂層組件是兄弟節(jié)點(diǎn)關(guān)系, 在index.html文件中定義一個(gè)供掛載的元素:

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

定義一個(gè)Dialog組件Dialog.vue, 留意 to 屬性默怨, 與上面的id選擇器一致:

<template>
  <teleport to="#dialog">
    <div class="dialog">
      <div class="dialog_wrapper">
        <div class="dialog_header" v-if="title">
          <slot name="header">
            <span>{{ title }}</span>
          </slot>
        </div>
      </div>
      <div class="dialog_content">
        <slot></slot>
      </div>
      <div class="dialog_footer">
        <slot name="footer"></slot>
      </div>
    </div>
  </teleport>
</template>

最后在一個(gè)子組件Header.vue中使用Dialog組件

<div class="header">
    ...
    <navbar />
    <Dialog v-if="dialogVisible"></Dialog>
</div>

[圖片上傳失敗...(image-8ff413-1660454836197)]

可以看到讯榕,我們使用 teleport 組件,通過 to 屬性匙睹,指定該組件渲染的位置與 <div id="app"></div> 同級愚屁,也就是在 body 下,但是 Dialog 的狀態(tài) dialogVisible 又是完全由內(nèi)部 Vue 組件控制.

Suspense

Suspense是 Vue3.x 中新增的特性痕檬, 那它有什么用呢霎槐?我們通過 Vue2.x 中的一些場景來認(rèn)識它的作用。 Vue2.x 中應(yīng)該經(jīng)常遇到這樣的場景:

<template>
<div>
    <div v-if="!loading">
        ...
    </div>
    <div v-if="loading">
        加載中...
    </div>
</div>
</template>

在前后端交互獲取數(shù)據(jù)時(shí)梦谜, 是一個(gè)異步過程丘跌,一般我們都會(huì)提供一個(gè)加載中的動(dòng)畫袭景,當(dāng)數(shù)據(jù)返回時(shí)配合v-if來控制數(shù)據(jù)顯示。
如果你使用過vue-async-manager這個(gè)插件來完成上面的需求闭树, 你對Suspense可能不會(huì)陌生耸棒,Vue3.x 感覺就是參考了vue-async-manager.
Vue3.x 新出的內(nèi)置組件Suspense, 它提供兩個(gè)template slot, 剛開始會(huì)渲染一個(gè) fallback 狀態(tài)下的內(nèi)容, 直到到達(dá)某個(gè)條件后才會(huì)渲染 default 狀態(tài)的正式內(nèi)容报辱, 通過使用Suspense組件進(jìn)行展示異步渲染就更加的簡單与殃。注意如果使用 Suspense, 要返回一個(gè) promise
使用:

 <Suspense>
        <template #default>
            <async-component></async-component>
        </template>
        <template #fallback>
            <div>
                Loading...
            </div>
        </template>
  </Suspense>

asyncComponent.vue:

<template>
<div>
    <h4>這個(gè)是一個(gè)異步加載數(shù)據(jù)</h4>
    <p>用戶名:{{user.nickname}}</p>
    <p>年齡:{{user.age}}</p>
</div>
</template>

<script>
import { defineComponent } from "vue"
import axios from "axios"
export default defineComponent({
    setup(){
        const rawData = await axios.get("http://xxx.xinp.cn/user")
        return {
            user: rawData.data
        }
    }
})
</script>

從上面代碼來看,Suspense 只是一個(gè)帶插槽的組件捏肢,只是它的插槽指定了defaultfallback 兩種狀態(tài)奈籽。

片段(Fragment)

在 Vue2.x 中, template中只允許有一個(gè)根節(jié)點(diǎn):

<template>
    <div>
        <span></span>
        <span></span>
    </div>
</template>

但是在 Vue3.x 中鸵赫,你可以直接寫多個(gè)根節(jié)點(diǎn)

<template>
    <span></span>
    <span></span>
</template>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末衣屏,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子辩棒,更是在濱河造成了極大的恐慌狼忱,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件一睁,死亡現(xiàn)場離奇詭異钻弄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)者吁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門窘俺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人复凳,你說我怎么就攤上這事瘤泪。” “怎么了育八?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵对途,是天一觀的道長。 經(jīng)常有香客問我髓棋,道長实檀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任按声,我火速辦了婚禮膳犹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘儒喊。我一直安慰自己镣奋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布怀愧。 她就那樣靜靜地躺著侨颈,像睡著了一般余赢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哈垢,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天妻柒,我揣著相機(jī)與錄音,去河邊找鬼耘分。 笑死举塔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的求泰。 我是一名探鬼主播央渣,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼渴频!你這毒婦竟也來了芽丹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤卜朗,失蹤者是張志新(化名)和其女友劉穎拔第,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體场钉,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚊俺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逛万。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泳猬。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宇植,靈堂內(nèi)的尸體忽然破棺而出暂殖,到底是詐尸還是另有隱情,我是刑警寧澤当纱,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站踩窖,受9級特大地震影響坡氯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜洋腮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一箫柳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧啥供,春花似錦悯恍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞬欧。三九已至,卻和暖如春罢防,著一層夾襖步出監(jiān)牢的瞬間艘虎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工咒吐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留野建,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓恬叹,卻偏偏與公主長得像候生,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子绽昼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

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