realworld+nuxtJS項目

REALWORLD項目

介紹
創(chuàng)建項目
// 在nuxt-js-demo創(chuàng)建realworld-nuxtJS分支
git checkout -b realworld-nuxtJS
# 生成 package.json 文件
npm init -y
# 安裝 nuxt 依賴
npm install nuxt

在 package.json 中添加啟動腳本:

"scripts": {
    "dev": "nuxt"
}

創(chuàng)建pages/index.vue

<template>
<div>
    <h1>Home Page</h1>
    </div>
</template>
<script>
    export default {
        name: 'HomePage'
    }
</script>
<style>
</style>

啟動項目:

npm run dev

此時在瀏覽器訪問http://localhost:3000/ 測試肆良。

導(dǎo)入樣式文件

在項目根目錄創(chuàng)建app.html頁面杀饵,導(dǎo)入nuxt.js默認的html

<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
    <head {{ HEAD_ATTRS }}>
        {{ HEAD }}
        <!-- 引入樣式文件 -->
        <!-- Import Ionicon icons & Google Fonts our Bootstrap theme relies on -->
        <link
              
              rel="stylesheet" type="text/css">
        <link href="http://fonts.googleapis.com/css?
                    family=Titillium+Web:700|Source+Serif+Pro:400,700|Merriweather+Sans:400,700|Sour
                    ce+Sans+Pro:400,300,600,700,300italic,400italic,600italic,700italic"
              rel="stylesheet" type="text/css">
        <!-- Import the custom Bootstrap 4 theme from our hosted CDN -->
        <!-- <link rel="stylesheet" > -->
        <link rel="stylesheet" href="/index.css">
    </head>
    <body {{ BODY_ATTRS }}>
        {{ APP }}
    </body>
</html>
創(chuàng)建nuxt.config.js文件
module.exports = {
  router: {
    linkActiveClass: 'active', // 處理導(dǎo)航鏈接高亮
    // 自定義路由規(guī)則
    extendRoutes (routes, resolve) {
      // 清空基于pages目錄默認生成的路由表規(guī)則
      routes.splice(0)

      routes.push(...[
        {
          path: '/',
          component: resolve(__dirname, 'pages/layout/'),
          children: [
            {
              path: '', // 為空代表默認子路由
              name: 'home',
              component: resolve(__dirname, 'pages/home/'),
            }, {
              path: '/login',
              name: 'login',
              component: resolve(__dirname, 'pages/login/'),
            }, {
              path: '/register',
              name: 'register',
              component: resolve(__dirname, 'pages/login/'),
            }, {
              path: '/profile/:username',
              name: 'profile',
              component: resolve(__dirname, 'pages/profile/'),
            }, {
              path: '/settings',
              name: 'settings',
              component: resolve(__dirname, 'pages/settings/'),
            }, {
              path: '/editor',
              name: 'editor',
              component: resolve(__dirname, 'pages/editor/'),
            }, {
              path: '/article/:slug',
              name: 'article',
              component: resolve(__dirname, 'pages/article/'),
            }
          ]
        }
      ])
    }
  }
}
導(dǎo)入以下對應(yīng)頁面 從[頁面模板](https://github.com/gothinkster/realworld-starter-kit/blob/master/FRONTEND_INS TRUCTIONS.md)導(dǎo)入

layout作為頁面根路由物舒,由頭部header慈省、子路由<nuxt-child/>和底部footer組成

image-20210319132908067.png
引入axios 封裝請求模塊
  • 安裝axios

    npm i axios

  • 創(chuàng)建utils/request.js

    import axios from 'axios'
    const request = axios.create({
        baseURL: 'https://conduit.productionready.io/'
    })
    export default request
    
登陸注冊模塊

接口文檔

  • 添加api/user.js文件,封裝登陸注冊方法

    import { request } from '@/plugins/request'
    // 用戶登錄
    export const login = data => {
      return request({
        method: 'POST',
        url: '/api/users/login',
        data
      })
    }
    // 用戶注冊
    export const register = data => {
      return request({
        method: 'POST',
        url: '/api/users',
        data
      })
    }
    
  • 在login組件中根據(jù)路由調(diào)用登陸或注冊接口

  • 為了防止刷新頁面數(shù)據(jù)丟失么介,我們需要把數(shù)據(jù)持久化把登陸狀態(tài)存到Cookie中

    // login/index.vue
    
    // 登陸成功后撬碟,為了防止刷新頁面數(shù)據(jù)丟失伯顶,我們需要把數(shù)據(jù)持久化 把登陸狀態(tài)存到Cookie中 
    // 瀏覽器刷新cookie數(shù)據(jù)不會消失
    Cookie.set('user', data.user)
    
    // store/index.js
    // 要使用cookie中的數(shù)據(jù)初始化vuex中的數(shù)據(jù) 保持登陸狀態(tài)
    export const actions = {
      // nuxtServerInit 是一個nuxt提供的特殊的 action 方法
      // 這個 action 會在服務(wù)端渲染期間自動調(diào)用,且僅在服務(wù)端中運行
      // 作用:初始化容器數(shù)據(jù)鳖眼,以及需要傳遞數(shù)據(jù)給客戶端使用的數(shù)據(jù)
      // commit提交mutations的方法 req服務(wù)端渲染期間的請求對象
      nuxtServerInit ({ commit }, { req }) {
        // console.log('nuxtServerInit')
        let user = null
    
        // 服務(wù)端代碼
        // 如果請求頭中有 Cookie
        if (req.headers.cookie) {
          // 使用 cookieparser 把 cookie 字符串轉(zhuǎn)為 JavaScript 對象
          // 接口中會自動將本地存儲的cookie數(shù)據(jù)發(fā)送到服務(wù)端
          const parsed = cookieparser.parse(req.headers.cookie)
          // try...catch...防止cookie的數(shù)據(jù)格式不對
          try {
            user = JSON.parse(parsed.user)
          } catch (err) {
            // No valid cookie found
          }
        }
    
        // 提交 mutation 修改 state 狀態(tài)
        commit('setUser', user)
      }
    }
    
  • 使用中間件處理頁面訪問權(quán)限

    創(chuàng)建middleware文件夾黑毅,添加authenticated.js和notAuthenticated.js文件,用于控制頁面權(quán)限

    在login/index.vue添加notAuthenticated中間件具帮,用于控制已登錄時跳轉(zhuǎn)到首頁博肋,其他路由頁面添加authenticated中間件用于驗證是否登錄

布局組件layout

在layout中根據(jù)vuex中的user低斋,判斷是否登陸狀態(tài),從而header中設(shè)置不同的選項

首頁模塊home
  • 封裝article.js請求

  • 獲取文章列表getArticles匪凡,應(yīng)該在服務(wù)端渲染膊畴,所以放入asyncData中

  • 根據(jù)獲取到的數(shù)據(jù)格式渲染頁面

  • 處理分頁參數(shù) limit和offset

  • 點擊分頁時改變路由query參數(shù),默認情況不會調(diào)用asyncData方法病游,通過watchQuery監(jiān)聽query改變

    watchQuery: ['page']
    
  • 獲取文章標(biāo)簽列表并展示

  • 優(yōu)化并行異步任務(wù)唇跨,使用Promise.all()實現(xiàn)獲取tags和articles

     // 并發(fā)執(zhí)行
    const [ articleRes, tagRes ] = await Promise.all([
        loadArticles({
            limit,
            offset: (page - 1) * limit, // 數(shù)據(jù)偏移量 頁數(shù) * 大小
            tag
        }),
        getTags()
    ])
    const { data: { articles, articlesCount } } = articleRes
    const { data: { tags } } = tagRes 
    
  • 處理標(biāo)簽列表鏈接和數(shù)據(jù),標(biāo)簽中通過改變query去重新加載數(shù)據(jù)

    watchQuery: ['page', 'tag'],
    
  • 處理標(biāo)簽高亮及鏈接衬衬,通過監(jiān)聽tab的變化买猖,改變標(biāo)簽的高亮及是否展示tag

     watchQuery: ['page', 'tag', 'tab']
    
  • 請求Your Feed標(biāo)簽數(shù)據(jù),getYourFeedArticles滋尉,需要設(shè)置請求頭

    export const getYourFeedArticles = params => {
      return request({
        method: 'GET',
        url: '/api/articles/feed',
        params,
        headers: {
          // 添加用戶身份玉控,數(shù)據(jù)格式:Token空格Token數(shù)據(jù)
          Authorization: `Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6NDgxMTYsInVzZXJuYW1lIjoibHB6OTk5IiwiZXhwIjoxNTk3NzQxNTA4fQ.2yO8Fss4hYnvsIN2UYHsutQ1hmYqSSAA-UrIRnP4DOY`
        }
      })
    }
    
  • 使用axios攔截器同一設(shè)置用戶Token

    如果在utils/request.js中直接設(shè)置請求攔截器,不能像Vue那樣直接通過import store from '@/store'拿到store對象狮惜,因為nuxt中的state是一個函數(shù)高诺;所以需要將請求request.js添加到plugins中

    1. 創(chuàng)建plugins文件夾,將request.js移入plugins中

    2. 在nuxt.config.js中引入,~代表根目錄

      // 注冊插件
      plugins: [
          '~/plugins/request.js',
      ]
      
    3. plugins中默認導(dǎo)出一個上下文對象context碾篡,包含一下內(nèi)容

image-20210321101529020.png
屬性 類型 可用 描述
app vue根實例 客戶端 & 服務(wù)端 包含所有插件的根實例虱而。例如:想使用axios,可以通過context.app.$axios獲取
isClient Boolean 客戶端 & 服務(wù)端 是否來自客戶端渲染开泽,廢棄牡拇,請使用process.client
isServer Boolean 客戶端 & 服務(wù)端 是否來自服務(wù)端渲染,廢棄穆律,請使用process.server
isStatic Boolean 客戶端 & 服務(wù)端 是否通過nuxt generate
isDev Boolean 客戶端 & 服務(wù)端 是否開發(fā)模式惠呼,在生產(chǎn)壞境的數(shù)據(jù)緩存中用到
isHMR Boolean 客戶端 & 服務(wù)端 是否通過模塊熱替換嵌戈,僅在客戶端以dev模式
route 路由 客戶端 & 服務(wù)端 路由實例
store vuex數(shù)據(jù) 客戶端 & 服務(wù)端 Vuex.sttore實例
env l Object 客戶端 & 服務(wù)端 nuxt.config.js中的環(huán)境變量
params Object 客戶端 & 服務(wù)端 route.params的別名
query Object 客戶端 & 服務(wù)端 route.query的別名
req http.Request 服務(wù)端 Node.js API的Request對象废恋。如果nuxt以中間件形式使用的話岁忘,這個對象就根據(jù)你所使用的框架(個人理解為頁面)而定翅敌。nuxt generate 不可用
res http.Reponse 服務(wù)端 Node.js API的Reponse對象椎侠。如果nuxt以中間件形式使用的話闰靴,這個對象就根據(jù)你所使用的框架(個人理解為頁面)而定角溃。nuxt generate 不可用
redirect Function 服務(wù)端 用于重定向另一個路由杠愧,狀態(tài)碼在服務(wù)端被使用利朵,默認302 redirect([status,]path[,query])
error Function 客戶端 & 服務(wù)端 前往錯誤頁面律想,error(parmas),params包含statusCode和message字段
nuxtState Object 客戶端 nuxt狀態(tài)
beforeNuxtRender(fn) Function 服務(wù)端 更新NUXT在客戶端呈現(xiàn)的變量,具體了解請看官網(wǎng)
  1. 設(shè)置axios請求攔截器,獲取store中的user對象绍弟,設(shè)置token

    // 通過插件機制獲取到上下文對象
    // export default (context)
    export default ({ store }) => {
      // console.log(context)
      // 可以在攔截器中做公共業(yè)務(wù)處理 如設(shè)置token
      request.interceptors.request.use(function (config) {
        /**
         * 需要拿到vuex中的user對象
         * import store from '@/store'
         * 因為store都是通過export按需導(dǎo)出
         * 需要按需加載import { state } from '@/store'
         * 此時拿到的state是一個函數(shù) 需要調(diào)用一下此函數(shù)
         * 這樣拿到的數(shù)據(jù)永遠是null
         * 不同于客戶端渲染 所以需要放入到plugins中
         */
        const { user } = store.state
      
        if (user && user.token) {
          config.headers.Authorization = `Token ${user.token}`
        }
      
        // 返回 config 請求配置對象
        return config
      }, function (error) {
        // 如果請求失敗(此時請求還沒有發(fā)出去)就會進入這里
        // Do something with request error
        return Promise.reject(error)
      })
    }
    
  • 處理文章發(fā)布時間格式化

    使用dayjs技即,比moment更輕量,封裝全局過濾器(在plugins中創(chuàng)建)

  • 文章點贊

    asyncData中請求數(shù)據(jù)后樟遣,設(shè)置文章點贊的disabled狀態(tài)

    articles.forEach(article => article.favoriteDisabled = false)
    

    文章點贊或取消點贊時而叼,需要在請求時處理點贊按鈕狀態(tài)

文章詳情
  • 通過getArticle獲取文章詳情身笤,需要在服務(wù)端渲染,請求放入asyncData中

  • 使用markdown-it將markdown格式轉(zhuǎn)為HTML葵陵,使用v-html渲染頁面

  • 展示文章作者相關(guān)信息液荸,封裝組件article-meta.vue,傳入article文章詳情進行渲染

  • 設(shè)置頁面meta優(yōu)化SEO脱篙,nuxt使用vue-meta更新應(yīng)用的頭部標(biāo)簽Head和html屬性娇钱,可以在nuxt.config.js中定義,也可以設(shè)置個性化特定頁面的meta標(biāo)簽

    // 設(shè)置頁面title和description對SEO非常有用
    head () {
        return {
            title: this.title,
            meta: [
                { hid: 'description', name: 'description', content: 'My custom description' }
            ]
        }
    }
    
  • 通過客戶端渲染展示評論列表

發(fā)布文章

添加成功后調(diào)用createArticle創(chuàng)建文章绊困,并跳轉(zhuǎn)到文章詳情頁

用戶中心

加載用戶信息文搂,修改并提交

修改成功后和登陸頁一樣做持久化處理,并跳轉(zhuǎn)到個人中心

退出登陸直接將容器和Coolie中的user設(shè)置為null秤朗,跳轉(zhuǎn)回首頁

個人中心

通過服務(wù)端渲染獲取文章列表和個人信息

處理Edit Profile SettingFollow Eric Simons 按鈕顯示與否

通過監(jiān)聽tab的變化加載文章數(shù)據(jù)

點贊和取消點贊和首頁相同

如果是當(dāng)前用戶點擊Edit Profile Setting進入設(shè)置

發(fā)布部署-打包

Nuxt.js 提供了一系列常用的 命令,用于開發(fā)或發(fā)布部署

命令 描述
nuxt 啟動一個熱加載的Web服務(wù)器(開發(fā)模式) localhost:3000煤蹭。
nuxt build 利用webpack編譯應(yīng)用,壓縮JS和CSS資源(發(fā)布用)取视。
nuxt start 以生產(chǎn)模式啟動一個Web服務(wù)器 (需要先執(zhí)行 nuxt build )疯兼。
nuxt generate 編譯應(yīng)用,并依據(jù)路由配置生成對應(yīng)的HTML文件 (用于靜態(tài)站點的部署)贫途。

部署 Nuxt.js 服務(wù)端渲染的應(yīng)用不能直接使用 nuxt 命令,而應(yīng)該先進行編譯構(gòu)建nuxt build待侵,然后再啟動 Nuxt 服務(wù)nuxt start

常見的命令有:

  • --config-file 或 -c : 指定 nuxt.config.js 的文件路徑丢早。
  • --spa 或 -s : 禁用服務(wù)器端渲染,使用SPA模式
  • --unix-socket 或 -n : 指定UNIX Socket的路徑秧倾。
最簡單的部署方式
  • 配置Host + Port

    在nuxt.config.js中添加

    // 生產(chǎn)環(huán)境服務(wù)器
    server: {
        host: '0.0.0.0', // 默認localhost 如果配置到生產(chǎn)環(huán)境時要設(shè)置為0.0.0.0怨酝,監(jiān)聽所有網(wǎng)卡地址,不然無法訪問
        port: 3000
    },
    
  • 壓縮發(fā)布包

image-20210321140231600.png

.nuxt目錄和static目錄以及nuxt配置文件那先;package.json和package-lock.json是因為需要在服務(wù)端安裝第三方包

壓縮這五個文件到一個壓縮包

  • 把發(fā)布包傳到服務(wù)端

    在vs Code終端中鏈接遠程服務(wù)器

    ssh root@106.75.190.29
    

    將壓縮包上傳到服務(wù)器對應(yīng)地址

    scp ./xxx.zip root@106.75.190.29:/root/realworld-nuxtjs
    
  • 解壓
    unzip 解壓

  • 安裝依賴

    1. 在服務(wù)器上安裝 nvm 參考: https://github.com/nvm-sh/nvm

      wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
      
    2. 重啟ssh終端后, 查看 nvm 版本

      nvm --version
      
    3. 安裝 Node.js lts 長期支持版

      nvm install --lts
      
    4. 安裝依賴

      cnpm i
      
  • 啟動服務(wù)

    npm run dev啟動服務(wù)

使用PM2啟動Node服務(wù)

在服務(wù)器上是通過npm run start命令啟動web服務(wù)农猬,最終執(zhí)行的是nodeJs下的相關(guān)腳本啟動。此時如果退出命令行售淡,服務(wù)就會被關(guān)閉斤葱,導(dǎo)致訪問不到,此時就需要讓服務(wù)在后臺運行揖闸。

如果使用了 Koa/Express 等 Node.js Web 開發(fā)框架揍堕,并使用了 Nuxt 作為中間件,可以自定義 Web 服 務(wù)器的啟動入口:

命令 描述
NODE_ENV=development nodemon server/index.js 啟動一個熱加載的自定義 Web 服務(wù)器(開發(fā)模 式)汤纸。
NODE_ENV=production node server/index.js 以生產(chǎn)模式啟動一個自定義 Web 服務(wù)器 (需要先執(zhí)行 nuxt build )衩茸。
自動化部署
  • 傳統(tǒng)部署

    麻煩,手動構(gòu)建并發(fā)布

  • 現(xiàn)代化部署方式(CI/CD)

    1. 本地將更新代碼推送到遠程倉庫

    2. 將用戶更新通知給持續(xù)集成/持續(xù)部署服務(wù)

      • 拉取最新代碼到服務(wù)當(dāng)中
      • 編譯構(gòu)建
      • 打包生成release
      • 將release部署到服務(wù)器
      image-20210321162548934.png
CI/CD服務(wù)
  • Jenkins
  • Gitlab CI
  • GitHub Actions
  • Travis CI
  • Circle CI
  • ...
使用GitHub Action實現(xiàn)自動部署
配置GItHub Access Token

生成:https://github.com/settings/tokens

  • github settings --> Developer settings --> Personal access tokens --> Generate new token

  • Note --> Select scopes 全選repo贮泞,對此倉庫操作權(quán)限楞慈,生成

  • 復(fù)制token(只顯示一次)

image-20210321171700294.png

配置到項目的Secrets中:https://

  • 指定倉庫 settings --> Secrets --> New Secret創(chuàng)建

  • Name填寫和腳本中的名稱要一致幔烛,value填入剛生成的token

image-20210321171822794.png
配置GitHub Actions執(zhí)行腳本
  • 在項目根目錄創(chuàng)建.github/workflows目錄

  • 在workflows目錄中創(chuàng)建main.yml文件

    name: Publish And Deploy Demo
    on:
      push:
        tags:
          - 'v*'
    
    jobs:
      build-and-deploy:
        runs-on: ubuntu-latest
        steps:
    
        # 下載源碼
        - name: Checkout
          uses: actions/checkout@master
    
        # 打包構(gòu)建
        - name: Build
          uses: actions/setup-node@master
        - run: npm install
        - run: npm run build
        - run: tar -zcvf release.tgz .nuxt static nuxt.config.js package.json package-lock.json pm2.config.json
    
        # 發(fā)布 Release
        - name: Create Release
          id: create_release
          uses: actions/create-release@master
          env:
            GITHUB_TOKEN: ${{ secrets.TOKEN }}
          with:
            tag_name: ${{ github.ref }}
            release_name: Release ${{ github.ref }}
            draft: false
            prerelease: false
    
        # 上傳構(gòu)建結(jié)果到 Release
        - name: Upload Release Asset
          id: upload-release-asset
          uses: actions/upload-release-asset@master
          env:
            GITHUB_TOKEN: ${{ secrets.TOKEN }}
          with:
            upload_url: ${{ steps.create_release.outputs.upload_url }}
            asset_path: ./release.tgz
            asset_name: release.tgz
            asset_content_type: application/x-tgz
    
        # 部署到服務(wù)器
        - name: Deploy
          uses: appleboy/ssh-action@master
          with:
            host: ${{ secrets.HOST }}
            username: ${{ secrets.USERNAME }}
            password: ${{ secrets.PASSWORD }}
            port: ${{ secrets.PORT }}
            script: |
              cd /root/realworld-nuxtjs
              wget https://github.com/lipengzhou/realworld-nuxtjs/releases/latest/download/release.tgz -O release.tgz
              tar zxvf release.tgz
              npm install --production
              pm2 reload pm2.config.json
    
    
  • 修改配置

    添加secrets參數(shù)到github對應(yīng)倉庫

image-20210321173115025.png
  • 配置PM2配置文件

    /**
     * pm2配置文件
     * 使用pm2啟動服務(wù) 名稱RealWorld
     * 腳本是npm 參數(shù)是start
     * 相當(dāng)于執(zhí)行npm start命令
     */
    {
      "apps": [
        {
          "name": "RealWorld",
          "script": "npm",
          "args": "start"
        }
      ]
    }
    
  • 提交更新

    git add .
    git tag v0.1.0
    git push origin v0.1.0
    
  • 查看自動部署狀態(tài)

    Actions頁簽 --> 發(fā)布部署-測試 --> Public And Deploy Demo --> build-and-deploy

  • 訪問網(wǎng)站

  • 提交更新...

項目地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市囊蓝,隨后出現(xiàn)的幾起案子饿悬,更是在濱河造成了極大的恐慌,老刑警劉巖慎颗,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乡恕,死亡現(xiàn)場離奇詭異,居然都是意外死亡俯萎,警方通過查閱死者的電腦和手機傲宜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夫啊,“玉大人函卒,你說我怎么就攤上這事∑裁校” “怎么了报嵌?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熊榛。 經(jīng)常有香客問我锚国,道長,這世上最難降的妖魔是什么玄坦? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任血筑,我火速辦了婚禮,結(jié)果婚禮上煎楣,老公的妹妹穿的比我還像新娘豺总。我一直安慰自己,他們只是感情好择懂,可當(dāng)我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布喻喳。 她就那樣靜靜地躺著,像睡著了一般困曙。 火紅的嫁衣襯著肌膚如雪表伦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天赂弓,我揣著相機與錄音绑榴,去河邊找鬼。 笑死盈魁,一個胖子當(dāng)著我的面吹牛翔怎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼赤套,長吁一口氣:“原來是場噩夢啊……” “哼飘痛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起容握,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宣脉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后剔氏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塑猖,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年谈跛,在試婚紗的時候發(fā)現(xiàn)自己被綠了羊苟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡感憾,死狀恐怖蜡励,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阻桅,我是刑警寧澤凉倚,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嫂沉,受9級特大地震影響稽寒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜趟章,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一瓦胎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尤揣,春花似錦、人聲如沸柬祠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漫蛔。三九已至嗜愈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莽龟,已是汗流浹背蠕嫁。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留毯盈,地道東北人剃毒。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赘阀。 傳聞我的和親對象是個殘疾皇子益缠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,107評論 2 356

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