Vue3之script-setup全面解析

可能很多同學(xué)(包括我)剛上手 Vue 3.0 之后迂猴,都會覺得開發(fā)過程似乎變得更繁瑣了,Vue 官方團(tuán)隊(duì)當(dāng)然不會無視群眾的呼聲,如果你基于腳手架和 .vue 文件開發(fā)躺屁,那么可以享受到更高效率的開發(fā)體驗(yàn)。

在閱讀這篇文章之前经宏,需要對 Vue 3.0 的單組件有一定的了解犀暑,如果還處于完全沒有接觸過的階段,請先抽點(diǎn)時間閱讀 單組件的編寫 一章烁兰。

WARNING
本章節(jié)的部分方案屬于實(shí)驗(yàn)性方案耐亏,或者是剛進(jìn)入定稿階段,所以在官網(wǎng)文檔上還暫時看不到使用說明沪斟,期間可能還會有一些功能調(diào)整和 BUG 修復(fù)广辰,請留意版本號說明。

所以要體驗(yàn)以下新特性币喧,請確保項(xiàng)目下 package.json 里的 vue (opens new window)@vue/compiler-sfc (opens new window)都在 v3.1.4 版本以上轨域,最好同步 NPM 上當(dāng)前最新的 @next 版本,否則在編譯過程中可能出現(xiàn)一些奇怪的問題(這兩個依賴必須保持同樣的版本號)杀餐。

#script-setup

這是一個比較有爭議的新特性干发,作為 setup 函數(shù)的語法糖,褒貶不一史翘,不過經(jīng)歷了幾次迭代之后枉长,目前在體驗(yàn)上來說,感受還是非常棒的琼讽。

TIP
截止至 2021-07-16 必峰,<script setup> 方案已在 Vue 3.2.0-beta.1 版本中脫離實(shí)驗(yàn)狀態(tài),正式進(jìn)入 Vue 3.0 的隊(duì)伍钻蹬,在新的版本中已經(jīng)可以作為一個官方標(biāo)準(zhǔn)的開發(fā)方案使用(但初期仍需注意與開源社區(qū)的項(xiàng)目兼容性問題吼蚁,特別是 UI 框架)。

另外问欠,Vue 的 3.1.2 版本是針對 script-setup 的一個分水嶺版本肝匆,自 3.1.4 開始 script-setup 進(jìn)入定稿狀態(tài),部分舊的 API 已被舍棄顺献,本章節(jié)內(nèi)容將以最新的 API 為準(zhǔn)進(jìn)行整理說明旗国,如果您需要查閱舊版 API 的使用,請參閱 這里 (opens new window)注整。

#新特性的產(chǎn)生背景

在了解它怎么用之前能曾,可以先了解一下它被推出的一些背景度硝,可以幫助你對比開發(fā)體驗(yàn)上的異同點(diǎn),以及了解為什么會有這一章節(jié)里面的新東西寿冕。

在 Vue 3.0 的 .vue 組件里蕊程,遵循 SFC 規(guī)范要求(注:SFC,即 Single-File Component蚂斤,.vue 單組件)存捺,標(biāo)準(zhǔn)的 setup 用法是,在 setup 里面定義的數(shù)據(jù)如果需要在 template 使用曙蒸,都需要 return 出來捌治。

如果你使用的是 TypeScript ,還需要借助 defineComponent 來幫助你對類型的自動推導(dǎo)纽窟。

<!-- 標(biāo)準(zhǔn)組件格式 -->
<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  setup () {
    // ...

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

關(guān)于標(biāo)準(zhǔn) setup 和 defineComponent 的說明和用法肖油,可以查閱 全新的 setup 函數(shù) 一節(jié)。

script-setup 的推出是為了讓熟悉 3.0 的用戶可以更高效率的開發(fā)組件臂港,減少一些心智負(fù)擔(dān)森枪,只需要給 script 標(biāo)簽添加一個 setup 屬性,那么整個 script 就直接會變成 setup 函數(shù)审孽,所有頂級變量县袱、函數(shù),均會自動暴露給模板使用(無需再一個個 return 了)佑力。

Vue 會通過單組件編譯器式散,在編譯的時候?qū)⑵涮幚砘貥?biāo)準(zhǔn)組件,所以目前這個方案只適合用 .vue 文件寫的工程化項(xiàng)目打颤。

<!-- 使用 script-setup 格式 -->
<script setup lang="ts">
  // ...
</script>

對建芙,就是這樣档悠,代碼量瞬間大幅度減少……

TIP
因?yàn)?script-setup 的大部分功能在書寫上和標(biāo)準(zhǔn)版是一致的藏姐,這里只提及一些差異化的表現(xiàn)厅篓。

#全局編譯器宏

在 script-setup 模式下,新增了 4 個全局編譯器宏透且,他們無需 import 就可以直接使用撕蔼。

但是默認(rèn)的情況下直接使用,項(xiàng)目的 eslint 會提示你沒有導(dǎo)入秽誊,但你導(dǎo)入后罕邀,控制臺的 Vue 編譯助手又會提示你不需要導(dǎo)入,就很尷尬…

哈哈哈哈不過不用著急养距,可以配置一下 lint ,把這幾個編譯助手寫進(jìn)全局規(guī)則里日熬,就可以了棍厌,不需要導(dǎo)入也不會報(bào)錯了。

// 項(xiàng)目根目錄下的 .eslintrc.js
module.exports = {
  // 原來的lint規(guī)則,補(bǔ)充下面的globals...
  globals: {
    defineProps: 'readonly',
    defineEmits: 'readonly',
    defineExpose: 'readonly',
    withDefaults: 'readonly',
  },
}

關(guān)于幾個宏的說明都在下面的文檔部分有說明耘纱,你也可以從這里導(dǎo)航過去直接查看敬肚。

說明
defineProps 點(diǎn)擊查看
defineEmits 點(diǎn)擊查看
defineExpose 點(diǎn)擊查看
withDefaults 點(diǎn)擊查看

下面我們繼續(xù)了解 script-setup 的變化。

#template 操作簡化

如果使用 JSX / TSX 寫法束析,這一點(diǎn)沒有太大影響艳馒,但對于習(xí)慣使用 <template /> 的開發(fā)者來說,這是一個非常爽的體驗(yàn)员寇。

主要體現(xiàn)在這兩點(diǎn):

#變量無需進(jìn)行 return

標(biāo)準(zhǔn)組件模式下弄慰,setup 里定義的變量,需要 return 后蝶锋,在 template 部分才可以正確拿到:

<!-- 標(biāo)準(zhǔn)組件格式 -->
<template>
  <p>{{ msg }}</p>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  setup () {
    const msg: string = 'Hello World!';
    
    // 要給 template 用的數(shù)據(jù)需要 return 出來才可以
    return {
      msg
    }
  }
})
</script>

在 script-setup 模式下陆爽,你定義了就可以直接使用。

<!-- 使用 script-setup 格式 -->
<template>
  <p>{{ msg }}</p>
</template>

<script setup lang="ts">
const msg: string = 'Hello World!';
</script>

#子組件無需手動注冊

子組件的掛載扳缕,在標(biāo)準(zhǔn)組件里的寫法是需要 import 后再放到 components 里才能夠啟用:

<!-- 標(biāo)準(zhǔn)組件格式 -->
<template>
  <Child />
</template>

<script lang="ts">
import { defineComponent } from 'vue'

// 導(dǎo)入子組件
import Child from '@cp/Child.vue'

export default defineComponent({
  // 需要啟用子組件作為模板
  components: {
    Child
  },

  // 組件里的業(yè)務(wù)代碼
  setup () {
    // ...
  }
})
</script>

在 script-setup 模式下慌闭,只需要導(dǎo)入組件即可,編譯器會自動識別并啟用躯舔。

<!-- 使用 script-setup 格式 -->
<template>
  <Child />
</template>

<script setup lang="ts">
import Child from '@cp/Child.vue'
</script>

#props 的接收方式變化

由于整個 script 都變成了一個大的 setup function 驴剔,沒有了組件選項(xiàng),也沒有了 setup 入?yún)⒅嘧詻]辦法和標(biāo)準(zhǔn)寫法一樣去接收 props 了丧失。

這里需要使用一個全新的 API :defineProps

defineProps 是一個方法飒赃,內(nèi)部返回一個對象利花,也就是掛載到這個組件上的所有 props ,它和普通的 props 用法一樣载佳,如果不指定為 prop炒事, 則傳下來的屬性會被放到 attrs 那邊去。

TIP
前置知識點(diǎn):接收 props - 組件之間的通信蔫慧。

#defineProps 的基礎(chǔ)用法

所以挠乳,如果只是單純在 template 里使用,那么其實(shí)就這么簡單定義就可以了:

defineProps([
  'name',
  'userInfo',
  'tags'
])

使用 string[] 數(shù)組作為入?yún)⒐枚悖?prop 的名稱作為數(shù)組的 item 傳給 defineProps 就可以了睡扬。

如果 script 里的方法要拿到 props 的值,你也可以使用字面量定義:

const props = defineProps([
  'name',
  'userInfo',
  'tags'
])

console.log(props.name);

但在作為一個 Vue 老玩家黍析,都清楚不顯性的指定 prop 類型的話卖怜,很容易在協(xié)作中引起程序報(bào)錯,那么應(yīng)該如何對每個 prop 進(jìn)行類型檢查呢阐枣?

有兩種方式來處理類型定義马靠。

#通過構(gòu)造函數(shù)檢查 prop

這是第一種方式:使用 JavaScript 原生構(gòu)造函數(shù)進(jìn)行類型規(guī)定奄抽。

也就是跟我們平時定義 prop 類型時一樣, Vue 會通過 instanceof 來進(jìn)行 類型檢查 (opens new window)甩鳄。

使用這種方法逞度,需要通過一個 “對象” 入?yún)韨鬟f給 defineProps ,比如:

defineProps({
  name: String,
  userInfo: Object,
  tags: Array
});

所有原來 props 具備的校驗(yàn)機(jī)制妙啃,都可以適用档泽,比如你除了要限制類型外,還想指定 name 是可選揖赴,并且?guī)в幸粋€默認(rèn)值:

defineProps({
  name: {
    type: String,
    required: false,
    default: 'Petter'
  },
  userInfo: Object,
  tags: Array
});

更多的 props 校驗(yàn)機(jī)制馆匿,可以點(diǎn)擊 帶有類型限制的 props可選以及帶有默認(rèn)值的 props 了解更多。

#使用類型注解檢查 prop

這是第二種方式:使用 TypeScript 的類型注解储笑。

和 ref 等 API 的用法一樣甜熔,defineProps 也是可以使用尖括號 <> 來包裹類型定義,緊跟在 API 后面突倍,另外腔稀,由于 defineProps 返回的是一個對象(因?yàn)?props 本身是一個對象),所以尖括號里面的類型還要用大括號包裹羽历,通過 key: value 的鍵值對形式表示焊虏,如:

defineProps<{ name: string }>();

注意到了嗎?這里使用的類型秕磷,和第一種方法提到的指定類型時是不一樣的诵闭。

TIP
在這里,不再使用構(gòu)造函數(shù)校驗(yàn)澎嚣,而是需要遵循使用 TypeScript 的類型疏尿。

比如字符串是 string,而不是 String 易桃。

如果有多個 prop 褥琐,就跟寫 interface 一樣:

defineProps<{
  name: string;
  phoneNumber: number;
  userInfo: object;
  tags: string[];
}>();

其中,舉例里的 userInfo 是一個對象晤郑,你可以簡單的指定為 object敌呈,也可以先定義好它對應(yīng)的類型,再進(jìn)行指定:

interface UserInfo {
  id: number;
  age: number;
}

defineProps<{
  name: string;
  userInfo: UserInfo;
}>();

如果你想對某個數(shù)據(jù)設(shè)置為可選造寝,也是遵循 TS 規(guī)范磕洪,通過英文問號 ? 來允許可選:

// name 是可選
defineProps<{
  name?: string;
  tags: string[];
}>();

如果你想設(shè)置可選參數(shù)的默認(rèn)值,需要借助 withDefaults API诫龙。

WARNING
需要強(qiáng)調(diào)的一點(diǎn)是:在 構(gòu)造函數(shù)類型注解 這兩種校驗(yàn)方式只能二選一析显,不能同時使用,否則會引起程序報(bào)錯

#withDefaults 的基礎(chǔ)用法

這個新的 withDefaults API 可以讓你在使用 TS 類型系統(tǒng)時签赃,也可以指定 props 的默認(rèn)值叫榕。

它接收兩個入?yún)ⅲ?/p>

參數(shù) 類型 含義
props object 通過 defineProps 傳入的 props
defaultValues object 根據(jù) props 的 key 傳入默認(rèn)值

可能缺乏一些官方描述浑侥,還是看參考用法可能更直觀:

withDefaults(defineProps<{
  size?: number
  labels?: string[]
}>(), {
  size: 3,
  labels: () => ['default label']
})

如果你要在 TS / JS 再對 props 進(jìn)行獲取,也可以通過字面量來拿到這些默認(rèn)值:

// 如果不習(xí)慣上面的寫法晰绎,你也可以跟平時一樣先通過interface定義一個類型接口
interface Props {
  msg?: string
}

// 再作為入?yún)魅?const props = withDefaults(defineProps<Props>(), {
  msg: 'hello'
})

// 這樣就可以通過props變量拿到需要的prop值了
console.log(props.msg)

#emits 的接收方式變化

和 props 一樣,emits 的接收也是需要使用一個全新的 API 來操作括丁,這個 API 就是 defineEmits 荞下。

defineProps 一樣, defineEmits 也是一個方法史飞,它接受的入?yún)⒏袷胶蜆?biāo)準(zhǔn)組件的要求是一致的尖昏。

TIP
注意:從 3.1.3 版本開始,該 API 已被改名构资,加上了復(fù)數(shù)結(jié)尾抽诉,帶有 s,在此版本之前是沒有 s 結(jié)尾吐绵!

前置知識點(diǎn):接收 emits - 組件之間的通信迹淌。

#defineEmits 的基礎(chǔ)用法

由于 emit 并非提供給模板直接讀取,所以需要通過字面量來定義 emits己单。

最基礎(chǔ)的用法也是傳遞一個 string[] 數(shù)組進(jìn)來唉窃,把每個 emit 的名稱作為數(shù)組的 item 。

// 獲取 emit
const emit = defineEmits(['chang-name']);

// 調(diào)用 emit
emit('chang-name', 'Tom');

由于 defineEmits 的用法和原來的 emits 選項(xiàng)差別不大纹笼,這里也不重復(fù)說明更多的諸如校驗(yàn)之類的用法了纹份,可以查看 接收 emits 一節(jié)了解更多。

#attrs 的接收方式變化

attrsprops 很相似廷痘,也是基于父子通信的數(shù)據(jù)蔓涧,如果父組件綁定下來的數(shù)據(jù)沒有被指定為 props ,那么就會被掛到 attrs 這邊來笋额。

在標(biāo)準(zhǔn)組件里元暴, attrs 的數(shù)據(jù)是通過 setup 的第二個入?yún)?context 里的 attrs API 獲取的。

// 標(biāo)準(zhǔn)組件的寫法
export default defineComponent({
  setup (props, { attrs }) {
    // attrs 是個對象鳞陨,每個 Attribute 都是它的 key
    console.log(attrs.class);

    // 如果傳下來的 Attribute 帶有短橫線昨寞,需要通過這種方式獲取
    console.log(attrs['data-hash']);
  }
})

但和 props 一樣,由于沒有了 context 參數(shù)厦滤,需要使用一個新的 API 來拿到 attrs 數(shù)據(jù)援岩。

這個 API 就是 useAttrs

TIP
請注意掏导,useAttrs API 需要 Vue 3.1.4 或更高版本才可以使用享怀。

#useAttrs 的基礎(chǔ)用法

顧名思義, useAttrs 可以是用來獲取 attrs 數(shù)據(jù)的趟咆,它的用法非常簡單:

// 導(dǎo)入 useAttrs 組件
import { useAttrs } from 'vue'

// 獲取 attrs
const attrs = useAttrs()

// attrs是個對象添瓷,和 props 一樣梅屉,需要通過 key 來得到對應(yīng)的單個 attr
console.log(attrs.msg);

attrs 不太了解的話,可以查閱 獲取非 Prop 的 Attribute

#slots 的接收方式變化

slots 是 Vue 組件的插槽數(shù)據(jù)鳞贷,也是在父子通信里的一個重要成員坯汤。

對于使用 template 的開發(fā)者來說,在 script-setup 里獲取插槽數(shù)據(jù)并不困難搀愧,因?yàn)楦鷺?biāo)準(zhǔn)組件的寫法是完全一樣的惰聂,可以直接在 template 里使用 <slot /> 標(biāo)簽渲染。

<template>
  <div>
    <!-- 插槽數(shù)據(jù) -->
    <slot />
    <!-- 插槽數(shù)據(jù) -->
  </div>
</template>

但對使用 JSX / TSX 的開發(fā)者來說咱筛,就影響比較大了搓幌,在標(biāo)準(zhǔn)組件里,想在 script 里獲取插槽數(shù)據(jù)迅箩,也是需要在 setup 的第二個入?yún)⒗锬玫?slots API 溉愁。

// 標(biāo)準(zhǔn)組件的寫法
export default defineComponent({
  // 這里的 slots 就是插槽
  setup (props, { slots }) {
    // ...
  }
})

新版本的 Vue 也提供了一個全新的 useSlots API 來幫助 script-setup 用戶獲取插槽。

TIP
請注意饲趋,useSlots API 需要 Vue 3.1.4 或更高版本才可以使用拐揭。

#useSlots 的基礎(chǔ)用法

先來看看父組件,父組件先為子組件傳入插槽數(shù)據(jù)篙贸,支持 “默認(rèn)插槽” 和 “命名插槽” :

<template>
  <!-- 子組件 -->
  <ChildTSX>
    <!-- 默認(rèn)插槽 -->
    <p>I am a default slot from TSX.</p>
    <!-- 默認(rèn)插槽 -->

    <!-- 命名插槽 -->
    <template #msg>
      <p>I am a msg slot from TSX.</p>
    </template>
    <!-- 命名插槽 -->
  </ChildTSX>
  <!-- 子組件 -->
</template>

<script setup lang="ts">
import ChildTSX from '@cp/context/Child.tsx'
</script>

在使用 JSX / TSX 編寫的子組件里投队,就可以通過 useSlots 來獲取父組件傳進(jìn)來的 slots 數(shù)據(jù)進(jìn)行渲染:

// 注意:這是一個 .tsx 文件
import { defineComponent, useSlots } from 'vue'

const ChildTSX = defineComponent({
  setup() {
    // 獲取插槽數(shù)據(jù)
    const slots = useSlots()

    // 渲染組件
    return () => (
      <div>
        {/* 渲染默認(rèn)插槽 */}
        <p>{ slots.default ? slots.default() : '' }</p>

        {/* 渲染命名插槽 */}
        <p>{ slots.msg ? slots.msg() : '' }</p>
      </div>
    )
  },
})

export default ChildTSX

#ref 的通信方式變化

在標(biāo)準(zhǔn)組件寫法里,子組件的數(shù)據(jù)都是默認(rèn)隱式暴露給父組件的爵川,也就是父組件可以通過 childComponent.value.foo 這樣的方式直接操作子組件的數(shù)據(jù)(參見:DOM 元素與子組件 - 響應(yīng)式 API 之 ref)敷鸦。

但在 script-setup 模式下,所有數(shù)據(jù)只是默認(rèn)隱式 return 給 template 使用寝贡,不會暴露到組件外扒披,所以父組件是無法直接通過掛載 ref 變量獲取子組件的數(shù)據(jù)。

在 script-setup 模式下圃泡,如果要調(diào)用子組件的數(shù)據(jù)碟案,需要先在子組件顯示的暴露出來,才能夠正確的拿到颇蜡,這個操作价说,就是由 defineExpose 來完成。

#defineExpose 的基礎(chǔ)用法

defineExpose 的用法非常簡單风秤,它本身是一個函數(shù)鳖目,可以接受一個對象參數(shù)。

在子組件里缤弦,像這樣把需要暴露出去的數(shù)據(jù)通過 key: value 的形式作為入?yún)ⅲㄏ旅娴睦邮怯玫搅?ES6 的 屬性的簡潔表示法 (opens new window)):

<script setup lang="ts">
// 定義一個想提供給父組件拿到的數(shù)據(jù)
const msg: string = 'Hello World!';

// 顯示暴露的數(shù)據(jù)领迈,才可以在父組件拿到
defineExpose({
  msg
});
</script>

然后你在父組件就可以通過掛載在子組件上的 ref 變量,去拿到暴露出來的數(shù)據(jù)了。

#頂級 await 的支持

在 script-setup 模式下狸捅,不必再配合 async 就可以直接使用 await 了衷蜓,這種情況下,組件的 setup 會自動變成 async setup 尘喝。

<script setup lang="ts">
const post = await fetch(`/api/post/1`).then((r) => r.json())
</script>

它轉(zhuǎn)換成標(biāo)準(zhǔn)組件的寫法就是:

<script lang="ts">
import { defineComponent, withAsyncContext } from 'vue'

export default defineComponent({
  async setup() {
    const post = await withAsyncContext(
      fetch(`/api/post/1`).then((r) => r.json())
    )

    return {
      post
    }
  }
})
</script>

點(diǎn)贊加關(guān)注磁浇,永遠(yuǎn)不迷路
每天一更新,創(chuàng)作拿命拼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞧省,一起剝皮案震驚了整個濱河市扯夭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鞍匾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骑科,死亡現(xiàn)場離奇詭異橡淑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)咆爽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門梁棠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人斗埂,你說我怎么就攤上這事符糊。” “怎么了呛凶?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵男娄,是天一觀的道長。 經(jīng)常有香客問我漾稀,道長模闲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任崭捍,我火速辦了婚禮尸折,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘殷蛇。我一直安慰自己实夹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布粒梦。 她就那樣靜靜地躺著亮航,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谍倦。 梳的紋絲不亂的頭發(fā)上塞赂,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音昼蛀,去河邊找鬼宴猾。 笑死圆存,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仇哆。 我是一名探鬼主播沦辙,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼讹剔!你這毒婦竟也來了油讯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤延欠,失蹤者是張志新(化名)和其女友劉穎陌兑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體由捎,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兔综,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了狞玛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片软驰。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖心肪,靈堂內(nèi)的尸體忽然破棺而出锭亏,到底是詐尸還是另有隱情,我是刑警寧澤硬鞍,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布慧瘤,位于F島的核電站,受9級特大地震影響膳凝,放射性物質(zhì)發(fā)生泄漏碑隆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一蹬音、第九天 我趴在偏房一處隱蔽的房頂上張望上煤。 院中可真熱鬧,春花似錦著淆、人聲如沸劫狠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽独泞。三九已至,卻和暖如春苔埋,著一層夾襖步出監(jiān)牢的瞬間懦砂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荞膘,地道東北人罚随。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像羽资,于是被迫代替她去往敵國和親淘菩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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