二、vue+ElementUI開發后臺管理模板—vuex狀態管理、布局

(獲取本節完整代碼 GitHub/chizijijiadami/vue-elementui-2

0、寫在前面

關于布局:我們常見的后臺管理頁面結構一般有下圖中顯示的三種,如果把Tabs(導航的多標簽顯示)、Crumbs(面包屑)、Content(頁面內容)和Footer(底部)當做中間區域視為一塊整體,可以看到主要的區別就是Menu(菜單欄)位置的區別,待會我們就根據這些來設立vuex(vuex官網)的布局狀態值,主要考慮以下兩點:
(1)菜單欄的位置;
(2)設置是否需要該模塊,包括Tabs、Crumbs、Foooter。

關于功能:在后臺模板中我們會用到以下幾種功能:
● Menu菜單自動化
● Tabs多標簽
● Crumbs面包屑導航
● vuex 的 modules
● svg 圖標雪碧圖 svg-sprite-loader
● 批量導入資源
● 自定義全局組件—批量全局注冊
● 自定義全局方法
● 獲取接口數據、模擬數據——axios+Mockjs 【關聯:axios源碼學習到使用】
● 精確到按鈕級別的權限控制

行動前準備:接下來我們用 GitHub/chizijijiadami/hand-to-hand 的代碼來做準備些工作。可以參見下文章 vue實踐1.1 企業官網——prerender-spa-plugin預渲染 ,第2段 css預處理器stylusstylus官網)、第5段vuex狀態管理vuex官網 )。
a、運行后自動打開瀏覽器src>package.json

- "serve": "vue-cli-service serve --mode development",
+ "serve": "vue-cli-service serve --mode development --open",

b、安裝

yarn add  vuex  element-ui
yarn add  stylus stylus-loader -D

c、src>App.vue

<template>
  <div id="app">
-    <header>
-      <nav><router-link to="/index">index</router-link><router-link to="/list">list</router-link></nav>
-    </header>
    <router-view></router-view>
  </div>
</template>
<script>
export default {
  name: 'App',
}
</script>

d、src>main.js

+ import Element from "element-ui";
+ import 'element-ui/lib/theme-chalk/index.css';
+ // 使用Element UI
+ Vue.use(Element, {
+   size: "small"
+ });

- import './assets/styles/reset.css'
- import './assets/styles/style.css'

e、src>pages>Index>index.vue

<template>
  <div>
    <p class="index-p">Index-index</p>
-    <img src="~@/assets/images/jerry.png" alt="" srcset="">
  </div>
</template>
<script>
export default {
    name:"IndexIndex",
-    created(){
-      console.log(process.env.VUE_APP_BASE_API,'輸出VUE_APP_BASE_API');
      
-    }
}
</script>
- <style>
-  @import '~@/assets/styles/component.css'
- </style>

f、刪除
src>assets>images>jerry.png
src>assets>styles>component.css
src>assets>styles>reset.css
src>assets>styles>style.css

準備工作到此結束。

1、新建布局文件

src>pages>Layout>components>Header.vue

<template>
  <div class="app-header">header</div>
</template>

src>pages>Layout>components>Mune.vue

<template>
  <div class="app-menu">
    <el-menu router default-active="/index/index" class="el-menu-vertical-demo">
        <el-menu-item index="/index/index">
          <i class="el-icon-location"></i>
          <span>首頁</span>
        </el-menu-item>
      <el-submenu index="list">
        <template slot="title">
          <i class="el-icon-s-grid"></i>列表
        </template>
          <el-menu-item index="/list/detail">
            <i class="el-icon-goods"></i>詳情
          </el-menu-item>
          <el-menu-item index="/list/feature">
            <i class="el-icon-document"></i>特性
          </el-menu-item>
      </el-submenu>
    </el-menu>
  </div>
</template>

src>pages>Layout>components>Tabs.vue

<template>
  <div clss="app-tabs">
    <el-tabs  type="card">
      <el-tab-pane
        label="首頁"
      ></el-tab-pane>
    </el-tabs>
  </div>
</template>

src>pages>Layout>components>Crumbs.vue

<template>
  <div clss="app-crumbs">
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首頁</el-breadcrumb-item>
    </el-breadcrumb>
 </div>
</template>

src>pages>Layout>components>Content.vue

<template>
   <div class="app-content"><router-view></router-view></div>
</template>

src>pages>Layout>components>Footer.vue

<template>
  <div class="app-footer">大米工廠</div>
</template>

src>pages>Layout>index.vue

<template>
  <div class="app-page">
    <Header />
    <Menu />
    <div class="app-container">
      <Tabs />
      <Crumbs />
      <Content />
      <Footer />
    </div>
</div>
</template>
<script>
import Header from "./components/Header";
import Tabs from "./components/Tabs";
import Menu from "./components/Menu";
import Crumbs from "./components/Crumbs";
import Content from "./components/Content";
import Footer from "./components/Footer";
export default {
  components: {
    Header,
    Menu,
    Tabs,
    Crumbs,
    Content,
    Footer
  }
};
</script>
2、修改src>router>index.js

Vue Router 滾動行為

export default new Router({
+    scrollBehavior() {    //頁面內容多過一屏時,需設置滾動位置
+        return { x: 0, y: 0 }
+    },
    routes: [
      {
            path: '',
-           redirect: '/index',
+           redirect: '/index/index'
        },
        {
              path: '/index',
-             component: _import('Index/index')
+             component: _import('Layout/index'),
+             redirect: '/index/index',
+             children:[
+                 {
+                     path: 'index',
+                     component: _import('Index/index'), 
+                 }
+             ]
         },
          {
             path: '/list',
-            component: _import('List/index'),
+            component: _import('Layout/index'),
             children: [
                  {
                      path: 'detail',
                      component: _import('List/Detail/index')
                  },
                  {
                    path: 'feature',
                     component: _import('List/Feature/index')
                }
             ]
        },
       {
            path: '/404',
            component: _import('ErrorPages/404')
        },
        {
            path: '*',
            redirect: '/404'
        }
    ]
})

訪問檢查下個模塊都加載出來了,接下來我們先按照布局1來寫樣式.

3、布局1樣式

(1)樣式文件中
src>assets>styles>reset.styl

//  主要是一些原生樣式的覆蓋,直接看源代碼

src>assets>styles>base.styl

$body-bgcolor=#f5f6f7
html
   background-color $body-bgcolor

src>assets>styles>layout.styl

$bg-color = #eee
$header_height = 60px
$menu_width = 200px
.app-header
  background-color white
  position absolute
  top 0
  left 0
  height $header_height
  width 100%
.app-menu
  background-color white
  position absolute
  top $header_height
  left 0
  width $menu_width
  height calc(100% - 60px) // $header_height
.app-container
  height 100vh
  padding $header_height  0 0 $menu_width
.app-tabs
  background-color white
  height 40px
.app-crumbs
  height 30px
  line-height 30px
.app-content
  background-color white
  padding 0 10px
  min-height calc(100% - 40px - 30px - 40px) // app-tabs_height、app-crumbs_height、app-footer_height
.app-footer
  background-color white
  height 40px
  line-height 40px

src>assets>styles>index.styl ,統一導入樣式

@require './reset.styl'
@require './base.styl'
@require './layout.styl'

src>main.js中引用

//樣式
import "@/assets/styles/index.styl";

瀏覽器中查看一下,有了。

盡管stylus中有了變量,但是無法跟 calc 友好結合,如果該變量涉及 calc 計算多的話在改版的時候容易漏掉,所以我們把這些搬運到布局文件中進行。
(2)在布局文件中計算
src>pages>Layout>index.vue

<template>
  <div class="app-page">
+    <Header :style="{height:header.height}" />
+    <Menu :style="{top:header.height,width:menu.width,height:menuHeight()}" />
+    <div class="app-container" :style="{padding:containerPadding()}">
+      <Tabs :style="{height:tabs.height}" />
+      <Crumbs :style="{height:crumbs.height,padding:'0 '+content.margin}"   :crumbs="crumbs" :content="content"/>
+      <Content :style="{'min-height':contentMinHeight(),margin:contentMargin()}"/>
+      <Footer :style="{height:footer.height,'line-height':footer.height}" />
    </div>
  </div>
</template>
<script>
import Header from "./components/Header";
import Tabs from "./components/Tabs";
import Menu from "./components/Menu";
import Crumbs from "./components/Crumbs";
import Content from "./components/Content";
import Footer from "./components/Footer";
export default {
  components: {
    Header,
    Menu,
    Tabs,
    Crumbs,
    Content,
    Footer
  },
+  data() {
+    return {
+      header: {
+        height: "60px"
+      },
+      menu: {
+        width: "200px"
+      },
+      content: {
+        margin: "10px"
+      },
+      tabs: {
+        height: "40px"
+      },
+      crumbs: {
+        height: "30px"
+      },
+      footer: {
+        height: "40px"
+      }
+    };
+  },
+  methods: {
+    menuHeight() {
+      return "calc(100% - " + this.header.height + ")";
+    },
+    containerPadding() {
+      return (
+        this.header.height +
+        " 0 0 " +
+        this.menu.width
+      );
+    },
+    contentMinHeight() {
+      return (
+        "calc(100% - " +
+        this.tabs.height +
+        " - " +
+        this.crumbs.height +
+        " - " +
+        this.footer.height +
+        ")"
+      );
+    }
+  }
};
</script>

src>assets>style>layout.styl

$bg-color = #eee
- $header_height = 60px
- $menu_width = 200px
.app-header
  background-color white
  position absolute
  top 0
  left 0
-   height $header_height
  width 100%
.app-menu
    background-color white
    position absolute
-   top $header_height
    left 0
-   width $menu_width
-   height calc(100% - 60px) // $header_height
.app-container
  height 100vh
+  .app-tabs,.app-crumbs,.app-content,.app-footer
+    background-color white   //這后面的都刪掉
-   padding $header_height 0 0 $menu_width
- .app-tabs
-   background-color white
-   height 40px
- .app-crumbs
-   height 30px
-   line-height 30px
-.app-content
-   background-color white
-   padding 0 10px
-   min-height calc(100% - 40px - 30px - 40px) // app-tabs_height、app-crumbs_height、app-footer_height
-.app-footer
-   background-color white
-   height 40px
-   line-height 40px

調整結束,看一下瀏覽器是沒有變化的。
另外左側菜單欄,往往是可以收縮的,下面我們從這里入手結合vuex進行布局調整。

4、結合vuex實現多種布局樣式

(1)菜單欄收縮
新建 src>data>store>index.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store=new Vuex.Store({
    state: { 
        menu: {
            isCollapse: false  //默認菜單展開
        }
    },
    mutations: {
        SET_MENU_ISCOLLAPSE: state => {
            state.menu.isCollapse = !state.menu.isCollapse
        }
    },
    actions: {
        setMenuIsCollapse({ commit }) {
            commit('SET_MENU_ISCOLLAPSE')
        }
    }
  })
export default store

引入 src>main.js

+ import store from './data/store'

new Vue({
   router,
+  store,
   render: h => h(App),
}).$mount('#app')

菜單頁面中取值 src>pages>Layout>components>Menu.vue

-  <el-menu router default-active="/index/index" class="el-menu-vertical-demo">
+  <el-menu :collapse="isCollapse" :collapse-transition="false"  router
                                                       default-active="/index/index" class="el-menu-vertical-demo">

+ <script>
+ export default {
+   computed: {
+     isCollapse() {
+       return this.$store.state.menu.isCollapse;
+     }
+   }
+ };
+ </script>

添加控制事件 src>pages>Layout>components>Hearder.vue

<template>
-  <div class="app-header"></div>
+  <div class="app-header">
+    <el-button type="primary" plain  :icon="isCollapse?'el-icon-s-fold':'el-icon-s-unfold'"></el-button>
+  </div>
</template>
+ <script>
+ export default {
+   computed: {
+     isCollapse() {
+       return this.$store.state.menu.isCollapse;
+     }
+   },
+   methods:{
+     setMenuIsCollapse(){
+       this.$store.dispatch('setMenuIsCollapse');
+     }
+   }
+ };
+ </script>

點擊看看效果,可以收縮,但是外邊 div 沒有同時進行收縮,布局文件中再改點東西。
src>pages>Layout>components>Hearder.vue

-   <Menu :style="{top:header.height,widthmenu.width,height:menuHeight()}" />
+   <Menu :style="{top:header.height,width:isCollapse?menu.widthCollapse:menu.width,height:menuHeight()}" />

+  computed: {  //script中添加
+    isCollapse() {
+      return this.$store.state.menu.isCollapse;
+    }
+  },

這么加只是收縮了菜單欄外層,還有 app-container 的 padding 也要調整

    containerPadding() {
      return (
         this.header.height +
         " 0 0 " +
-         this.menu.width
+        (this.isCollapse ? this.menu.widthCollapse : this.menu.width)
      );
    },

現在點點看,就正常了。

(2)菜單欄位置變化
根據我們前面的布局分類給菜單欄位置設定狀態值。
src>data>store>index.js

        menu: {
            isCollapse: false,
 +           location:"VH"   //V、VH、H三個值,V表示在左側,VH表示橫跨頭部,H表示在頭部,默認 V
        }

根據這個設定,我們目前的布局是 V,現在我們做 VH 。
src>pages>Layout>index.vue——在布局頁獲取

  computed: {
    isCollapse() {
      return this.$store.state.menu.isCollapse;
    },
+    menuLocation(){
+        return this.$store.state.menu.location;
+    }
  },

觀察布局圖,從V到VH只是菜單欄跟頭部的決定定位值不同。那么我們要做的,修改Menu的 top、height 屬性加,Header的 left、width屬性。
src>pages>Layout>index.vue

- <Header :style="{height:header.height}" />
- <Menu :style="{top:header.height,width:isCollapse?menu.widthCollapse:menu.width,height:menuHeight()}" />
+ <Header :style="{height:header.height,left:headerLeft(),width:headerWidth()}" />
+ <Menu :style="{top:menuTop(),width:this.menuWidth(),height:menuHeight()}" />

 methods:{
+  headerLeft(){  //涉及三目運算多時,最好加上括號方便讀碼——這里別忘記菜單欄的收縮
+     return this.menuLocation === "V" ? "0" : ( this.isCollapse ? this.menu.widthCollapse : this.menu.width );
+  },
+  headerWidth(){
+      return this.menuLocation==="V" ? "100%" : "calc(100% - "+this.menuWidth()+")"
+  },
+  menuTop() {
+     return this.menuLocation === "V" ? this.header.height : "0";
+  },
   menuHeight() {
-     return "calc(100% - " + this.header.height + ")";
+     return  this.menuLocation==="V" ? "calc(100% - " + this.header.height + ")" : "100vh";
   },
+  menuWidth(){    //這個值用到的比較多我們單獨寫成一個方式使用
+     return this.isCollapse?this.menu.widthCollapse:this.menu.width;
+  },
    containerPadding() {
      return (
        this.header.height +
        " 0 0 " +
-      (this.isCollapse ? this.menu.widthCollapse : this.menu.width)
+      this.menuWidth()
      );
    },
 ......
 }

src>assets>style>layout.styl

.app-header
   background-color white
   position absolute
   top 0
-  left 0
-  width 100%
.app-menu
   background-color white
   position absolute
-  left 0
.app-container
   height 100vh
   .app-tabs,.app-content,.app-footer
     background-color white

修改完成,瀏覽器里點點看。
接下來,我們寫 H 布局。
src>data>store>index.js

        menu: {
            isCollapse: false,
-           location:"VH"   //V、VH、H三個值,V表示在左側,VH表示橫跨頭部,H表示在頭部
+           location:"H"   //V、VH、H三個值,V表示在左側,VH表示橫跨頭部,H表示在頭部
        }

觀察一下,相對其他兩個布局,布局文件Menu這塊是直接沒了的,還要修改app-container的 padding,Herder的 left、width 屬性。
src>pages>Layout>index.vue

-  <Menu :style="{top:menuTop(),width:this.menuWidth(),height:menuHeight()}" />
+  <Menu v-if="menuLocation!=='H'" :style="{top:menuTop(),width:this.menuWidth(),height:menuHeight()}" />
//methods中
    headerLeft(){
-     return this.menuLocation==="V" ? "0": this.menuWidth();
+     return this.menuLocation==="V" || this.menuLocation==="H" ? "0": this.menuWidth();
    },
    headerWidth(){
-        return this.menuLocation==="V" ? "100%" : "calc(100% - "+this.menuWidth()+")"
+        return this.menuLocation==="V" || this.menuLocation==="H" ? "100%" : "calc(100% - "+this.menuWidth()+")"
    },

    menuWidth() {
-     return this.isCollapse ? this.menu.widthCollapse : this.menu.width;
+     return this.menuLocation === "H"?"0px":this.isCollapse ? this.menu.widthCollapse : this.menu.width;
    },

到這里還剩下菜單欄沒有在Header中顯示,我們接著改Header。
src>pages>Layout>componets>Header.vue

<template>
  <div class="app-header">
-    <el-button type="primary"  plain  @click='setMenuIsCollapse' :icon="isCollapse?'el-icon-s-fold':'el-icon-s-unfold'"></el-button>
+    <Menu  v-if="menuLocation==='H'"/>
+    <el-button v-if="menuLocation!=='H'" type="primary"  plain  @click='setMenuIsCollapse' :icon="isCollapse?'el-icon-s-fold':'el-icon-s-unfold'"></el-button>
  </div>
</template>
<script>
+ import Menu from "./Menu";
+ export default {
+   components:{
+     Menu
+   },
  computed: {
    isCollapse() {
      return this.$store.state.menu.isCollapse;
    },
+     menuLocation() {
+       return this.$store.state.menu.location;
+     }
  },
  methods:{
    setMenuIsCollapse(){
      this.$store.dispatch('setMenuIsCollapse');
    }
  }
};
</script>

src>pages>Layout>componets>Menu.vue

    <el-menu
      :collapse="isCollapse"
      :collapse-transition="false"
      router
      default-active="/index/index"
      class="el-menu-vertical-demo"
+      :mode="menuLocation==='H'?'horizontal':'vertical'"
    >

<script>
export default {
  computed: {
     isCollapse() {
       return this.$store.state.menu.isCollapse;
     },
+    menuLocation() {
+       return this.$store.state.menu.location;
+    }
  }
};
</script>

這就全部改好了,隨意切換下布局狀態值,完美 :)

(3)Tabs、Crumbs、Footer狀態
src>data>store>index.js

    state: { 
        menu: {
            isCollapse: false,
            location:"VH"   //V、VH、H三個值,V表示在左側,VH表示橫跨頭部,H表示在頭部
        },
+        tabs:{
+             isShow:true
+         },
+         crumbs:{
+             isShow:true
+         },
+         footer:{
+             isShow:true
+         }
    },

src>pages>Layout>index.vue

    <div class="app-container" :style="{padding:containerPadding()}">
-     <Tabs :style="{height:tabs.height}" />
-     <Crumbs v-if="isShowCrumbs" :style="{height:crumbs.height,padding:'0 '+content.margin}" :crumbs="crumbs" :content="content" />
+     <Tabs v-if="isShowTabs" :style="{height:tabs.height}" />
+     <Crumbs v-if="isShowCrumbs" :style="{height:crumbs.height,padding:'0 '+content.margin}" :crumbs="crumbs" :content="content" />
      <Content :style="{'min-height':contentMinHeight(),margin:contentMargin()}" />
-     <Footer  :style="{height:footer.height,'line-height':footer.height}" />
+     <Footer v-if="isShowFooter" :style="{height:footer.height,'line-height':footer.height}" />
    </div>

  computed: {
    isCollapse() {
      return this.$store.state.menu.isCollapse;
    },
    menuLocation() {
      return this.$store.state.menu.location;
    },
+    isShowTabs(){
+      return this.$store.state.tabs.isShow;
+    },
+    isShowCrumbs(){
+      return this.$store.state.crumbs.isShow;
+    },
+    isShowFooter(){
+      return this.$store.state.footer.isShow;
+    }
  },

現在可以修改相應的狀態值,看下頁面這些組件的顯示情況,內容不夠一屏時需要頁面撐開,就需要調整Content的 min-height 屬性,先窮舉組合情況:
● Content
● Tabs + Content
● Crumbs + Content
● Tabs + Crumbs + Content
● Tabs + Crumbs + Content + Footer
● Crumbs + Content + Footer
● Tabs + Content + Footer
● Content + Footer
src>pages>Layout>index.vue

    contentMargin() {
-     return "0 " + this.content.margin;
+     let marginTop = this.isShowCrumbs ? "0" : this.content.margin;
+     let marginBottom = this.isShowFooter ? "0" : this.content.margin;
+     return marginTop + " " + this.content.margin +" "+ marginBottom;
    },
    contentMinHeight() {
-      return (
-        "calc(100% - " +
-        this.tabs.height +
-        " - " +
-        this.crumbs.height +
-        " - " +
-        this.footer.height +
        ")"
-      );
+      let tabsHeight = this.isShowTabs ?  this.tabs.height: "0px" ;
+      let crumbsHeight = this.isShowCrumbs ? this.crumbs.height : this.content.margin;  //只有content時留有底部空隙
+      let footerHeight = this.isShowFooter ? this.footer.height : this.content.margin;
+      return ("calc(100% - " +tabsHeight + " - " +crumbsHeight +" - " +footerHeight +")");
    }

現在任意調整狀態值看看。

(4)Tabs位置調整
隨意在一個頁面添加超過一屏的內容,滾動看看,發現忘記將 Tabs 浮動置頂了,現在修改添加一下。
src>assets>style>layout.styl

  .app-menu
    background-color white
    position fixed
+ .app-tabs
+   position fixed

src>pages>Layout>index.vue

-  <Tabs v-if="isShowTabs" :style="{height:tabs.height}" />
+  <Tabs v-if="isShowTabs" :style="{height:tabs.height,top:header.height,left:tabsLeft(),width:tabsWidth()}" />

    containerPadding() {
+    let tabsHeight=this.isShowTabs ? this.tabs.height : "0px"
+    let paddingTop=parseInt(this.header.height)+parseInt(tabsHeight)+"px"
      return (
-       this.header.height +
+       paddingTop +
        " 0 0 " +
        this.menuWidth()
      );
     },
+    tabsLeft(){
+        return this.menuWidth();
+    },
+    tabsWidth(){
+        return "calc(100% - "+this.menuWidth()+" )"
+    },

    contentMinHeight() {
-      let tabsHeight = this.isShowTabs ?  this.tabs.height: "0px" ;   //tabs的高已經在containerPadding中有計算,此處去掉
       let crumbsHeight = this.isShowCrumbs ? this.crumbs.height : this.content.margin;
       let footerHeight = this.isShowFooter ? this.footer.height : this.content.margin;
-      return ("calc(100% - " +tabsHeight + " - " +crumbsHeight +" - " +footerHeight +")");
+      return ("calc(100% - " +crumbsHeight +" - " +footerHeight +")");
    }

到此我們后臺模板最基本的布局就寫成了,接下來我們需要進行模板塊功能的實現:Menu菜單自動化(現在Menu中的導航都是我們手寫的,應當根據路由文件router自動生成相應數據為佳)、Tabs多標簽、Crumbs路徑等將在接下來的文章中實現。

這里拿到的代碼中一些文件的引入路徑跟文章里的是有些區別的,小伙伴么可以想到是為什么么,答案下章說哦。

感謝閱讀,喜歡的話點個贊吧:)
更多內容請關注后續文章。。。

一、vue入門基礎開發—手把手教你用vue開發
三、vue+ElementUI開發后臺管理模板—功能、資源、全局組件
四、vue+ElementUI開發后臺管理模板—方法指令、接口數據
五、vue+ElementUI開發后臺管理模板—精確到按鈕的權限控制

vue3 + vite + ElementPlus開發后臺管理模板

vue實踐1.1 企業官網——prerender-spa-plugin預渲染

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
禁止轉載,如需轉載請通過簡信或評論聯系作者。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374