Vue教程--Wap端项目搭建从0到1(详解3)

本文基于工作项目开发,做的整理笔记
前段时间公司有的小伙伴刚开始学习vue,就直接着手用在新项目上,以项目实战步步为营,不断推进vue的学习和使用。时间短,需求多,又是刚刚上手,遇到的坑和困难也真不少,感觉每天都在疯狂地解决问题。说真的,每种技术的学习和使用,在实际项目的开发上得到了充分检验,个人能力也在快速的成长。
前一段时间,写过文章“Vue教程--使用官方脚手架构建实例”,主要是针对PC端,架构而写。当初的目的,也是想做为一个入门的教程,但是根据反馈和自己后面的感受,发现并不是很好,并没有做到真正的一步步上手。
今天决定专门针对Wap端去做这样一个demo,整体架构的搭建,并含有一些通用的功能。其中,部分知识点请回看前面那篇文章。对比来看,此篇应该更为详细,步步为营。

前提条件:
你已经了解vue的基础知识,尝试过使用vue-cli官方脚手架搭建项目。

编码环境:
system:OS X EI Capitan 10.12.5
npm:5.4.2
node:v8.8.0
vue-cli:@lastest

相关技术栈:
vue2 + vuex + vue-router + webpack + ES6/7 + fetch/axios + sass + flex + svg

相关地址:
项目代码github地址:https://github.com/YuxinChou/vue-wap-demo
项目在线地址:http://www.knowing365.com
(可用手机扫描下文中二维码,或用chrome浏览器模拟手机访问)
参考项目:https://github.com/bailicangdu/vue2-elm

WAP端项目搭建从0到1.jpg

目录
| - 0.传送门
| - 1.安装
| - 2.项目说明
| - 3.项目搭建
  | - Step1. 初始化
  | - Step2. 母版页Layout
  | - Step3. 配置rem
  | - Step4. 配置sass
  | - Step5. 顶部导航header
  | - Step6. 引入iconfont
  | - Step7. 侧边菜单sidebar
  | - Step8. 底部导航footer
  | - Step9. 返回顶部backToTop(组件)
  | - Step10. 仓库存储store
  | - Step11. 侧边菜单状态保存
  | - Step12. 搜索栏searchBar(组件)
  | - Step13. 页面添加
  | - Step14. 弹窗提示(组件)
  | - ---------------------------------- 下内容为详解2
  | - Step15. 完善login页面(fetch请求数据)
  | - Step16. 合理引入svg
  | - Step17. 用axios实现请求(取代原生fetch)
  | - Step18. 登录状态存入仓库
  | - Step19. 滚动加载更多(组件)
  | - Step20. 回到指定位置(组件)
  | - Step21. 完善消息列表页面
  | - Step22. 顶部菜单改造(slot的使用)
  | - --------------------------------- 下内容为详解3
  | - Step23. 完善其他页面
  | - Step24. 权限检查
  | - Step25. 页面切换动画transition
  | - Step26. 轮播展示(swiper)
  | - Step26. 分享功能(vue-social-share)
  | - Step28. ...
| - 4.项目部署
  | - a)本地部署
  | - b)服务器部署
| - 5.后续

Step23. 完善其他页面

contacts联系人页面与messages消息页面想似,用了仓库存储数据。下面看看它的相关代码:

/**********************************************/
/* src/page/contacts/contacts.vue             */
/**********************************************/

<template>
  <div>
    <!-- head -->
    <head-top>
      <span slot='head_text' class="head_text">联系人</span>
      <span slot='head_btn' class="head_btn"><router-link to="/add">添加</router-link></span>
    </head-top>
    <!-- main -->
    <div class="main_wrapper">
      <div class="container">
        <search-bar></search-bar>
        <div class="new_friend">
          <router-link to="/add">
            新朋友
            <span style="position: absolute; right: 0.5rem;"><i class="iconfont icon-arrow-right"></i></span>
          </router-link>
        </div>
        <div class="tab">
          <span class="tab_item" :class="{active:tabActive==0}" @click="handleChangeTab(0)">好友</span>
          <span class="tab_item" :class="{active:tabActive==1}" @click="handleChangeTab(1)">群</span>
          <span class="tab_item" :class="{active:tabActive==2}" @click="handleChangeTab(2)">多人聊天</span>
          <span class="tab_item" :class="{active:tabActive==3}" @click="handleChangeTab(3)">设备</span>
          <span class="tab_item" :class="{active:tabActive==4}" @click="handleChangeTab(4)">通讯录</span>
          <span class="tab_item" :class="{active:tabActive==5}" @click="handleChangeTab(5)">公众号</span>
        </div>
        <div class="group clearfix" v-for="(group, index) in data" :key="index">
          <div class="group_catg" @click="handleToggleGroupList(index)">
            <i class="iconfont" :class="group.closed?'icon-arrow-right':'icon-arrow-down'"></i>
            <span class="name">{{group.name}}</span>
            <span class="nums">{{group.online}}/{{group.total}}</span>
          </div>
          <div class="group_list" :class="{hide:group.closed}">
            <router-link to="/profile" class="item" v-for="(item, index) in group.list" :key="index">
              <div class="item_image" :style="'background-image: url('+item.image+');'"></div>
              <div class="item_info" :class="{last:index==(group.list.length-1)}">
                <div class="item_info_head">
                  <span class="name">{{item.name}}</span>
                </div>
                <div class="item_info_content"><span>{{item.type}}</span>&nbsp;{{item.content}}</div>
              </div>
            </router-link>
          </div>
        </div>
        <transition name="loading">
          <div style="background-color: #fff; padding: 0.5rem; text-align: center; color: #999;" v-show="showLoading">Loading...</div>
        </transition>
      </div>
    </div>
    <!-- footer -->
    <foot-menu :activeIndex="1"></foot-menu>
  </div>
</template>

<script>
  import headTop from '@/components/header/head'
  import footMenu from '@/components/footer/footer'  
  import searchBar from '@/components/common/searchBar' 
  import {scrollPosition} from '@/utils/utils'
  export default {
    components: {
      headTop,
      footMenu,
      searchBar,
    },
    data () {
      return {
        data:[], // 列表数据
        tabActive: 0, // 当前激活的tab
        showLoading: true, //显示加载动画
      }
    },
    mounted(){
      this.initData();
    },
    methods: {
      async initData(){
        // 判断之前是否请求过数据
        if (this.$store.getters.contacts.length == 0) {
          // 请求数据
          this.$store.dispatch('GetContactsList').then(() => {
            this.data = this.$store.getters.contacts;
          }).catch(err => {
            console.log('error:'+err);
          });
          this.hideLoading();
        } else {
          // 直接取之前的数据
          this.data = this.$store.getters.contacts;
          this.hideLoading();
        }
      },
      handleChangeTab(value){
        this.tabActive = value;
      },
      handleToggleGroupList(index){
        this.data[index].closed = !this.data[index].closed;
      },
      hideLoading(){
        this.showLoading = false;
      },

    },
  }
</script>

<style lang="scss" scoped>
  .container {
    margin-bottom: 1.95rem;
    background-color: #f5f5f5;
  }
  .new_friend {
    position: relative;
    background-color: #fff;
    border: 1px solid #eee;
    border-width: 1px 0; 
    margin-bottom: 0.5rem;
    color: #666;
    a {
      display: block;
      padding: 0.5rem; 
      span {
        position: absolute;
        right: 0.5rem;
        .iconfont {
          color: #666;
          font-size: 0.6rem;
        }
      }
    }
  }
  .tab {
    background-color: #fff;
    border: 1px solid #eee;
    border-width: 1px 0; 
    overflow-x: auto;
    overflow-y: hidden;
    width: 140%;
    height: 1.85rem;
    .tab_item {
      display: inline-block;
      padding: 0.5rem 0;
      margin: 0 0.5rem;
      color: #666;
      &.active {
        color: #61b8f8;
      }
    }
  }
  .group {
    background-color: #fff;
    .group_catg {
      position: relative;
      padding: 0.3rem 0.5rem;
      line-height: 1rem;
      .iconfont {
        color: #999;
        font-size: 0.6rem;
        margin-right: 0.3rem;
      }
      .name {
        color: #666;
        font-size: 0.6rem;
        font-weight: 600;
      }
      .nums {
        position: absolute;
        right: 0.5rem;
        color: #999;
        font-size: 0.4rem;
      }
    }
  }
  .item {
    display: flex;
    flex-basis: 100%;
    background-color: #fff;
    .item_image {
      display: flex;
      margin: 0.25rem 0.5rem;
      min-width: 2rem;
      height: 2rem;
      border-radius: 2rem;
      background-size: cover;
      background-position: 50%;
      background-color: #d2d2d2;
      border-bottom: 1px solid transparent;
    }
    .item_info {
      display: flex;
      flex-basis: 100%;
      flex-direction: column;
      padding: 0.25rem 0.5rem 0.25rem 0;
      border-bottom: 1px solid #eee;
      overflow: hidden;
      .item_info_head {
        padding-top: 0.2rem;
        font-size: 0.5rem;
        overflow: hidden;
        color: #999;
        > .name {
          padding-top: 0.4rem;
          color: #666;
          font-size: 0.6rem;
          font-weight: 600;
          line-height: 1rem;
        }
        > .time {
          float: right;
          color: #999;
          font-size: 0.5rem;
          line-height: 1rem;
        }
      }
      .item_info_content {
        font-size: 0.5rem;
        line-height: 1.4;
        color: #666;
        overflow: hidden;
        text-overflow:ellipsis;
        white-space: nowrap;
        span {
          color: #f2a73b;
        }
      }
      &.last {
        border: none;
      }
    }
  }
</style>

其他的页面均为静态页面,直接上代码,如下:

/**********************************************/
/* src/page/dynamics/dynamics.vue             */
/**********************************************/

<template>
  <div>
    <!-- head -->
    <head-top>
      <span slot='head_text' class="head_text">动态</span>
      <span slot='head_btn' class="head_btn"><router-link to="/more">更多</router-link></span>
    </head-top>
    <!-- main -->
    <div class="main_wrapper">
      <div class="container">
        <search-bar></search-bar>
        <div class="catg">
          <router-link to="/more" class="catg_item">
            <i class="iconfont icon-category"></i>
            <span>好友动态</span>
          </router-link>
          <router-link to="/more" class="catg_item">
            <i class="iconfont icon-category"></i>
            <span>附近</span>
          </router-link>
          <router-link to="/more" class="catg_item">
            <i class="iconfont icon-category"></i>
            <span>兴趣部落</span>
          </router-link>
        </div>
        <div class="box">
          <div class="box_item">
            <router-link to="/game">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">游戏 (swiper demo)</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">日迹</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">看点</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">京东购物</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">阅读</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">动漫</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">音乐</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
        </div>
        <div class="box">
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">运动</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">吃喝玩乐</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
          <div class="box_item">
            <router-link to="/more">
              <span class="image"><i class="iconfont icon-category"></i></span>
              <span class="name">同城服务</span>
              <span class="right"><i class="iconfont icon-arrow-right"></i></span>
            </router-link>
          </div>
        </div>
      </div>
    </div>
    <!-- footer -->
    <foot-menu :activeIndex="2"></foot-menu>
  </div>
</template>

<script>
  import headTop from '@/components/header/head'
  import footMenu from '@/components/footer/footer'  
  import searchBar from '@/components/common/searchBar' 
  export default {
    components: {
      headTop,
      footMenu,
      searchBar
    },
  }
</script>

<style lang="scss" scoped>
  .container {
    margin-bottom: 1.95rem;
    background-color: #f5f5f5;
  }
  .catg {
    background-color: #fff;
    width: 100%;
    height: 2.45rem;
    display: flex;
    margin-bottom: 0.5rem;
    .catg_item {
      flex: 1;
      display: flex;
      text-align: center;
      flex-direction: column;
      align-items: center;
      .iconfont {
        display: block;
        font-size: 1rem;
        margin-top: 0.2rem;
        color: #666;
      }
      span {
        display: block;
        font-size: 0.4rem;
        color: #666;
      }
      &.active {
        .iconfont {
          color: #68b7f9;
        }
        span {
          color: #68b7f9;
        }
      }
    }
  }
  .box {
    margin-bottom: 0.5rem;
    border-top: 1px solid #eee;
    .box_item {
      position: relative;
      background-color: #fff;
      border-bottom: 1px solid #eee;
      border-width: 1px 0; 
      color: #666;
      a {
        display: block;
        padding: 0.5rem; 
        .image {
          margin-right: 0.5rem;
          .iconfont {
            font-size: 0.6rem;
          }
        }
        .right {
          position: absolute;
          right: 0.5rem;
          .iconfont {
            color: #666;
            font-size: 0.6rem;
          }
        }
      }
    }
  }
</style>
/**********************************************/
/* src/page/search/search.vue                 */
/**********************************************/

<template>
  <div>
    <!-- head -->
    <head-top :toggleBtn="false">
      <div slot="head_input" class="search">
        <div class="search_content">
          <i class="iconfont icon-search"></i><input placeholder="搜索" value="" />
        </div>
      </div>
      <span slot='head_btn' class="head_btn" @click="returnBack">取消</span>
    </head-top>
    <!-- main -->
    <div class="main_wrapper">
      <div class="container" :style="'height:'+wHeight+'px;'">
        <div class="recent">
          <router-link to="/chat" class="item">
            <div class="item_image" style="background-image: url(http://img.pingan.fusio.com.cn/materials/pic/700/20170928180518_0_KcXn.jpg);"></div>
            <div class="item_info">
              <div class="item_info_head">
                <span class="name">万丈-Infinite</span>
                <span class="close">x</span>
              </div>
            </div>
          </router-link>
          <router-link to="/chat" class="item">
            <div class="item_image" style="background-image: url(http://img.pingan.fusio.com.cn/materials/pic/700/20171012184532_0_xTaB.jpg;"></div>
            <div class="item_info last">
              <div class="item_info_head">
                <span class="name">切图者联盟</span>
                <span class="close">x</span>
              </div>
            </div>
          </router-link>
        </div>
        <div class="catg">
          <div class="catg_title">
            <span>网址导航</span>
          </div>
          <div class="catg_row">
            <router-link to="/more" class="catg_item">
              <span>看点</span>
            </router-link>
            <router-link to="/more" class="catg_item">
              <span>好友动态</span>
            </router-link>
            <router-link to="/more" class="catg_item">
              <span>部落</span>
            </router-link>
          </div>
          <div class="catg_row">
            <router-link to="/more" class="catg_item">
              <span>小说</span>
            </router-link>
            <router-link to="/more" class="catg_item">
              <span>头像</span>
            </router-link>
            <router-link to="/more" class="catg_item">
              <span>热搜榜</span>
            </router-link>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import headTop from '@/components/header/head'
  export default {
    components: {
      headTop,
    },
    data() {
      return {
        wHeight: 0,
      }
    },
    mounted() {
      this.wHeight = document.documentElement.clientHeight || document.body.clientHeight;
    },
    methods: {
      returnBack() {
        this.$router.go(-1);
      },
    }
  }
</script>

<style lang="scss" scoped>
  .container {
    background-color: #fff;
  }
  .catg {
    background-color: #fff;
    width: 100%;
    display: flex;
    flex-direction: column;
    margin-bottom: 0.5rem;
    .catg_title {
      padding: 0.8rem 0.5rem 0.5rem;
      color: #999;
      font-size: 0.4rem;
      text-align: center;
      border-top: 1px solid #eee;
    }
    .catg_row {
      width: 100%;
      display: flex;
      .catg_item {
        flex: 1;
        display: flex;
        text-align: center;
        flex-direction: column;
        align-items: center;
        margin: 0.5rem 0;
        span {
          display: block;
          font-size: 0.6rem;
          color: #1890f5;
        }
        &:nth-child(3n+2) {
          border: 1px solid #ccc;
          border-width: 0 1px;
        }
      }
    }
  }
  .item {
    display: flex;
    flex-basis: 100%;
    background-color: #fff;
    .item_image {
      display: flex;
      margin: 0.25rem 0.5rem;
      min-width: 1.6rem;
      height: 1.6rem;
      border-radius: 2rem;
      background-size: cover;
      background-position: 50%;
      background-color: #d2d2d2;
      border-bottom: 1px solid transparent;
    }
    .item_info {
      display: flex;
      flex-basis: 100%;
      flex-direction: column;
      padding: 0.25rem 0.5rem 0.25rem 0;
      border-bottom: 1px solid #eee;
      overflow: hidden;
      .item_info_head {
        padding-top: 0.3rem;
        font-size: 0.5rem;
        overflow: hidden;
        color: #999;
        > .name {
          padding-top: 0.4rem;
          color: #666;
          font-size: 0.6rem;
          font-weight: 600;
          line-height: 1rem;
        }
        > .close {
          float: right;
          color: #999;
          font-size: 0.6rem;
          line-height: 1rem;
        }
      }
      &.last {
        border: none;
      }
    }
  }
</style>

Step24. 权限检查

我们想在进入每个页面的时候,进行权限检查。之前我们已经缓存了用户登录后的token,可以根据token来判断是否登录。同时,配合路由白名单过滤掉那些不需要登录即可访问的页面。

我们修改src/main.js即可实现权限检查,代码如下:

/**********************************************/
/* src/main.js                                */
/**********************************************/

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import './config/rem'
import './style/index.scss';
import store from './store/index'

Vue.config.productionTip = false

// 不重定向白名单
const whiteList = ['/login', '/signup', '/forget', '/authredirect'];

// 权限检查
router.beforeEach((to, from, next) => {
    document.title = (to.name || '') + ' - vue wap demo';
    next();
     if (store.getters.token) {
         if (to.path === '/login') {
             next({
                 path: '/messages'
             });
         } else {
            next();
        }
     } else {
         if (whiteList.indexOf(to.path) !== -1) {
             next()
         } else {
             next('/login')
         }
     }
});

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App }
})

更进一步的检查是“角色检查”,是否有查看某页面的权限,此项目略,请自己尝试。

Step25. 页面切换动画transition

实现页面切换的动画效果,我们只要修改App.vue即可,代码如下:

/**********************************************/
/* src/App.vue                                */
/**********************************************/

<template>
  <div id="app">
    <transition name="router-fade" mode="out-in">
      <keep-alive>
        <router-view v-if="$route.meta.keepAlive"></router-view>
      </keep-alive>
    </transition>
    <transition name="router-fade" mode="out-in">
      <router-view v-if="!$route.meta.keepAlive"></router-view>
    </transition>
    <!--所有用到的svg可以丢这里-->
    <svg-icon></svg-icon>
  </div>
</template>

<script>
  import svgIcon from '@/components/common/svg'
  export default {
    name: 'app',
    components: {
      svgIcon
    },
  }
</script>

<style lang="scss">
    .router-fade-enter-active,
    .router-fade-leave-active {
      transition: opacity 0.5s;
    }

    .router-fade-enter,
    .router-fade-leave-to {
      opacity: 0;
  }
</style>

目前这样添加代码,只有从login页面登录成功,跳入messages页面的时候才有过渡动画。

如果你还需要在每个页面之间有动画效果,需要在Layout.vue的代码中作类似处理,可以尝试一下。

Step26. 轮播展示

源码中已包含,稍后更新...

Step27. 分享功能

源码中已包含,稍后更新...

Step28. ...

正在更新..

4.项目部署

项目部署,实际是部署一个静态网站,打包生成的dist文件夹就是静态网站的所有文件。现在,就来看一下如何部署。

a)本地部署

本地的话,就直接使用【MAMP】这个软件吧,按步骤一步步安装之后,运行起来基本就可以用了,不需要配置什么。

在“Hosts”那边新增一个Server Name,右边唯一注意的就是把Name resolution的via Xip.io(LAN only)勾选上,这样你就看到下面输入框有个访问地址。在Document root选择你指向的dist文件夹路径(打包文生成的那个)。运行访问就OK了。

MAMP本地运行.png

(在Mac,可以直接利用apache搭建一个的服务器,只要在Users/yourname/Sites这个目录下的静态网站,都可以直接访问,具体搭建可以查询类似“在Mac上搭建本地Apache服务器”)

b)服务器部署

另外一种方式,就是找一个服务器进行部署了,比如亚马逊云、阿里云、腾讯云等。我只是玩过ubuntu和centOS,它们在安装nginx后的路径、配置文件的路径有些不一样,只要找对了位置进行配置就好了。

先把部署文件夹dist丢上服务器,之后再配置nginx的时候指向这个路径就行了。可以通过专门建一个放dist部署文件夹的git项目,这样方便部署更新。

先看下centOS服务器的:

# centOS上面的安装配置大概就这几行
# 遇到权限问题切换admin安装,也可以谷歌查询解决方案

1、安装nodeJS
curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
yum -y install nodejs

2、安装nginx
sudo yum install epel-release
sudo yum install nginx
vi /etc/nginx/nginx.conf  //编辑配置文件
sudo /etc/init.d/nginx start  //启动
sudo /etc/init.d/nginx restart  //重启
sudo /etc/init.d/nginx stop  //停止

3、配置文件内容
# 修改server那一块就好了
server {
    listen 80;
    server_name www.ma.h.fusio.net.cn;
    index index.html;
    root /data/web/apps/ma_front_dev/my-vue-demo-dist/dist;     // 这一行可以测试下不写
    location / {
       root /data/web/apps/ma_front_dev/my-vue-demo-dist/dist;
       try_files $uri $uri/ /index.html =404;
  }
}

下面则是ubuntu服务器的:

# ubuntu上面的安装配置大概就这几行
# 应该比centOS遇到的问题少一点

1、安装nodeJS
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install -y build-essential

2、安装nginx
sudo apt-get update
sudo apt-get install nginx
sudo vi /etc/nginx/sites-available/default   //编辑配置文件
sudo /etc/init.d/nginx start  //启动
sudo /etc/init.d/nginx restart  //重启
sudo /etc/init.d/nginx stop  //停止

3、配置文件内容
(同上)

5.后续

继续补全一些功能,思考中...

写的仓促,可能有些错误,请留言指正...


学习是一条漫漫长路,每天不求一大步,进步一点点就是好的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,277评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,777评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,946评论 0 245
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,271评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,636评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,767评论 1 221
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,989评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,733评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,457评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,674评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,155评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,518评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,160评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,114评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,898评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,822评论 2 280
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,705评论 2 273

推荐阅读更多精彩内容