Vue3.0新特性以及使用經(jīng)驗(yàn)總結(jié)

寫在最前:本文轉(zhuǎn)自掘金

Composition API

Composition API 主要解決了高蜂,將零散分布的邏輯組合在一起來維護(hù)事秀,并且還可以將單獨(dú)的功能邏輯拆分成單獨(dú)的文件。


watermark3.jpg

setup

setup 是 Vue3.x新增的一個(gè)選項(xiàng)山宾,他是組件內(nèi)使用 Compsition API的入口扎阶。

setup 執(zhí)行時(shí)機(jī)

setup 執(zhí)行時(shí)機(jī)是在 beforeCreate 之前執(zhí)行

setup 參數(shù)

setup接收兩個(gè)參數(shù):

  1. props: 組件傳入的屬性
  2. context

setup 中接收的props是響應(yīng)式的揩晴,當(dāng)傳入的新的props時(shí)筐钟,會及時(shí)被更新。由于是響應(yīng)式的疹鳄,所以不可以使用ES6結(jié)構(gòu)拧略,結(jié)構(gòu)會消除它的響應(yīng)式。

// 錯(cuò)誤代碼示例瘪弓,這代代碼會讓props不再支持響應(yīng)式
export default defineComponent({
  setup(props, context){
    const {name} = props
    console.log(name)
  },
})

toRefs學(xué)習(xí)的地方為大家解答垫蛆。接下來我們來說一下setup接受的第二個(gè)參數(shù)context,我們前面說了setup中不能訪問Vue2中最常用的this對象,所以context中提供了this中最常用的是三個(gè)屬性:attrs月褥、slot弛随、emit,分別對應(yīng)Vue2.x中的$attr屬性宁赤、slot插槽和$emit觸發(fā)事件。并且這幾個(gè)屬性都是自動(dòng)同步最新的值栓票,所以我們每次使用拿到的都是最新的值决左。

reactive、 ref 與toRefs

在Vue3.x中走贪,定義數(shù)據(jù)可以使用reactiveref來進(jìn)行數(shù)據(jù)定義佛猛。那么refreactive他們有什么區(qū)別呢?分別什么時(shí)候使用呢坠狡?ref可以處理js基礎(chǔ)類型的雙向綁定继找,也可以定義對象類型雙向綁定。但是reactive函數(shù)只能代理對象類型逃沿。

watermark4.jpg

我們在模板中使用user.name,user.age這樣寫感覺很繁瑣婴渡,如果需要解構(gòu)出來,就需要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>

生命周期鉤子

我們可以直接看生命周期圖來認(rèn)識有哪些生命周期鉤子


watermark5.jpg

從圖中我們可以看到Vue3.0新增了setup,然后是將Vue2.x中的beforeDestroy名稱變更為beforeUnmount假消;destroyed名稱變更為unmounted柠并。其它Vue2中的生命周期仍然保留。上邊生命周期圖并沒有包含全部的生命周期鉤子富拗,還有其它幾個(gè)臼予,全部聲明周期鉤子如下圖所示:

watermark6.jpg

我們可以看到beforeCreatecreatedsetup替換了。其次啃沪,鉤子函數(shù)都增加了on前綴粘拾;Vue3.x還新增了用于調(diào)試的鉤子函數(shù)onRenderTriggeredonRenderTricked下面我們就簡單使用幾個(gè)鉤子,方便大家學(xué)習(xí)如何使用谅阿,Vue3.x中的鉤子函數(shù)是需要從vue中導(dǎo)入的

import {defineComponent, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmout, onUnmounted, onErrorCaptured, onRenderTracked, onRenderTriggered} from 'vue';
export default defineComponent({
  beforeCreate(){
    console.log("beforeCreated")
  },
  created(){
    console.log("created")
  },
  setup(){
    console.log("setup");
    // vue3.x生命周期寫在setup中
    onBeforeMount(()=>{
      console.log("onBeforeMount")
    });
    onMounted(()=>{
      console.log("onMounted")
    });
    // 調(diào)試哪些數(shù)據(jù)發(fā)生了變化
    onRenderTriggered((event)=>{
      console.log("onRenderTriggered", event)
    });
  }
})

watch 與 watchEffect 的用法

watch函數(shù)用來偵聽特定的數(shù)據(jù)源半哟,并在回調(diào)函數(shù)中執(zhí)行邏輯。默認(rèn)情況是惰性的签餐,也就是說僅在偵聽的源數(shù)據(jù)變更時(shí)才執(zhí)行回調(diào)寓涨。

watch(source, callback, [options])

參數(shù)說明

  • source: 可以支持string, Object, Function, Array;用于指定要偵聽的響應(yīng)式變量
  • callback: 執(zhí)行的回調(diào)函數(shù)
  • options: 支持deep, immediate 和 flush 選項(xiàng)

偵聽reactive定義的數(shù)據(jù)

import {defineComponent, ref, reactive, toRefs, watch} from 'vue';
export default defineComponent({
  setup(){
    const state = reactive({nickname: "xiaofan", age: 20});

    setTimeout(()=>{
      state.age++;
    }, 1000);
  
    // 修改age值時(shí)會觸發(fā)watch的回調(diào)
    watch(()=> state.age, (curAge, preAge)=>{console.log(curAge, preAge)});
    
    return {
      ...toRefs(state),
    }
  }
})

偵聽ref定義的數(shù)據(jù)

const year = ref(0);
 
setTimeout(()=>{
  year.value++;
}, 1000);

watch(year, (newVal, oldVal)=>{
  console.log("新值", newVal, "老值", oldVal);
})

偵聽多個(gè)數(shù)據(jù)

   watch([()=>test.age,year],([curAge,newVal],[preAge, oldVal])=>{console.log(curAge,preAge);console.log(newVal,oldVal)})

偵聽復(fù)雜的嵌套對象

const state = reactive({
  room: {
    id: 100,
    attrs: {
      size: "140平方米",
      type: "三室兩廳",
    },
  },
});
watch(
  () => state.room,
  (newType, oldType) => {
    console.log("新值:", newType, "老值:", oldType);
  },
  { deep: true }
);

如果不適用第三個(gè)參數(shù)deep:true,是無法監(jiān)聽到數(shù)據(jù)變化的氯檐。前面我們提到戒良,默認(rèn)情況下,watch是惰性的冠摄,那什么情況下不是惰性的糯崎,可以立即執(zhí)行回調(diào)函數(shù)呢几缭?給第三個(gè)參數(shù)中設(shè)置 immediate:true即可。關(guān)于flush配置沃呢,還在學(xué)習(xí)年栓,后期補(bǔ)充。

stop停止監(jiān)聽
我們在組件中創(chuàng)建的watch監(jiān)聽薄霜,會在組件被銷毀時(shí)自動(dòng)停止某抓。如果在組件銷毀之前我們想要停止掉某個(gè)監(jiān)聽,可以調(diào)用watch()函數(shù)的返回值惰瓜,操作如下:

const stopWatchRoom = watch(() => state.room, (newType, oldType) => {
    console.log("新值:", newType, "老值:", oldType);
}, {deep:true});

setTimeout(()=>{
    // 停止監(jiān)聽
    stopWatchRoom()
}, 3000)

watchEffect 的用法

import {defineComponent, ref, reactive, toRefs, watchEffect} from 'vue';
export default defineComponent({
  setup() {
    const state = reactive({nickname:"xiaofan", age: 20});
    let year = ref(0);

    setInterval(()=>{
      state.age++
      year.value++
    },1000)
    
    watchEffect(()=>{
      console.log(state);
      console.log(year);
    });
    return {...toRefs(state)}
  },
})

執(zhí)行結(jié)果首先打印一次stateyear值否副;然后每隔一秒,打印stateyear值崎坊。
從上面的代碼可以看出备禀, 并沒有像watch一樣需要先傳入依賴,watchEffect會自動(dòng)收集依賴, 只要指定一個(gè)回調(diào)函數(shù)奈揍。在組件初始化時(shí)曲尸, 會先執(zhí)行一次來收集依賴, 然后當(dāng)收集到的依賴中數(shù)據(jù)發(fā)生變化時(shí)打月, 就會再次執(zhí)行回調(diào)函數(shù)队腐。所以總結(jié)對比如下:

  1. watchEffect 不需要手動(dòng)傳入依賴
  2. watchEffect 會先執(zhí)行一次用來自動(dòng)收集依賴
  3. watchEffect 無法獲取到變化前的值, 只能獲取變化后的值

computed 計(jì)算屬性

setup() {
    let name = ref('xiaofan')
    let age = ref(21)
    
    //計(jì)算屬性
    let getInfo = computed(() => {
        return `我的名字:${name.value},今年${age.value}奏篙,請多多指教`
    })
    return {
        name,
        age,
        getInfo,
    }
}

自定義 Hooks

我們來寫了一個(gè)實(shí)現(xiàn)加減的例子柴淘,這里將其封裝成hook,我們約定這些[自定義的hook]以use作為前綴秘通,和普通的函數(shù)加以區(qū)分为严。useCount.ts實(shí)現(xiàn):

import { ref, Ref, computed } from 'vue'

interface 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

<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>

teleport

Teleport 是什么呢?
Teleport就像是哆啦 A 夢中的「任意門」肺稀,任意門的作用就是可以將人瞬間傳送到另一個(gè)地方第股。有了這個(gè)認(rèn)識,我們再來看一下為什么需要用到 Teleport 的特性呢话原,看一個(gè)小例子:
在子組件Header中使用到Dialog組件夕吻,我們實(shí)際開發(fā)中經(jīng)常會在類似的情形下使用到 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的使用方式

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組件, 這里主要演示 Teleport 的使用滞诺,不相關(guān)的代碼就省略了形导。header組件

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

watermark7.jpg

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

Suspense

暫未學(xué)習(xí)

片段(Fragment)

在 Vue2.x 中, template中只允許有一個(gè)根節(jié)點(diǎn)伪阶,
但是在 Vue3.x 中煞檩,你可以直接寫多個(gè)根節(jié)點(diǎn), 是不是很爽栅贴。

更好的 Tree - Shaking

Vue3.x 在考慮到tree-shaking的基礎(chǔ)上重構(gòu)了全局和內(nèi)部API斟湃,表現(xiàn)結(jié)果就是現(xiàn)在的全局API需要通過ESMoudle的引用方式進(jìn)行具名引用,比如在Vue2.x中檐薯,我們要使用nextTick:

// vue2.x
import Vue from 'vue'
Vue.nextTick(()=>{
  ...
})

Vue.nextTick()是一個(gè)從Vue對象直接暴露出來的API凝赛,其實(shí)$nextTick()只是Vue.nextTick()的一個(gè)簡易包裝,只是為了方便而把后者的回調(diào)函數(shù)的this綁定到了當(dāng)前實(shí)例坛缕。雖然我們借助webpacktree-shaking墓猎,但是不管我們實(shí)際上是否使用Vue.nextTick(),最終都會進(jìn)入我們的生產(chǎn)代碼赚楚,因?yàn)閂ue實(shí)例是作為單個(gè)對象導(dǎo)出的毙沾,打包器無法檢測出代碼中使用對象的哪些屬性。在Vue3.x中改成這樣寫:

import {nextTick} from 'vue'
nextTick(()=>{
  ...
})

受影響的API

  • Vue.nextTick
  • Vue.observable(用 Vue.reactive 替換)
  • Vue.version
  • Vue.compile(僅限完整版本時(shí)可用)
  • Vue.set(僅在 2.x 兼容版本中可用)
  • Vue.delete(與上同)

變更

slot 具名插槽語法

在vue2.x中宠页,具名插槽的寫法:

<!-- 子組件中 -->
<slot name="title"></slot>

在父組件中使用:

<template slot="title">
  <h1>歌曲</h1>
</template>

如果我們要在slot上面綁定數(shù)據(jù)左胞,可以使用作用域插槽,實(shí)現(xiàn)如下:

// 子組件
<slot name="content" :data="data"></slot>
export default {
data(){
        return{
            data:["走過來人來人往","不喜歡也得欣賞","陪伴是最長情的告白"]
        }
    }
}
<!-- 父組件中使用 -->
<template slot="content" slot-scope="scoped">
    <div v-for="item in scoped.data">{{item}}</div>
<template>

在Vue2.x中具名插槽的作用域插槽分別使用slotslot-scope來實(shí)現(xiàn)举户,在Vue3.x中將slotslot-scope進(jìn)行了合并統(tǒng)一使用烤宙。Vue3.x中 v-slot

<!--父組件中使用-->
<template v-slot:content="scoped">
  <div v-for="item in scope.data">{{item}}</div>
</template>

<!--也可以簡寫成:-->
<template #content="{data}">
  <div v-for="item in data">{{item}}</div>
</template>

自定義指令

首先回顧下 Vue2 中實(shí)現(xiàn)一個(gè)自定義指令:

// 注冊一個(gè)全局自定義指令 v-focus
Vue.directive('focus', {
  inserted: function (el){
    // 聚焦
    el.focus()
  }
})

在vue2.x中,自定義指令通過以下幾個(gè)可選鉤子創(chuàng)建:

  • bind: 只調(diào)用一次敛摘,指令第一次綁定到元素時(shí)調(diào)用门烂。在這里可以進(jìn)行一次性的初始化設(shè)置。
  • inserted: 被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用(僅保證父節(jié)點(diǎn)存在,但不一定已被插入文檔中)
  • update: 所在組件的VNode更新時(shí)調(diào)用屯远,但是可能發(fā)生在其子VNode更新之前蔓姚。指令的值可能發(fā)生了改變,也可能沒有慨丐。但是你可以通過比較更新前后的值來忽略不必要的模板更新坡脐。
  • componentUpdated: 指令所在組件的VNode 及其子VNode 全部更新后調(diào)用
  • unbind: 只調(diào)用一次,指令與元素解綁時(shí)調(diào)用
    在Vue3 中對自定義的API進(jìn)行了更加語義化的修改房揭。


    watermark8.jpg

    所以在 Vue3 中备闲, 可以這樣來自定義指令:

const { createApp } from "vue"

const app = createApp({})
app.directive('focus', {
    mounted(el) {
        el.focus()
    }
})

然后可以在模板中任何元素上使用新的v-focus指令, 如下:

<input v-focus />

v-model 升級

在使用Vue3 之前就了解到 v-model 發(fā)生了很大的變化捅暴,下面來了解下發(fā)生了哪些變化:

  • 變更:在自定義組件上使用v-model時(shí)恬砂,屬性以及事件的默認(rèn)名稱變了
  • 變更: v-bind.sync修飾符在Vue3中去掉,合并到v-model
  • 新增: 同一組件可以同時(shí)設(shè)置多個(gè)v-model
  • 新增: 開發(fā)者可以自定義v-model修飾符

在vue2中蓬痒,在組件上使用 v-model 其實(shí)就相當(dāng)于傳遞了 value屬性呐舔,并觸發(fā)了input事件:

<search-input v-model="searchValue"></search-input>
<!-- 相當(dāng)于 -->
<search-input :value="searchValue" @input="searchValue=$event"></search-input>

這時(shí) v-model只能綁定在組件的value屬性上垄潮,如果我們想給自己組件用一個(gè)別的屬性婆芦,并且不想通過input來更新值楼吃,在.sync出來之前,Vue2是這樣實(shí)現(xiàn)的:

// 子組件:searchInput.vue
export default {
    model:{
        prop: 'search',
        event:'change'
    }
}

修改后亲轨, searchInput 組件使用v-model就相當(dāng)于這樣:

<search-input v-model="searchValue"><search-input>
<!-- 相當(dāng)于 -->
<search-input :search="searchValue" @change="searchValue=$event"><search-input>

但是在實(shí)際開發(fā)中趋惨,有些場景我們可能需要對一個(gè) prop 進(jìn)行 “雙向綁定”, 這里以最常見的 modal 為例子:modal 挺合適屬性雙向綁定的惦蚊,外部可以控制組件的visible顯示或者隱藏器虾,組件內(nèi)部關(guān)閉可以控制 visible屬性隱藏,同時(shí)visible 屬性同步傳輸?shù)酵獠垦病=M件內(nèi)部曾撤, 當(dāng)我們關(guān)閉modal時(shí), 在子組件中以 update:PropName 模式觸發(fā)事件:

this.$emit('update:visible', false)

然后在父組件中可以監(jiān)聽這個(gè)事件進(jìn)行數(shù)據(jù)更新:

<modal :visible="isVisible" @update:visible="isVisible = $event"></modal>

此時(shí)我們也可以使用v-bind.sync來簡化實(shí)現(xiàn):

<modal :visible.sync="isVisible"></modal>

上面回顧了 Vue2 中v-model實(shí)現(xiàn)以及組件屬性的雙向綁定,那么在 Vue 3 中應(yīng)該怎樣實(shí)現(xiàn)的呢晕粪?在vue3中挤悉,在自定義組件上使用v-model,相當(dāng)于傳遞一個(gè)modelValue屬性巫湘,同時(shí)觸發(fā)一個(gè)update:modelValue事件:

<modal v-model="isVisible"></modal>
<!--相當(dāng)于-->
<modal :modelValue="isVisible" @update:modelValue="isVisible = $event"></modal>

如果要綁定屬性名装悲,只需要給v-model傳遞一個(gè)參數(shù)就行,同時(shí)可以綁定多個(gè)v-model

<modal v-model:visible="isVisible" v-model:content="content"></modal>

<!-- 相當(dāng)于 -->
<modal
    :visible="isVisible"
    :content="content"
    @update:visible="isVisible"
    @update:content="content"
/>

不知道你有沒有發(fā)現(xiàn)尚氛,這個(gè)寫法完全沒有.sync什么事兒了诀诊, 所以啊,Vue 3 中又拋棄了.sync寫法阅嘶, 統(tǒng)一使用v-model

異步組件

Vue3 中使用defineAsyncComponent定義異步組件属瓣,配置選項(xiàng)component 替換為loader载迄,Loader函數(shù)本身不在接收resolve 和 reject 參數(shù),且必須返回一個(gè)Promise 抡蛙,用法如下

<template>
  <!--異步組件的使用-->
  <AsyncPage/>
</template>
<script>
import {defineAsyncComponent} from 'vue';
export default{
   components:{
    // 無配置項(xiàng)異步組件
    AsyncPage: defineAsyncComponent(()=>import('./NextPage.vue')),
    // 有配置項(xiàng)異步組件
    AsyncPage: defineAsyncComponent(()=>{
      loader:()=>import('./NextPage.vue'),
      delay:200,
      timeout:3000,
      errorComponent:()=>import("./ErrorComponent.vue"),
      loadingComponent:()=>import("./LoadingComponent.vue")
     })
  },
}
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末护昧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(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)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布魁兼。 她就那樣靜靜地躺著,像睡著了一般漠嵌。 火紅的嫁衣襯著肌膚如雪咐汞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天儒鹿,我揣著相機(jī)與錄音化撕,去河邊找鬼。 笑死约炎,一個(gè)胖子當(dāng)著我的面吹牛植阴,可吹牛的內(nèi)容都是我干的蟹瘾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼掠手,長吁一口氣:“原來是場噩夢啊……” “哼憾朴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惨撇,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤伊脓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后魁衙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體报腔,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年剖淀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纯蛾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纵隔,死狀恐怖翻诉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捌刮,我是刑警寧澤碰煌,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站绅作,受9級特大地震影響芦圾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俄认,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一个少、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧眯杏,春花似錦夜焦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至河闰,卻和暖如春科平,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姜性。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工瞪慧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人部念。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓弃酌,卻偏偏與公主長得像氨菇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子妓湘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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