Vue3 組合式 API 的基礎(chǔ) —— setup

參考文檔

組合式 API 基礎(chǔ) - Vue3中文文檔
Setup - Vue3中文文檔

一、setup 是什么?

  • 為了開(kāi)始使用組合式 API凭涂,我們首先需要一個(gè)可以實(shí)際使用它的地方。在 Vue 組件中屉更,我們將此位置稱為 setup删壮。
  • 它是一個(gè)組件選項(xiàng)

觀看 Vue Mastery 上的免費(fèi) setup 視頻综慎。

PS: 個(gè)人覺(jué)得這個(gè)視頻講的挺好的莱找。

二酬姆、在哪里使用 setup ?

setup 是一個(gè)組件選項(xiàng)奥溺,所以像別的組件選項(xiàng)一樣辞色,寫(xiě)在組件導(dǎo)出的對(duì)象里。

<script>
  export default {
    name: "App",
    setup() {
      // ...

      return {
        // ...
      }
    },
  }
</script>

三浮定、使用 setup 的正確姿勢(shì)

官方文檔如此描述:
setup 選項(xiàng)應(yīng)該是一個(gè)接受 propscontext 的函數(shù)相满。
此外,我們從 setup 返回的所有內(nèi)容都將暴露給組件的其余部分 (計(jì)算屬性桦卒、方法立美、生命周期鉤子等等) 以及組件的模板。

個(gè)人覺(jué)得可以理解為:

  1. setup 選項(xiàng)應(yīng)該為一個(gè)函數(shù)
  2. setup 選項(xiàng)函數(shù)接受兩個(gè)參數(shù): propscontext
  3. setup 選項(xiàng)函數(shù)需要返回要暴露給組件的內(nèi)容

setup 函數(shù)的參數(shù)

1. setup 函數(shù)中的第一個(gè)參數(shù) —— props

正如在一個(gè)標(biāo)準(zhǔn)組件中所期望的那樣方灾,setup 函數(shù)中的 props 是響應(yīng)式的建蹄,當(dāng)傳入新的 prop 時(shí),它將被更新裕偿。

// MyBook.vue

export default {
  props: {
    title: String
  },
  setup(props) {
    console.log(props.title)
  }
}

WARNING:

但是洞慎,因?yàn)?props 是響應(yīng)式的,你不能使用 ES6 解構(gòu)嘿棘,因?yàn)樗鼤?huì)消除 prop 的響應(yīng)性劲腿。
如果需要解構(gòu) prop,可以通過(guò)使用 setup 函數(shù)中的 toRefs 來(lái)安全地完成此操作鸟妙。

// MyBook.vue

import { toRefs } from 'vue'

setup(props) {
    const { title } = toRefs(props)

    console.log(title.value)
}

2. setup 函數(shù)中的第二個(gè)參數(shù) —— context

context 上下文是一個(gè)普通的 JavaScript 對(duì)象焦人,它暴露三個(gè)組件的 property:

// MyBook.vue
export default {
  setup(props, context) {
    // Attribute (非響應(yīng)式對(duì)象)
    console.log(context.attrs)

    // 插槽 (非響應(yīng)式對(duì)象)
    console.log(context.slots)

    // 觸發(fā)事件 (方法)
    console.log(context.emit)
  }
}

context 是一個(gè)普通的 JavaScript 對(duì)象,也就是說(shuō)重父,它不是響應(yīng)式的花椭,這意味著你可以安全地對(duì) context 使用 ES6 解構(gòu)。

// MyBook.vue
export default {
  setup(props, { attrs, slots, emit }) {
    ...
  }
}

attrsslots 是有狀態(tài)的對(duì)象房午,它們總是會(huì)隨組件本身的更新而更新个从。這意味著你應(yīng)該避免對(duì)它們進(jìn)行解構(gòu),并始終以 attrs.xslots.x 的方式引用 property。請(qǐng)注意嗦锐,與 props 不同,attrsslots 是非響應(yīng)式的沪曙。如果你打算根據(jù) attrsslots 更改應(yīng)用副作用奕污,那么應(yīng)該在 onUpdated 生命周期鉤子中執(zhí)行此操作。

setup 函數(shù)的返回值

1. setup 函數(shù)的返回值 —— 對(duì)象

如果 setup 返回一個(gè)對(duì)象液走,則可以在組件的模板中像傳遞給 setupprops property 一樣訪問(wèn)該對(duì)象的 property:

<!-- MyBook.vue -->
<template>
  <!-- 模板中使用會(huì)被自動(dòng)解開(kāi)碳默,所以不需要 .value  -->
  <div>{{ readersNumber }} {{ book.title }}</div>
</template>

<script>
  import { ref, reactive } from 'vue'

  export default {
    setup() {
      const readersNumber = ref(0)
      const book = reactive({ title: 'Vue 3 Guide' })

      // expose to template
      return {
        readersNumber,
        book
      }
    }
  }
</script>

注意,從 setup 返回的 refs 在模板中訪問(wèn)時(shí)是被自動(dòng)解開(kāi)的缘眶,因此不應(yīng)在模板中使用 .value嘱根。

2. setup 函數(shù)的返回值 —— 渲染函數(shù)

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

// MyBook.vue

import { h, ref, reactive } from 'vue'

export default {
  setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // Please note that we need to explicitly expose ref value here
    return () => h('div', [readersNumber.value, book.title])
  }
}

新的 setup 組件選項(xiàng)在創(chuàng)建組件之前執(zhí)行巷懈,一旦 props 被解析该抒,并充當(dāng)合成 API 的入口點(diǎn)。

三顶燕、setup 函數(shù)內(nèi)部一般不使用 this

setup() 內(nèi)部凑保,this 不會(huì)是該活躍實(shí)例的引用,因?yàn)?setup() 是在解析其它組件選項(xiàng)之前被調(diào)用的涌攻,所以 setup() 內(nèi)部的 this 的行為與其它選項(xiàng)中的 this 完全不同欧引。這在和其它選項(xiàng)式 API 一起使用 setup() 時(shí)可能會(huì)導(dǎo)致混淆。

四恳谎、響應(yīng)式系統(tǒng) API

1. reactive

reactive() 接收一個(gè)普通對(duì)象然后返回該普通對(duì)象的響應(yīng)式代理芝此。等同于 2.x 的 Vue.observable()

const obj = reactive({ count: 0 })

響應(yīng)式轉(zhuǎn)換是“深層的”:會(huì)影響對(duì)象內(nèi)部所有嵌套的屬性∫蛲矗基于 ES2015 的 Proxy 實(shí)現(xiàn)婚苹,返回的代理對(duì)象不等于原始對(duì)象。建議僅使用代理對(duì)象而避免依賴原始對(duì)象婚肆。

<template>
  <div id="app">{ state.count }</div>
</template>

<script>
import { reactive } from 'vue'
export default {
  setup() {
    // state 現(xiàn)在是一個(gè)響應(yīng)式的狀態(tài)
    const state = reactive({
      count: 0,
    })
  }
}
</script>

2. ref

接受一個(gè)參數(shù)值并返回一個(gè)響應(yīng)式且可改變的 ref 對(duì)象租副。ref 對(duì)象擁有一個(gè)指向內(nèi)部值的單一屬性 .value

const count = ref(0)
console.log(count.value) // 0

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

如果傳入 ref 的是一個(gè)對(duì)象较性,將調(diào)用 reactive 方法進(jìn)行深層響應(yīng)轉(zhuǎn)換用僧。

  • 模板中訪問(wèn)

    當(dāng) ref 作為渲染上下文的屬性返回(即在setup() 返回的對(duì)象中)并在模板中使用時(shí),它會(huì)自動(dòng)解套赞咙,無(wú)需在模板內(nèi)額外書(shū)寫(xiě) .value

    <template>
      <div>{{ count }}</div>
    </template>
    
    <script>
      export default {
        setup() {
          return {
            count: ref(0),
          }
        },
      }
    </script>
    
  • 作為響應(yīng)式對(duì)象的屬性訪問(wèn)

    當(dāng) ref 作為 reactive 對(duì)象的 property 被訪問(wèn)或修改時(shí)责循,也將自動(dòng)解套 value 值,其行為類(lèi)似普通屬性:

    const count = ref(0)
    const state = reactive({
      count,
    })
    
    console.log(state.count) // 0
    
    state.count = 1
    console.log(count.value) // 1
    

    注意如果將一個(gè)新的 ref 分配給現(xiàn)有的 ref攀操, 將替換舊的 ref:

    const otherCount = ref(2)
    
    state.count = otherCount
    console.log(state.count) // 2
    console.log(count.value) // 1
    

    注意當(dāng)嵌套在 reactive Object 中時(shí)院仿,ref 才會(huì)解套。從 Array 或者 Map 等原生集合類(lèi)中訪問(wèn) ref 時(shí),不會(huì)自動(dòng)解套:

    const arr = reactive([ref(0)])
    // 這里需要 .value
    console.log(arr[0].value)
    
    const map = reactive(new Map([['foo', ref(0)]]))
    // 這里需要 .value
    console.log(map.get('foo').value)
    
  • 類(lèi)型定義

    interface Ref<T> {
      value: T
    }
    
    function ref<T>(value: T): Ref<T>
    

    有時(shí)我們可能需要為 ref 做一個(gè)較為復(fù)雜的類(lèi)型標(biāo)注歹垫。我們可以通過(guò)在調(diào)用 ref 時(shí)傳遞泛型參數(shù)來(lái)覆蓋默認(rèn)推導(dǎo):

    const foo = ref<string | number>('foo') // foo 的類(lèi)型: Ref<string | number>
    
    foo.value = 123 // 能夠通過(guò)剥汤!
    

3. computed

使用響應(yīng)式 computed API 有兩種方式:

  1. 傳入一個(gè) getter 函數(shù),返回一個(gè)默認(rèn)不可手動(dòng)修改的 ref 對(duì)象排惨。
const count = ref(1)
const plusOne = computed(() => count.value + 1)

console.log(plusOne.value) // 2

plusOne.value++ // 錯(cuò)誤吭敢!
  1. 傳入一個(gè)擁有 getset 函數(shù)的對(duì)象,創(chuàng)建一個(gè)可手動(dòng)修改的計(jì)算狀態(tài)暮芭。
const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: (val) => {
    count.value = val - 1
  },
})

plusOne.value = 1
console.log(count.value) // 0

  • 類(lèi)型定義

    // 只讀的
    function computed<T>(getter: () => T): Readonly<Ref<Readonly<T>>>
    
    // 可更改的
    function computed<T>(options: {
      get: () => T
      set: (value: T) => void
    }): Ref<T>
    
    

4. readonly

傳入一個(gè)對(duì)象(響應(yīng)式或普通)或 ref鹿驼,返回一個(gè)原始對(duì)象的只讀代理。一個(gè)只讀的代理是“深層的”辕宏,對(duì)象內(nèi)部任何嵌套的屬性也都是只讀的畜晰。

const original = reactive({ count: 0 })

const copy = readonly(original)

watchEffect(() => {
  // 依賴追蹤
  console.log(copy.count)
})

// original 上的修改會(huì)觸發(fā) copy 上的偵聽(tīng)
original.count++

// 無(wú)法修改 copy 并會(huì)被警告
copy.count++ // warning!

5. watchEffect

立即執(zhí)行傳入的一個(gè)函數(shù),并響應(yīng)式追蹤其依賴瑞筐,并在其依賴變更時(shí)重新運(yùn)行該函數(shù)凄鼻。

const count = ref(0)

watchEffect(() => console.log(count.value))
// -> 打印出 0

setTimeout(() => {
  count.value++
  // -> 打印出 1
}, 100)

  1. 停止偵聽(tīng)

當(dāng) watchEffect 在組件的 setup() 函數(shù)或生命周期鉤子被調(diào)用時(shí), 偵聽(tīng)器會(huì)被鏈接到該組件的生命周期面哼,并在組件卸載時(shí)自動(dòng)停止野宜。

在一些情況下,也可以顯式調(diào)用返回值以停止偵聽(tīng):

const stop = watchEffect(() => {
  /* ... */
})

// 之后
stop()
  1. 清除副作用

有時(shí)副作用函數(shù)會(huì)執(zhí)行一些異步的副作用, 這些響應(yīng)需要在其失效時(shí)清除(即完成之前狀態(tài)已改變了)魔策。所以偵聽(tīng)副作用傳入的函數(shù)可以接收一個(gè) onInvalidate 函數(shù)作入?yún)? 用來(lái)注冊(cè)清理失效時(shí)的回調(diào)匈子。當(dāng)以下情況發(fā)生時(shí),這個(gè)失效回調(diào)會(huì)被觸發(fā):

  • 副作用即將重新執(zhí)行時(shí)

  • 偵聽(tīng)器被停止 (如果在 setup() 或 生命周期鉤子函數(shù)中使用了 watchEffect, 則在卸載組件時(shí))

watchEffect((onInvalidate) => {
  const token = performAsyncOperation(id.value)
  onInvalidate(() => {
    // id 改變時(shí) 或 停止偵聽(tīng)時(shí)
    // 取消之前的異步操作
    token.cancel()
  })
})

我們之所以是通過(guò)傳入一個(gè)函數(shù)去注冊(cè)失效回調(diào)闯袒,而不是從回調(diào)返回它(如 React useEffect 中的方式)虎敦,是因?yàn)榉祷刂祵?duì)于異步錯(cuò)誤處理很重要。

在執(zhí)行數(shù)據(jù)請(qǐng)求時(shí)政敢,副作用函數(shù)往往是一個(gè)異步函數(shù):

const data = ref(null)
watchEffect(async () => {
  data.value = await fetchData(props.id)
})

我們知道異步函數(shù)都會(huì)隱式地返回一個(gè) Promise其徙,但是清理函數(shù)必須要在 Promise 被 resolve 之前被注冊(cè)。另外喷户,Vue 依賴這個(gè)返回的 Promise 來(lái)自動(dòng)處理 Promise 鏈上的潛在錯(cuò)誤唾那。

  1. 副作用刷新時(shí)機(jī)

Vue 的響應(yīng)式系統(tǒng)會(huì)緩存副作用函數(shù),并異步地刷新它們褪尝,這樣可以避免同一個(gè) tick 中多個(gè)狀態(tài)改變導(dǎo)致的不必要的重復(fù)調(diào)用闹获。在核心的具體實(shí)現(xiàn)中, 組件的更新函數(shù)也是一個(gè)被偵聽(tīng)的副作用。當(dāng)一個(gè)用戶定義的副作用函數(shù)進(jìn)入隊(duì)列時(shí), 會(huì)在所有的組件更新后執(zhí)行:

<template>
  <div>{{ count }}</div>
</template>

<script>
  export default {
    setup() {
      const count = ref(0)

      watchEffect(() => {
        console.log(count.value)
      })

      return {
        count,
      }
    },
  }
</script>

在這個(gè)例子中:

  • count 會(huì)在初始運(yùn)行時(shí)同步打印出來(lái)
  • 更改 count 時(shí)河哑,將在組件更新后執(zhí)行副作用避诽。

請(qǐng)注意,初始化運(yùn)行是在組件 mounted 之前執(zhí)行的璃谨。因此沙庐,如果你希望在編寫(xiě)副作用函數(shù)時(shí)訪問(wèn) DOM(或模板 ref)鲤妥,請(qǐng)?jiān)?onMounted 鉤子中進(jìn)行:

onMounted(() => {
  watchEffect(() => {
    // 在這里可以訪問(wèn)到 DOM 或者 template refs
  })
})

如果副作用需要同步或在組件更新之前重新運(yùn)行,我們可以傳遞一個(gè)擁有 flush 屬性的對(duì)象作為選項(xiàng)(默認(rèn)為 'post'):

// 同步運(yùn)行
watchEffect(
  () => {
    /* ... */
  },
  {
    flush: 'sync',
  }
)

// 組件更新前執(zhí)行
watchEffect(
  () => {
    /* ... */
  },
  {
    flush: 'pre',
  }
)

  1. 偵聽(tīng)器調(diào)試

onTrackonTrigger 選項(xiàng)可用于調(diào)試一個(gè)偵聽(tīng)器的行為拱雏。

  • 當(dāng)一個(gè) reactive 對(duì)象屬性或一個(gè) ref 作為依賴被追蹤時(shí)棉安,將調(diào)用 onTrack

  • 依賴項(xiàng)變更導(dǎo)致副作用被觸發(fā)時(shí),將調(diào)用 onTrigger

這兩個(gè)回調(diào)都將接收到一個(gè)包含有關(guān)所依賴項(xiàng)信息的調(diào)試器事件古涧。建議在以下回調(diào)中編寫(xiě) debugger 語(yǔ)句來(lái)檢查依賴關(guān)系:

watchEffect(
  () => {
    /* 副作用的內(nèi)容 */
  },
  {
    onTrigger(e) {
      debugger
    },
  }
)

onTrackonTrigger 僅在開(kāi)發(fā)模式下生效垂券。

  • 類(lèi)型定義

    function watchEffect(
      effect: (onInvalidate: InvalidateCbRegistrator) => void,
      options?: WatchEffectOptions
    ): StopHandle
    
    interface WatchEffectOptions {
      flush?: 'pre' | 'post' | 'sync'
      onTrack?: (event: DebuggerEvent) => void
      onTrigger?: (event: DebuggerEvent) => void
    }
    
    interface DebuggerEvent {
      effect: ReactiveEffect
      target: any
      type: OperationTypes
      key: string | symbol | undefined
    }
    
    type InvalidateCbRegistrator = (invalidate: () => void) => void
    
    type StopHandle = () => void
    
    

6. watch

watch API 完全等效于 2.x this.$watch (以及 watch 中相應(yīng)的選項(xiàng))。watch 需要偵聽(tīng)特定的數(shù)據(jù)源羡滑,并在回調(diào)函數(shù)中執(zhí)行副作用。默認(rèn)情況是懶執(zhí)行的算芯,也就是說(shuō)僅在偵聽(tīng)的源變更時(shí)才執(zhí)行回調(diào)柒昏。

  • 對(duì)比 watchEffectwatch 允許我們:

    • 懶執(zhí)行副作用熙揍;
    • 更明確哪些狀態(tài)的改變會(huì)觸發(fā)偵聽(tīng)器重新運(yùn)行副作用职祷;
    • 訪問(wèn)偵聽(tīng)狀態(tài)變化前后的值。
  • 偵聽(tīng)單個(gè)數(shù)據(jù)源

    偵聽(tīng)器的數(shù)據(jù)源可以是一個(gè)擁有返回值的 getter 函數(shù)届囚,也可以是 ref:

    // 偵聽(tīng)一個(gè) getter
    const state = reactive({ count: 0 })
    watch(
      () => state.count,
      (count, prevCount) => {
        /* ... */
      }
    )
    
    // 直接偵聽(tīng)一個(gè) ref
    const count = ref(0)
    watch(count, (count, prevCount) => {
      /* ... */
    })
    
    
  • 偵聽(tīng)多個(gè)數(shù)據(jù)源

    watcher 也可以使用數(shù)組來(lái)同時(shí)偵聽(tīng)多個(gè)源:

    watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
      /* ... */
    })
    
    
  • watchEffect 共享的行為

    watch 和 watchEffect 在停止偵聽(tīng), 清除副作用 (相應(yīng)地 onInvalidate 會(huì)作為回調(diào)的第三個(gè)參數(shù)傳入)有梆,副作用刷新時(shí)機(jī)偵聽(tīng)器調(diào)試 等方面行為一致.

  • 類(lèi)型定義

    // 偵聽(tīng)單數(shù)據(jù)源
    function watch<T>(
      source: WatcherSource<T>,
      callback: (
        value: T,
        oldValue: T,
        onInvalidate: InvalidateCbRegistrator
      ) => void,
      options?: WatchOptions
    ): StopHandle
    
    // 偵聽(tīng)多數(shù)據(jù)源
    function watch<T extends WatcherSource<unknown>[]>(
      sources: T
      callback: (
        values: MapSources<T>,
        oldValues: MapSources<T>,
        onInvalidate: InvalidateCbRegistrator
      ) => void,
      options? : WatchOptions
    ): StopHandle
    
    type WatcherSource<T> = Ref<T> | (() => T)
    
    type MapSources<T> = {
      [K in keyof T]: T[K] extends WatcherSource<infer V> ? V : never
    }
    
    // 共有的屬性 請(qǐng)查看 `watchEffect` 的類(lèi)型定義
    interface WatchOptions extends WatchEffectOptions {
      immediate?: boolean // default: false
      deep?: boolean
    }
    
    

#生命周期鉤子函數(shù)

可以直接導(dǎo)入 onXXX 一族的函數(shù)來(lái)注冊(cè)生命周期鉤子:

未完待續(xù)。意系。泥耀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蛔添,隨后出現(xiàn)的幾起案子痰催,更是在濱河造成了極大的恐慌,老刑警劉巖迎瞧,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夸溶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡凶硅,警方通過(guò)查閱死者的電腦和手機(jī)缝裁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)足绅,“玉大人捷绑,你說(shuō)我怎么就攤上這事”嗉欤” “怎么了胎食?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)允懂。 經(jīng)常有香客問(wèn)我厕怜,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任粥航,我火速辦了婚禮琅捏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘递雀。我一直安慰自己柄延,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布缀程。 她就那樣靜靜地躺著搜吧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪杨凑。 梳的紋絲不亂的頭發(fā)上滤奈,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音撩满,去河邊找鬼蜒程。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伺帘,可吹牛的內(nèi)容都是我干的昭躺。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼伪嫁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼领炫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起礼殊,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤驹吮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后晶伦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體碟狞,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年婚陪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了族沃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泌参,死狀恐怖脆淹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情沽一,我是刑警寧澤盖溺,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站铣缠,受9級(jí)特大地震影響烘嘱,放射性物質(zhì)發(fā)生泄漏昆禽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一蝇庭、第九天 我趴在偏房一處隱蔽的房頂上張望醉鳖。 院中可真熱鬧,春花似錦哮内、人聲如沸盗棵。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)纹因。三九已至,卻和暖如春琳拨,著一層夾襖步出監(jiān)牢的瞬間辐怕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工从绘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人是牢。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓僵井,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親驳棱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子批什,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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