Vite + Vue3 初體驗(yàn) —— Vue3 篇

在上一篇 Vite + Vue3 初體驗(yàn) —— Vite 篇 博客中恃泪,我感受到了 Vite 帶來(lái)的運(yùn)行時(shí)效率提升贝乎,這一期再來(lái)感受感受 Vue3 帶來(lái)的新變化 —— 關(guān)注點(diǎn)分離。

Todo List 設(shè)計(jì)

這次體驗(yàn) Vue3朽肥,我想做一個(gè)能體驗(yàn)(部分) Vue3 新特性的功能模塊持钉。

想了想每强,用一個(gè) Todo List 應(yīng)該是比較合適的空执。

我們來(lái)規(guī)劃一下它的功能清單吧辨绊。

  1. 輸入 Todo门坷,按下回車(chē)即可添加一條新的 Todo Item默蚌。
  2. 以列表的形式顯示所有的 Todo Item鼻弧。
  3. 可以將 Todo Item 標(biāo)記為完成攘轩,標(biāo)記完成后的 Todo Item 會(huì)置灰度帮,并且排序處于最下面。
  4. 可以將 Todo Item 刪除挠铲,刪除后在列表中不展示安聘。
  5. 可以將 Todo Item 置頂浴韭,高亮顯示念颈,以提高優(yōu)先級(jí)。

OK窟感,接下來(lái)柿祈,我們先把基礎(chǔ)頁(yè)面搭建出來(lái)吧蜜自。

搭建基礎(chǔ) UI 界面

配置 UI 庫(kù)

目前支持 Vue3 的 UI 框架有下面幾種:

  1. Ant Design Vue
  2. Element Plus
  3. Ionic
  4. Native UI

其中 ant-designelementui 是從 Vue2 一路走來(lái)的老 UI 庫(kù)了袁辈,我在體驗(yàn) Vue3 的時(shí)候決定還是使用輕風(fēng)格的 ant-design

先安裝支持 Vue3ant-design-vue 吧荞彼。

yarn add ant-design-vue@next

然后鸣皂,再配置一下按需加載寞缝,這樣的話(huà)荆陆,只有被使用到的組件才會(huì)被打包被啼,可有效減小生產(chǎn)包的體積。

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    Components({
      resolvers: [
        AntDesignVueResolver(),
      ],
    }),
  ]
});

最后命浴,在 main.ts 中引入樣式文件。

// main.ts
import 'ant-design-vue/dist/antd.css';

基礎(chǔ)布局

現(xiàn)在,我們的布局需要一個(gè)輸入框和一個(gè)列表飞醉,我們先在頁(yè)面把這兩個(gè)元素畫(huà)出來(lái)吧轴术。

在此之前,在 App.vue 中引入了我們的 TodoList 組件失暂。

// TodoList.vue
<script setup lang="ts">
import { DeleteOutlined, CheckOutlined, CheckCircleFilled } from '@ant-design/icons-vue';
import { Input } from "ant-design-vue";


</script>

<template>
  <section class="todo-list-container">
    <section class="todo-wrapper">
      <Input class="todo-input" placeholder="請(qǐng)輸入待辦項(xiàng)" />
      <section class="todo-list">
        <section class="todo-item">
          <span>Todo Item</span>
          <div class="operator-list">
            <DeleteOutlined />
            <CheckOutlined />
          </div>
        </section>
        <section class="todo-item">
          <span>Todo Item</span>
          <div class="operator-list">
            <DeleteOutlined />
            <CheckOutlined />
          </div>
        </section>
        <section class="todo-item todo-checked">
          <span>Todo Item</span>
          <div class="operator-list">
            <CheckCircleFilled />
          </div>
        </section>
      </section>
    </section>
  </section>
</template>

<style scoped lang="less">
.todo-list-container {
  display: flex;
  justify-content: center;
  width: 100vw;
  height: 100vh;
  box-sizing: border-box;
  padding-top: 100px;
  background: linear-gradient(rgba(93, 190, 129, .02), rgba(125, 185, 222, .02));
  .todo-wrapper {
    width: 60vw;
    .todo-input {
      width: 100%;
      height: 50px;
      font-size: 18px;
      color: #F05E1C;
      border: 2px solid rgba(255, 177, 27, 0.5);
      border-radius: 5px;
    }
    .todo-input::placeholder {
      color: #F05E1C;
      opacity: .4;
    }
    .ant-input:hover, .ant-input:focus {
      border-color: #FFB11B;
      box-shadow: 0 0 0 2px rgb(255 177 27 / 20%);
    }
    .todo-list {
      margin-top: 20px;
      .todo-item {
        box-sizing: border-box;
        padding: 15px 10px;
        cursor: pointer;
        border-bottom: 2px solid rgba(255, 177, 27, 0.3);
        color: #F05E1C;
        margin-bottom: 5px;
        font-size: 16px;
        transition: all .5s;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding-right: 10px;
        .operator-list {
          display: flex;
          justify-content: flex-start;
          align-items: center;
          :first-child {
            margin-right: 10px;
          }
        }
      }
      .todo-checked {
        color: rgba(199, 199, 199, 1);
        border-bottom-color: rgba(199, 199, 199, .4);
        transition: all .5s;
      }

      .todo-item:hover {
        box-shadow: 0 0 5px 8px rgb(255 177 27 / 20%);
        border-bottom: 2px solid transparent;
      }
      .todo-checked:hover {
        box-shadow: none;
        border-bottom-color: rgba(199, 199, 199, .4);
      }
    }
  }
}
</style>

這次我選了一套黃橙配色摧冀,我們來(lái)看看界面的效果吧索昂。

image

處理業(yè)務(wù)邏輯

處理輸入

現(xiàn)在,我們來(lái)處理一下我們的輸入邏輯框产,在按下回車(chē)鍵時(shí)秉宿,將輸入的結(jié)果收集起來(lái)添加到 Todo 數(shù)組中描睦,并且將輸入框清空。

這里需要用到雙向綁定,定義一個(gè) 引用 變量撵彻,與輸入框進(jìn)行綁定。

<script setup lang="ts">
import { ref } from "vue";

// 創(chuàng)建一個(gè)引用變量陌僵,用于綁定 Todo List 數(shù)據(jù)
const todoList = ref<{
  title: string,
  is_completed: boolean
}[]>([]);

// 創(chuàng)建一個(gè)引用變量轴合,用于綁定輸入框
const todoText = ref('');
const onTodoInputEnter = () => {
  // 將 todo item 添加到 todoList 中
  todoList.value.unshift({
    title: todoText.value,
    is_completed: false
  });
  // 添加到 todoList 后,清空 todoText 的值
  todoText.value = '';
}
</script>
<template>
   //...
  <!-- v-model:value 語(yǔ)法是 vue3 的新特性碗短,代表組件內(nèi)部進(jìn)行雙向綁定是值 key 是 value -->
  <Input v-model:value="todoText" @keyup.enter="onTodoInputEnter" class="todo-input" placeholder="請(qǐng)輸入待辦項(xiàng)" />
</template>

現(xiàn)在打開(kāi)本地開(kāi)發(fā)界面受葛,輸入一個(gè)值,然后按下回車(chē)偎谁,輸入框的值就被清空了 —— 將這一項(xiàng)添加到了 todoList 數(shù)組中总滩!

渲染列表

在處理好了輸入之后搭盾,現(xiàn)在需要將列表渲染出來(lái)蝌以。

這里還是用經(jīng)典的 v-for 語(yǔ)法奸攻,同時(shí)需要加上一些狀態(tài)的判斷硝训。

<section class="todo-list">
  <section v-for="item in todoList" class="todo-item" :class="{'todo-completed': item.is_completed}">
    <span>{{item.title}}</span>
    <div class="operator-list">
      <CheckCircleFilled v-show="item.is_completed" />
      <DeleteOutlined v-show="!item.is_completed" />
      <CheckOutlined v-show="!item.is_completed" />
    </div>
  </section>
</section>

這個(gè)語(yǔ)法相信用過(guò) vue2 的都清楚荸哟,就不做過(guò)多介紹了掏父。

有一說(shuō)一陶缺,vscode + volar 對(duì) vue3 + ts 的支持是真不錯(cuò),代碼提示和錯(cuò)誤提示都非常完善了。在開(kāi)發(fā)過(guò)程中慎菲,簡(jiǎn)直是事半功倍有决。

處理刪除和完成邏輯

最后篱瞎,我們來(lái)處理一下刪除和完成的邏輯吧。

<script setup lang="ts">
// 創(chuàng)建一個(gè)引用變量,用于綁定 Todo List 數(shù)據(jù)
const todoList = ref<{
  title: string,
  is_completed: boolean
}[]>([]);
// 刪除和完成的邏輯都與 todoList 放在同一個(gè)地方嫌套,這樣對(duì)于邏輯關(guān)注點(diǎn)就更加聚焦了
const onDeleteItem = (index: number) => {
  todoList.value.splice(index, 1);
}
const onCompleteItem = (index: number) => {
  todoList.value[index].is_completed = true;
  // 重新排序挨约,將已經(jīng)完成的項(xiàng)目往后排列
  todoList.value = todoList.value.sort(item => item.is_completed ? 0 : -1);
}
</script>
<template>
   //...
  <DeleteOutlined v-show="!item.is_completed" @click="onDeleteItem(index)" />
  <CheckOutlined v-show="!item.is_completed" @click="onCompleteItem(index)" />
</template>

最后,來(lái)看看我們界面的效果吧篮撑。(如下圖)

image

加入置頂邏輯

我們需要先給數(shù)組元素添加一個(gè)字段 is_top又碌,用于判斷該節(jié)點(diǎn)是否置頂圾笨。

然后俭令,再加入置頂函數(shù)的邏輯處理以及樣式顯示。(如下)

<script setup lang="ts">
// 創(chuàng)建一個(gè)引用變量奏寨,用于綁定 Todo List 數(shù)據(jù)
const todoList = ref<{
  title: string,
  is_completed: boolean,
  is_top: boolean
}[]>([]);
const onTopItem = (index: number) => {
  todoList.value[index].is_top = true;
  // 重新排序,將已經(jīng)完成的項(xiàng)目往前排列
  const todoItem = todoList.value.splice(index, 1);
  todoList.value.unshift(todoItem[0]);
}
</script>
<template>
   //...
  <section class="todo-list">
    <section v-for="(item, index) in todoList" 
      class="todo-item" 
      :class="{'todo-completed': item.is_completed, 'todo-top': item.is_top}">
      <span>{{item.title}}</span>
      <div class="operator-list">
        <CheckCircleFilled v-show="item.is_completed" />
        <DeleteOutlined v-show="!item.is_completed" @click="onDeleteItem(index)" />
        <ToTopOutlined v-show="!item.is_completed" @click="onTopItem(index)" />
        <CheckOutlined v-show="!item.is_completed" @click="onCompleteItem(index)" />
      </div>
    </section>
  </section>
</template>

然后,我們來(lái)看看我們的界面效果吧1枳纭(如下圖)

image

這樣一來(lái)邢滑,我們的 Todo List 就完成了愿汰!

現(xiàn)在再來(lái)看看我們的代碼,主要是有兩塊邏輯關(guān)注點(diǎn):

  1. todoList 相關(guān)邏輯酗宋,負(fù)責(zé)列表的渲染以及列表的相關(guān)操作(刪除芬失、置頂、完成)抛蚤。
  2. todoText 相關(guān)邏輯骑脱,負(fù)責(zé)處理輸入框的輸入菜枷。

在分離了邏輯關(guān)注點(diǎn)后帶來(lái)的好處時(shí),如果我想要修改列表相關(guān)的處理邏輯叁丧,我只需要關(guān)注和調(diào)整 todoList 相關(guān)的代碼即可啤誊;如果我想要調(diào)整輸入相關(guān)的邏輯,我只需要關(guān)注和調(diào)整 todoText 相關(guān)的邏輯即可拥娄。

如果這兩塊的邏輯后面隨著業(yè)務(wù)發(fā)展而變得越來(lái)越復(fù)雜了蚊锹,我可以選擇將其拆分成更小塊的業(yè)務(wù)邏輯來(lái)進(jìn)行維護(hù),還可以將這些邏輯都拆分到單文件中進(jìn)行維護(hù)管理稚瘾,這樣對(duì)于后續(xù)的維護(hù)和升級(jí)都能夠有更好的把控牡昆。

處理前后端交互邏輯

我們之前所有的邏輯都是在本地做的處理,現(xiàn)在我們來(lái)接入服務(wù)端的邏輯摊欠,將我們的所有數(shù)據(jù)及變更進(jìn)行持久化丢烘。同時(shí),我們也來(lái)看看在 Vue3 中些椒,如何處理有前后端交互邏輯的場(chǎng)景播瞳。

假設(shè)我們有下面這么幾組接口(如下圖)

image

那么,基于這幾組接口的后端交互邏輯免糕,我們還是用經(jīng)典的 axios 來(lái)做吧赢乓。

使用 yarn add axios 添加依賴(lài)。

這里石窑,我們先在 src 目錄下新建一個(gè) service牌芋,用于初始化我們用于網(wǎng)絡(luò)請(qǐng)求的 service。(如下)

// src/service/index.ts
import axios from "axios";

const service = axios.create({
  // 設(shè)置 baseURL松逊,這個(gè)地址是我部署的后端服務(wù)
  baseURL: "https://hacker.jt-gmall.com"
});

export default service;

用戶(hù)身份信息

我們?cè)O(shè)計(jì)的 Todo List 是一個(gè)在線(xiàn)網(wǎng)頁(yè)躺屁,我們希望每個(gè)用戶(hù)進(jìn)來(lái)看到的都是自己的 Todo List

我們來(lái)看看后臺(tái)的接口設(shè)計(jì)经宏,他使用 key 來(lái)給 Todo Item 做分組楼咳,所以我們需要在進(jìn)入頁(yè)面時(shí),為每一個(gè)用戶(hù)生成一個(gè)獨(dú)一無(wú)二的 user key烛恤。

我們先設(shè)計(jì)一個(gè)用來(lái)獲取 key 的函數(shù)吧母怜。

這里使用 uuid 來(lái)生成唯一的 user key

// service/auth.ts
import { v4 as uuid } from "uuid";

const getUserKey = () => {
  if (localStorage.getItem('user_key')) return localStorage.getItem('user_key');

  const userKey = uuid();
  localStorage.setItem('user_key', userKey);
  return userKey;
}

export {
  getUserKey
}

獲取 Todo List

然后缚柏,我們回到我們的 TodoList.vue 文件苹熏,我們先寫(xiě)一個(gè)獲取遠(yuǎn)端 Todo 列表的邏輯。(如下)

// TodoList.vue
import service from "@/service";
import { getUserKey } from '@/service/auth';

// 創(chuàng)建一個(gè)引用變量,用于綁定 Todo List 數(shù)據(jù)
const todoList = ref<{
  title: string,
  is_completed: boolean,
  is_top: boolean
}[]>([]);
// 初始化 todo list
const getTodoList = async () => {
  const reply = await service.get('/todo/get-todo-list', { params: { key: getUserKey() } });
  todoList.value = reply.data.data;
}
getTodoList();

這里加上網(wǎng)絡(luò)請(qǐng)求后轨域,頁(yè)面也是不會(huì)有什么變化的袱耽,因?yàn)檫@個(gè)用戶(hù)目前是沒(méi)有數(shù)據(jù)的。

接下來(lái)干发,我們把剩下的幾個(gè)邏輯都補(bǔ)全朱巨。

注意:這里使用到了 alias 別名功能,需要在 vite.config.tstsconfig.json 中進(jìn)行配置枉长。

import path from 'path';

// vite.config.ts
export default defineConfig({
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src"),
    }
  },
  // ...
})
// tsconfig.json

{
  "compilerOptions": {
    // ...
    "baseUrl": "./",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

新增冀续、置頂、完成必峰、刪除 Todo

由于用戶(hù)進(jìn)入 Todo List 查看的都是自己的數(shù)據(jù)洪唐,并且該數(shù)據(jù)只有自己可操作。

所以吼蚁,也是為了能有更好的用戶(hù)體驗(yàn)凭需,在我們所有的操作邏輯完成后,回顯數(shù)據(jù)還是用原有的邏輯肝匆。

當(dāng)然粒蜈,新增數(shù)據(jù)時(shí),還是需要重新獲取列表數(shù)據(jù)旗国,因?yàn)槲覀儾僮鲾?shù)據(jù)時(shí)需要用到每一項(xiàng)的 id枯怖。

綜上所述,我們重構(gòu)后的四個(gè)函數(shù)長(zhǎng)這樣粗仓。

// 刪除、完成设捐、置頂?shù)倪壿嫸寂c todoList 放在同一個(gè)地方借浊,這樣對(duì)于邏輯關(guān)注點(diǎn)就更加聚焦了
const onDeleteItem = async (index: number) => {
  const id = todoList.value[index].id;
  await service.post('/todo/delete', { id });

  todoList.value.splice(index, 1);
}

const onCompleteItem = async (index: number) => {
  const id = todoList.value[index].id;
  await service.post('/todo/complete', { id });

  todoList.value[index].is_completed = true;
  // 重新排序,將已經(jīng)完成的項(xiàng)目往后排列
  const todoItem = todoList.value.splice(index, 1);
  todoList.value.push(todoItem[0]);
}

const onTopItem = async (index: number) => {
  const id = todoList.value[index].id;
  await service.post('/todo/top', { id });

  todoList.value[index].is_top = true;
  // 重新排序萝招,將已經(jīng)完成的項(xiàng)目往前排列
  const todoItem = todoList.value.splice(index, 1);
  todoList.value.unshift(todoItem[0]);
}

// 新增 Todo Item 的邏輯都放在一處
// 創(chuàng)建一個(gè)引用變量蚂斤,用于綁定輸入框
const todoText = ref('');
const addTodoItem = () => {
  // 新增一個(gè) TodoItem,請(qǐng)求新增接口
  const todoItem = {
    key: getUserKey(),
    title: todoText.value
  }
  return service.post('/todo/add', todoItem);
}
const onTodoInputEnter = async () => {
  if (todoText.value === '') return;

  await addTodoItem();
  await getTodoList();

  // 添加成功后槐沼,清空 todoText 的值
  todoText.value = '';
}

邏輯修改完成后曙蒸,我們回到頁(yè)面查看一下效果吧!我們做一些操作后岗钩,刷新頁(yè)面查看一下纽窟。(如下圖)

image

刷新頁(yè)面后,我們的數(shù)據(jù)依然是可以展示出來(lái)的兼吓,說(shuō)明數(shù)據(jù)已經(jīng)成功做了服務(wù)端持久化啦臂港!

小結(jié)

這次,我們用 Vue3 來(lái)完成了一個(gè)簡(jiǎn)單的 Todo List 系統(tǒng)。

可以看出审孽,Vue3 對(duì) ts 的支持變得更友好了县袱,而新的 vue 單文件語(yǔ)法和 組合式 API 給我的體驗(yàn)也有點(diǎn)接近 React + JSX。 —— 我的意思是佑力,給開(kāi)發(fā)者的體驗(yàn)更好了式散。

我們?cè)賮?lái)看看我們用 組合式 API 實(shí)現(xiàn)的邏輯部分(如下圖)。

image

從上圖可以看出打颤,我們的邏輯關(guān)注點(diǎn)被分成了兩大塊暴拄,分別是列表相關(guān)邏輯(渲染、操作)和新增 Todo Item瘸洛。

這種清晰的職責(zé)劃分使得我們需要維護(hù)某一部分的功能時(shí)揍移,與之相關(guān)的內(nèi)容都被圈在了一個(gè)比較小的范圍,能夠讓人更加聚焦到需要調(diào)整的功能上反肋。

如果現(xiàn)在讓我給 Vue3Vue2 的(開(kāi)發(fā))體驗(yàn)打個(gè)分的話(huà)那伐,我會(huì)分別給出 8分6分

好啦石蔗,我們這次的 Vue3 體驗(yàn)就到此為止了罕邀,Vue3 給我的體驗(yàn)還是非常不錯(cuò)的!

最后附上本次體驗(yàn)的 Demo 地址养距。

最后一件事

如果您已經(jīng)看到這里了诉探,希望您還是點(diǎn)個(gè)贊再走吧~

您的點(diǎn)贊是對(duì)作者的最大鼓勵(lì),也可以讓更多人看到本篇文章棍厌!

如果覺(jué)得本文對(duì)您有幫助肾胯,請(qǐng)幫忙在 github 上點(diǎn)亮 star 鼓勵(lì)一下吧!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耘纱,一起剝皮案震驚了整個(gè)濱河市敬肚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌束析,老刑警劉巖艳馒,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異员寇,居然都是意外死亡弄慰,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)蝶锋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)陆爽,“玉大人,你說(shuō)我怎么就攤上這事扳缕∧钩拢” “怎么了恶守?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)贡必。 經(jīng)常有香客問(wèn)我兔港,道長(zhǎng),這世上最難降的妖魔是什么仔拟? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任衫樊,我火速辦了婚禮,結(jié)果婚禮上利花,老公的妹妹穿的比我還像新娘科侈。我一直安慰自己,他們只是感情好炒事,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布臀栈。 她就那樣靜靜地躺著,像睡著了一般挠乳。 火紅的嫁衣襯著肌膚如雪权薯。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,215評(píng)論 1 299
  • 那天睡扬,我揣著相機(jī)與錄音盟蚣,去河邊找鬼。 笑死卖怜,一個(gè)胖子當(dāng)著我的面吹牛屎开,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播马靠,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼奄抽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了甩鳄?” 一聲冷哼從身側(cè)響起逞度,我...
    開(kāi)封第一講書(shū)人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娩贷,沒(méi)想到半個(gè)月后第晰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體锁孟,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡彬祖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了品抽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片储笑。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖圆恤,靈堂內(nèi)的尸體忽然破棺而出突倍,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布羽历,位于F島的核電站焊虏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏秕磷。R本人自食惡果不足惜诵闭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望澎嚣。 院中可真熱鬧疏尿,春花似錦、人聲如沸易桃。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晤郑。三九已至敌呈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贩汉,已是汗流浹背驱富。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匹舞,地道東北人褐鸥。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像赐稽,于是被迫代替她去往敵國(guó)和親叫榕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

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