Vue3 筆記

安裝


安裝Vue3,初始化npm:

npm init vue@3
cd dirname
npm i
npm run dev

一路回車即可帆锋。

修改App.vue:

<script>
export default {
  data() {
    return {
      message: 'LuckyStar'
    }
  }
}
</script>

<template>
  <h1>Hello {{ message }}</h1>
</template>

選項式API


  • 模板引用

特別的顷啼,如果一定要操作某個DOM,可以使用 模板引用

<script>
export default {
  mounted() {
    this.$refs.p.textContent = "hello world!"
  }
}
</script>

<template>
  <p ref="p">hello</p>
</template>
  • Vue3 生命周期

生命周期如下嫡秕。多了一個 setup() 函數(shù)


Vue3 生命周期

組合式API(Composition API)


  • setup() 函數(shù)

如上圖所示,setup() 函數(shù)比 beforeCreate() 更早被調(diào)用苹威。

1. Props 參數(shù)
export default {
  props: {
    title: String
  },
  setup(props) {
    console.log(props.title)
  }
}
2. Context 參數(shù)
export default {
  setup(props, context) {
    // 透傳 Attributes(非響應(yīng)式的對象昆咽,等價于 $attrs)
    console.log(context.attrs)

    // 插槽(非響應(yīng)式的對象,等價于 $slots)
    console.log(context.slots)

    // 觸發(fā)事件(函數(shù)牙甫,等價于 $emit)
    console.log(context.emit)

    // 暴露公共屬性(函數(shù))
    console.log(context.expose)
  }
}

context 是非響應(yīng)式的掷酗,可以安全解構(gòu)。

2.1 expose 暴露公共屬性
export default {
  setup(props, { expose }) {
    // 讓組件實例處于 “關(guān)閉狀態(tài)”
    // 即不向父組件暴露任何東西
    expose()

    const publicCount = ref(0)
    const privateCount = ref(0)
    // 有選擇地暴露局部狀態(tài)
    expose({ count: publicCount })
  }
}
3. 返回渲染函數(shù)

setup 也可以返回一個渲染函數(shù)窟哺,此時在渲染函數(shù)中可以直接使用在同一作用域下聲明的響應(yīng)式狀態(tài):

import { h, ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return () => h('div', count.value)
  }
}

返回一個渲染函數(shù)將會阻止我們返回其他東西泻轰。對于組件內(nèi)部來說,這樣沒有問題且轨,但如果我們想通過模板引用將這個組件的方法暴露給父組件浮声,那就有問題了。

我們可以通過調(diào)用 expose() 解決這個問題:

import { h, ref } from 'vue'

export default {
  setup(props, { expose }) {
    const count = ref(0)
    const increment = () => ++count.value

    expose({
      increment
    })

    return () => h('div', count.value)
  }
}
  • <script setup>

<script setup> 是在單文件組件 (SFC) 中使用組合式 API 的編譯時語法糖。當(dāng)同時使用 SFC 與組合式 API 時該語法是默認(rèn)推薦。相比于普通的 <script> 語法竭望,它具有更多優(yōu)勢:

  • 更少的樣板內(nèi)容贪磺,更簡潔的代碼。
  • 能夠使用純 TypeScript 聲明 props 和自定義事件。
  • 更好的運行時性能 (其模板會被編譯成同一作用域內(nèi)的渲染函數(shù),避免了渲染上下文代理對象)。
  • 更好的 IDE 類型推導(dǎo)性能 (減少了語言服務(wù)器從代碼中抽取類型的工作)矗钟。
<script setup>
console.log('hello script setup')
</script>
1. 頂層的綁定會被暴露給模板

當(dāng)使用 <script setup> 的時候,任何在 <script setup> 聲明的頂層的綁定 (包括變量嫌变,函數(shù)聲明真仲,以及 import 導(dǎo)入的內(nèi)容) 都能在模板中直接使用:

<script setup>
// 變量
const msg = 'Hello!'

// 函數(shù)
function log() {
  console.log(msg)
}
</script>

<template>
  <button @click="log">{{ msg }}</button>
</template>

import 導(dǎo)入的內(nèi)容也會以同樣的方式暴露。這意味著我們可以在模板表達(dá)式中直接使用導(dǎo)入的 helper 函數(shù)初澎,而不需要通過 methods 選項來暴露它:

<script setup>
import { capitalize } from './helpers'
</script>

<template>
  <div>{{ capitalize('hello') }}</div>
</template>
2. 響應(yīng)式

響應(yīng)式狀態(tài)需要明確使用 響應(yīng)式 API 來創(chuàng)建秸应。和 setup() 函數(shù)的返回值一樣虑凛,ref 在模板中使用的時候會自動解包:

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">{{ count }}</button>
</template>
3. 使用 Component
<script setup>
import MyComponent from './MyComponent.vue'
</script>

<template>
  <MyComponent />
</template>
4. 動態(tài) Component
<script setup>
import Foo from './Foo.vue'
import Bar from './Bar.vue'
</script>

<template>
  <component :is="Foo" />
  <component :is="someCondition ? Foo : Bar" />
</template>

Vue 響應(yīng)式基礎(chǔ)


https://cn.vuejs.org/guide/essentials/reactivity-fundamentals.html

Vue 響應(yīng)式的本質(zhì),實際上是一個 JavaScript Proxy软啼,其行為表現(xiàn)與一般對象相似桑谍。不同之處在于 Vue 能夠跟蹤對響應(yīng)式對象屬性的訪問與更改操作。

要在組件模板中使用響應(yīng)式狀態(tài)祸挪,需要在 setup() 函數(shù)中定義并返回锣披。

import { reactive } from 'vue'

export default {
  // `setup` 是一個專門用于組合式 API 的特殊鉤子函數(shù)
  setup() {
    const state = reactive({ count: 0 })

    // 暴露 state 到模板
    return {
      state
    }
  }
}
<div>{{ state.count }}</div>

自然,我們也可以在同一個作用域下定義一個更新響應(yīng)式狀態(tài)的函數(shù)贿条,并作為一個方法與狀態(tài)一起暴露出去:

import { reactive } from 'vue'

export default {
  setup() {
    const state = reactive({ count: 0 })

    function increment() {
      state.count++
    }

    // 不要忘記同時暴露 increment 函數(shù)
    return {
      state,
      increment
    }
  }
}
<button @click="increment">
  {{ state.count }}
</button>
<script setup> 簡化代碼

在 setup() 函數(shù)中手動暴露大量的狀態(tài)和方法非常繁瑣雹仿。幸運的是,我們可以通過使用構(gòu)建工具來簡化該操作整以。當(dāng)使用單文件組件(SFC)時胧辽,我們可以使用 <script setup> 來大幅度地簡化代碼。

<script setup>
import { reactive } from 'vue'

const state = reactive({ count: 0 })

function increment() {
  state.count++
}
</script>

<template>
  <button @click="increment">
    {{ state.count }}
  </button>
</template>
nextTick()

當(dāng)你更改響應(yīng)式狀態(tài)后公黑,DOM 會自動更新邑商。然而,你得注意 DOM 的更新并不是同步的凡蚜。相反人断,Vue 將緩沖它們直到更新周期的 “下個時機” 以確保無論你進行了多少次狀態(tài)更改,每個組件都只需要更新一次朝蜘。
若要等待一個狀態(tài)改變后的 DOM 更新完成恶迈,你可以使用 nextTick() 這個全局 API:

import { nextTick } from 'vue'

function increment() {
  state.count++
  nextTick(() => {
    // 訪問更新后的 DOM
  })
}
深層響應(yīng)性

在 Vue 中,狀態(tài)都是默認(rèn)深層響應(yīng)式的谱醇。這意味著即使在更改深層次的對象或數(shù)組暇仲,你的改動也能被檢測到。

import { reactive } from 'vue'

const obj = reactive({
  nested: { count: 0 },
  arr: ['foo', 'bar']
})

function mutateDeeply() {
  // 以下都會按照期望工作
  obj.nested.count++
  obj.arr.push('baz')
}

當(dāng)然也可以直接創(chuàng)建一個淺層響應(yīng)式對象枣抱。

響應(yīng)式代理 vs. 原始對象

值得注意的是熔吗,reactive() 返回的是一個原始對象的 Proxy辆床,它和原始對象是不相等的:

const raw = {}
const proxy = reactive(raw)

// 代理對象和原始對象不是全等的
console.log(proxy === raw) // false

只有代理對象是響應(yīng)式的佳晶,更改原始對象不會觸發(fā)更新。因此讼载,使用 Vue 的響應(yīng)式系統(tǒng)的最佳實踐是 僅使用你聲明對象的代理版本轿秧。

為保證訪問代理的一致性,對同一個原始對象調(diào)用 reactive() 會總是返回同樣的代理對象咨堤,而對一個已存在的代理對象調(diào)用 reactive() 會返回其本身:

// 在同一個對象上調(diào)用 reactive() 會返回相同的代理
console.log(reactive(raw) === proxy) // true

// 在一個代理上調(diào)用 reactive() 會返回它自己
console.log(reactive(proxy) === proxy) // true
reactive() 的局限性

reactive() API 有兩條限制:

  1. 僅對對象類型有效(對象菇篡、數(shù)組和 MapSet 這樣的集合類型)一喘,而對 string驱还、numberboolean 這樣的 原始類型 無效嗜暴。

  2. 因為 Vue 的響應(yīng)式系統(tǒng)是通過屬性訪問進行追蹤的,因此我們必須始終保持對該響應(yīng)式對象的相同引用议蟆。這意味著我們不可以隨意地“替換”一個響應(yīng)式對象闷沥,因為這將導(dǎo)致對初始引用的響應(yīng)性連接丟失:

let state = reactive({ count: 0 })

// 上面的引用 ({ count: 0 }) 將不再被追蹤(響應(yīng)性連接已丟失!)
state = reactive({ count: 1 })

用 ref() 定義響應(yīng)式變量


reactive() 的種種限制歸根結(jié)底是因為 JavaScript 沒有可以作用于所有值類型的 “引用” 機制咐容。為此舆逃,Vue 提供了一個 ref() 方法來允許我們創(chuàng)建可以使用任何值類型的響應(yīng)式 ref

import { ref } from 'vue'
const count = ref(0)

ref() 函數(shù)將傳入?yún)?shù)的值包裝為一個帶 .value 屬性的 ref 對象:

const count = ref(0)

console.log(count) // { value: 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

和響應(yīng)式對象的屬性類似,ref 的 .value 屬性也是響應(yīng)式的戳粒。同時路狮,當(dāng)值為對象類型時,會用 reactive() 自動轉(zhuǎn)換它的 .value蔚约。

一個包含對象類型值的 ref 可以響應(yīng)式地替換整個對象:

const objectRef = ref({ count: 0 })

// 這是響應(yīng)式的替換
objectRef.value = { count: 1 }

Vue3 生命周期


每個 Vue 組件實例在創(chuàng)建時都需要經(jīng)歷一系列的初始化步驟奄妨,比如設(shè)置好數(shù)據(jù)偵聽,編譯模板炊琉,掛載實例到 DOM展蒂,以及在數(shù)據(jù)改變時更新 DOM。在此過程中苔咪,它也會運行被稱為生命周期鉤子的函數(shù)锰悼,讓開發(fā)者有機會在特定階段運行自己的代碼。

注冊周期鉤子

舉例來說团赏,onMounted 鉤子可以用來在組件完成初始渲染并創(chuàng)建 DOM 節(jié)點后運行代碼:

<script setup>
import { onMounted } from 'vue'

onMounted(() => {
  console.log(`the component is now mounted.`)
})
</script>

偵聽器 Watch


在組合式 API 中箕般,我們可以使用 watch 函數(shù)在每次響應(yīng)式狀態(tài)發(fā)生變化時觸發(fā)回調(diào)函數(shù):

<script setup>
import { ref, watch } from 'vue'

const question = ref('')
const answer = ref('Questions usually contain a question mark. ;-)')

// 可以直接偵聽一個 ref
watch(question, async (newQuestion, oldQuestion) => {
  if (newQuestion.indexOf('?') > -1) {
    answer.value = 'Thinking...'
    try {
      const res = await fetch('https://yesno.wtf/api')
      answer.value = (await res.json()).answer
    } catch (error) {
      answer.value = 'Error! Could not reach the API. ' + error
    }
  }
})
</script>

<template>
  <p>
    Ask a yes/no question:
    <input v-model="question" />
  </p>
  <p>{{ answer }}</p>
</template>
watch 數(shù)據(jù)源類型

watch 的第一個參數(shù)可以是不同形式的“數(shù)據(jù)源”:它可以是一個 ref (包括計算屬性)、一個響應(yīng)式對象舔清、一個 getter 函數(shù)丝里、或多個數(shù)據(jù)源組成的數(shù)組:

const x = ref(0)
const y = ref(0)

// 單個 ref
watch(x, (newX) => {
  console.log(`x is ${newX}`)
})

// getter 函數(shù)
watch(
  () => x.value + y.value,
  (sum) => {
    console.log(`sum of x + y is: ${sum}`)
  }
)

// 多個來源組成的數(shù)組
watch([x, () => y.value], ([newX, newY]) => {
  console.log(`x is ${newX} and y is ${newY}`)
})

注意,你不能直接偵聽響應(yīng)式對象的屬性值体谒,例如:

const obj = reactive({ count: 0 })

// 錯誤杯聚,因為 watch() 得到的參數(shù)是一個 number
watch(obj.count, (count) => {
  console.log(`count is: ${count}`)
})

這里需要用一個返回該屬性的 getter 函數(shù):

// 提供一個 getter 函數(shù)
watch(
  () => obj.count,
  (count) => {
    console.log(`count is: ${count}`)
  }
)
深層偵聽器

直接給 watch() 傳入一個響應(yīng)式對象,會隱式地創(chuàng)建一個深層偵聽器——該回調(diào)函數(shù)在所有嵌套的變更時都會被觸發(fā):

const obj = reactive({ count: 0 })

watch(obj, (newValue, oldValue) => {
  // 在嵌套的屬性變更時觸發(fā)
  // 注意:`newValue` 此處和 `oldValue` 是相等的
  // 因為它們是同一個對象抒痒!
})

obj.count++

而 一個返回響應(yīng)式對象的 getter 函數(shù)幌绍,只有在返回不同的對象時,才會觸發(fā)回調(diào):

watch(
  () => state.someObject,
  () => {
    // 僅當(dāng) state.someObject 被替換時觸發(fā)
  }
)

你也可以給上面這個例子顯式地加上 deep 選項故响,強制轉(zhuǎn)成深層偵聽器:

watch(
  () => state.someObject,
  (newValue, oldValue) => {
    // 注意:`newValue` 此處和 `oldValue` 是相等的
    // *除非* state.someObject 被整個替換了
  },
  { deep: true }
)
watchEffect()

watch() 是懶執(zhí)行的:僅當(dāng)數(shù)據(jù)源變化時傀广,才會執(zhí)行回調(diào)。但在某些場景中彩届,我們希望在創(chuàng)建偵聽器時伪冰,立即執(zhí)行一遍回調(diào)。舉例來說樟蠕,我們想請求一些初始數(shù)據(jù)贮聂,然后在相關(guān)狀態(tài)更改時重新請求數(shù)據(jù)靠柑。我們可以這樣寫:

const url = ref('https://...')
const data = ref(null)

async function fetchData() {
  const response = await fetch(url.value)
  data.value = await response.json()
}

// 立即獲取
fetchData()
// ...再偵聽 url 變化
watch(url, fetchData)

我們可以用 watchEffect 來簡化上面的代碼。watchEffect() 會立即執(zhí)行一遍回調(diào)函數(shù)吓懈,如果這時函數(shù)產(chǎn)生了副作用病往,Vue 會自動追蹤副作用的依賴關(guān)系,自動分析出響應(yīng)源骄瓣。上面的例子可以重寫為:

watchEffect(async () => {
  const response = await fetch(url.value)
  data.value = await response.json()
})

這個例子中停巷,回調(diào)會立即執(zhí)行。在執(zhí)行期間榕栏,它會自動追蹤 url.value 作為依賴(和計算屬性的行為類似)畔勤。每當(dāng) url.value 變化時,回調(diào)會再次執(zhí)行扒磁。

watch vs. watchEffect

watch 和 watchEffect 都能響應(yīng)式地執(zhí)行有副作用的回調(diào)庆揪。它們之間的主要區(qū)別是追蹤響應(yīng)式依賴的方式:

  • watch 只追蹤明確偵聽的數(shù)據(jù)源。它不會追蹤任何在回調(diào)中訪問到的東西妨托。另外缸榛,僅在數(shù)據(jù)源確實改變時才會觸發(fā)回調(diào)。watch 會避免在發(fā)生副作用時追蹤依賴兰伤,因此内颗,我們能更加精確地控制回調(diào)函數(shù)的觸發(fā)時機。
  • watchEffect敦腔,則會在副作用發(fā)生期間追蹤依賴均澳。它會在同步執(zhí)行過程中,自動追蹤所有能訪問到的響應(yīng)式屬性符衔。這更方便找前,而且代碼往往更簡潔,但有時其響應(yīng)性依賴關(guān)系會不那么明確判族。

<Transition> & <TransitionGroup>


Vue 提供了兩個內(nèi)置組件躺盛,可以幫助你制作基于狀態(tài)變化的過渡和動畫:

  • <Transition> 會在一個元素或組件進入和離開 DOM 時應(yīng)用動畫。本章節(jié)會介紹如何使用它形帮。

  • <TransitionGroup> 會在一個 v-for 列表中的元素或組件被插入槽惫,移動,或移除時應(yīng)用動畫沃缘。

<Transition> 組件

該組件可以將進入和離開動畫應(yīng)用到通過默認(rèn)插槽傳遞給它的元素或組件上躯枢。進入或離開可以由以下的條件之一觸發(fā):

  • 由 v-if 所觸發(fā)的切換
  • 由 v-show 所觸發(fā)的切換
  • 由特殊元素 <component> 切換的動態(tài)組件

<Transition> 僅支持單個元素或者組件作為其插槽內(nèi)容则吟。如果內(nèi)容是組件槐臀,則組件必須僅有一個根元素。

基礎(chǔ)用法
<button @click="show = !show">Toggle</button>
<Transition>
  <p v-if="show">hello</p>
</Transition>
/* 下面我們會解釋這些 class 是做什么的 */
.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}
CSS 過渡效果 class
過渡效果 class
  1. v-enter-from:進入動畫的起始狀態(tài)氓仲。在元素插入之前添加水慨,在元素插入完成后的下一幀移除得糜。

  2. v-enter-active:進入動畫的生效狀態(tài)。應(yīng)用于整個進入動畫階段晰洒。在元素被插入之前添加朝抖,在過渡或動畫完成之后移除。這個 class 可以被用來定義進入動畫的持續(xù)時間谍珊、延遲與速度曲線類型治宣。

  3. v-enter-to:進入動畫的結(jié)束狀態(tài)。在元素插入完成后的下一幀被添加 (也就是 v-enter-from 被移除的同時)砌滞,在過渡或動畫完成之后移除侮邀。

  4. v-leave-from:離開動畫的起始狀態(tài)。在離開過渡效果被觸發(fā)時立即添加贝润,在一幀后被移除绊茧。

  5. v-leave-active:離開動畫的生效狀態(tài)。應(yīng)用于整個離開動畫階段打掘。在離開過渡效果被觸發(fā)時立即添加华畏,在過渡或動畫完成之后移除。這個 class 可以被用來定義離開動畫的持續(xù)時間尊蚁、延遲與速度曲線類型亡笑。

  6. v-leave-to:離開動畫的結(jié)束狀態(tài)。在一個離開動畫被觸發(fā)后的下一幀被添加 (也就是 v-leave-from 被移除的同時)横朋,在過渡或動畫完成之后移除况芒。

v-enter-active 和 v-leave-active 給我們提供了為進入和離開動畫指定不同速度曲線的能力,我們將在下面的小節(jié)中看到一個示例叶撒。

命名 Transition
<Transition name="fade">
  ...
</Transition>

對于一個有名字的過渡效果绝骚,對它起作用的過渡 class 會以其名字而不是 v 作為前綴。比如祠够,上方例子中被應(yīng)用的 class 將會是 fade-enter-active 而不是 v-enter-active压汪。這個“fade”過渡的 class 應(yīng)該是這樣:

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市古瓤,隨后出現(xiàn)的幾起案子止剖,更是在濱河造成了極大的恐慌,老刑警劉巖落君,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件穿香,死亡現(xiàn)場離奇詭異,居然都是意外死亡绎速,警方通過查閱死者的電腦和手機皮获,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纹冤,“玉大人洒宝,你說我怎么就攤上這事购公。” “怎么了雁歌?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵宏浩,是天一觀的道長。 經(jīng)常有香客問我靠瞎,道長比庄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任乏盐,我火速辦了婚禮印蔗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丑勤。我一直安慰自己华嘹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布法竞。 她就那樣靜靜地躺著耙厚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪岔霸。 梳的紋絲不亂的頭發(fā)上薛躬,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機與錄音呆细,去河邊找鬼型宝。 笑死,一個胖子當(dāng)著我的面吹牛絮爷,可吹牛的內(nèi)容都是我干的趴酣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼坑夯,長吁一口氣:“原來是場噩夢啊……” “哼岖寞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起柜蜈,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤仗谆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后淑履,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體隶垮,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年秘噪,在試婚紗的時候發(fā)現(xiàn)自己被綠了狸吞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖捷绒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贯要,我是刑警寧澤暖侨,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站崇渗,受9級特大地震影響字逗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宅广,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一葫掉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跟狱,春花似錦俭厚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至关翎,卻和暖如春扛门,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纵寝。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工论寨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爽茴。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓葬凳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親室奏。 傳聞我的和親對象是個殘疾皇子沮明,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

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