vue移動端總結(jié)

移動端適配

相對于PC端來說,移動端設(shè)備分辨率百花齊放,千奇百怪,對于每一個開發(fā)者來說,移動端適配是我們進行移動端開發(fā)第一個需要面對的問題。

在移動端我們經(jīng)常可以在head標(biāo)簽中看到這段代碼:

<meta name='viewport' content='width=device-width,initial-scale=1,user-scale=no' />

通過meta標(biāo)簽對viewport的設(shè)置,定義了頁面的縮放比例;要了解這些參數(shù)的意義,我們需要先知道幾個視口寬度的意義。

  • layoutviewport布局寬度,就是網(wǎng)頁的寬度
  • visualviewport可是寬度,就是瀏覽器窗口的寬度,這個值決定了我們手機一屏能看到的內(nèi)容;visualviewportlayoutviewport的大小關(guān)系,決定了是否會出現(xiàn)滾動條,當(dāng)visualviewport更大或者剛好等于layoutviewport時是不會出現(xiàn)滾動條的。
  • idealviewport為瀏覽器定義的可完美適配移動端的viewport,固定不變,可以認(rèn)為是設(shè)備視口寬度device-width

meta的設(shè)置其實就是對layoutviewportvisualviewport進行設(shè)置。

  • width=device-width表示頁面寬度layoutviewport與設(shè)備視口寬度idealviewport一致
  • initial-scale=1表示頁面寬度和網(wǎng)頁寬度與設(shè)備視口寬度的初始縮放比例,visualviewport由這個比例決定,但是對于layoutviewport來說,它同時受到兩個屬性的影響,然后取其中較大的那個值。
  • user-scale=no禁止縮放

所以現(xiàn)在我們知道,這段在移動端常見的代碼的意思,即將visualviewportlayoutviewport設(shè)置為idealviewport的值;這樣我們在移動端就不會出現(xiàn)滾動條,網(wǎng)頁內(nèi)容可以比較好的展示出來,在這個前提下我們再考慮頁面的適配問題。

UI出圖的時候一般是有一個固定的寬度的,而我們實際的移動端設(shè)備的寬度卻都不太一樣,但是如果頁面元素的縮放比例和頁面寬度的縮放比例一致,在不同尺寸的設(shè)備下我們網(wǎng)頁的效果也將會是一致的。

使用相對單位

rem

rem 是相對于根元素 html 的 font-size 來做計算。通常在頁面初始化時加載時通過對document.documentElement.style.fontSize 設(shè)置來實現(xiàn)。一般我們將根元素html的font-size設(shè)置為寬度的1/10,不同設(shè)備的寬度不同,但是同樣數(shù)值的rem比例與設(shè)備的寬度比例是一致的。

document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';

在實際項目中我們無須在開發(fā)中自己進行轉(zhuǎn)換,可以使用pxtorem在輸出的時候?qū)x轉(zhuǎn)換為rem。

視口單位

將視口寬度window.innerWidth和視口高度window.innerHeight(即layoutviewport)等分為 100 份。

vw : 1vw 為視口寬度的 1%
vh : 1vh 為視口高度的 1%
vmin : vw 和 vh 中的較小值
vmax : 選取 vw 和 vh 中的較大值

和rem相比較,視口單位不需要使用js對根元素進行設(shè)置,兼容性稍差,但是大部分設(shè)備都已經(jīng)支持了,同樣的無須再開發(fā)時進行單位換算,直接使用相關(guān)的插件postcss-px-to-viewport在輸出的時候進行轉(zhuǎn)換。

image

修改viewport

之前我們提到了layoutviewport布局寬度實際上不是一個固定值,而是通過meta設(shè)置屬性,通過idealviewport計算出來的值,我們可以通過控制meta的屬性來將layoutviewport固定為某一個值。一般設(shè)計圖的寬度為750px,現(xiàn)在我們的目標(biāo)就是將layoutviewport設(shè)置為750px;layoutviewport受到兩個屬性的影響,width屬性我們之間設(shè)置為750,initial-scale縮放比例應(yīng)該為idealviewport的寬度/750;當(dāng)我們未改變meta標(biāo)簽屬性的時候,layoutviewport的值其實就是idealviewport的值,所以可以通過document.body.clientWidth或者window.innerWidth來獲取。

;(function () {
    const width = document.body.clientWidth || window.innerWidth
    const scale = width / 750
    const content = 'width=750, initial-scale=' + scale + ', minimum-scale=' + scale + ', maximum-scale=' + scale + ', viewport-fit=cover'
    document.querySelector('meta[name="viewport"]').content = content
})()

設(shè)置完成之后,layoutviewport在不同的設(shè)備中會始終保持為750px,我們開發(fā)時可以直接使用設(shè)計稿尺寸。

布局樣式

布局的方式可以是各種各樣的,但是出于兼容性的考慮,有些樣式我們最好避免使用,難以解決的問題,那就不去面對。

需要謹(jǐn)慎對待的fixed

position:fixed在日常的頁面布局中非常常用,在許多布局中起到了關(guān)鍵的作用。它的作用是:
position:fixed的元素將相對于屏幕視口(viewport)的位置來指定其位置。并且元素的位置在屏幕滾動時不會改變。
但是,在許多特定的場合,position:fixed的表現(xiàn)與我們想象的大相徑庭。

  1. iOS彈出鍵盤;軟鍵盤喚起后,頁面的 fixed元素將失效(iOS認(rèn)為用戶更希望的是元素隨著滾動而移動,也就是變成了 absolute 定位),既然變成了absolute,所以當(dāng)頁面超過一屏且滾動時,失效的 fixed 元素就會跟隨滾動了。
  2. 當(dāng)元素祖先的 transform 屬性非 none 時,定位容器由視口改為該祖先。說的簡單點,就是position:fixed的元素會相對于最近的并且應(yīng)用了transform的祖先元素定位,而不是窗口。導(dǎo)致這個現(xiàn)象的原因是使用了transform的元素將創(chuàng)建一個新的堆疊上下文。堆疊上下文(Stacking Context):堆疊上下文是 HTML 元素的三維概念,這些 HTML 元素在一條假想的相對于面向(電腦屏幕的)視窗或者網(wǎng)頁的用戶的 z 軸上延伸,HTML 元素依據(jù)其自身屬性按照優(yōu)先級順序占用層疊上下文的空間。順序如下圖所示,總之堆疊上下文會對定位關(guān)系產(chǎn)生影響。想要進一步可以查看不受控制的 position:fixed
    image

鍵盤彈出與使用transform屬性的情況在移動端是很常見的,所以需要謹(jǐn)慎使用position:fixed

推薦使用flex

image

flex,即彈性布局,移動端兼容性較好,能夠滿足大部分布局需求。現(xiàn)在我們使用flex來實現(xiàn)h5中常見的頂部標(biāo)題欄+中部滾動內(nèi)容+底部導(dǎo)航欄的布局;實現(xiàn)效果如下:
image

首先我們來實現(xiàn)整體的布局,整體布局應(yīng)該是一個方向為flex-direction: column;并且占據(jù)整個窗口的彈性盒子,然后里面的布局,應(yīng)該是首尾為固定高度,中間內(nèi)容區(qū)域為flex: 1;

html, body {
  padding: 0;
  margin: 0;
}
.page {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  .page-content {
    flex: 1;
    overflow-y: auto;
  }
}

然后再來實現(xiàn)底部標(biāo)題欄,底部標(biāo)題欄一般由居中標(biāo)題和左右操作區(qū)域組成;為了實現(xiàn)中間區(qū)域標(biāo)題居中,我們左右兩部分應(yīng)該保持相同的寬度。

<template>
  <div class="header">
    <div class="header__left">
      左
    </div>
    <div class="header__main">
      <slot>Title</slot>
    </div>
    <div class="header__right">
      <div>右</div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'HeadBar'
}
</script>
<style lang="scss" scoped>
.header {
  display: flex;
  width: 100%;
  line-height: 88px;
  height: 88px;
  font-size: 36px;
  background-color: #42b983;
  z-index: 999;
  color: #fff;
  transition: background-color .5s ease;
  .header__main {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
  }
  .header__left, .header__right {
    padding: 0 16px;
    width: 120px;
  }
  .header__left {
    text-align: left;
  }
  .header__right {
    text-align: right;
  }
}
</style>

底部導(dǎo)航欄主體部分,其實是單個導(dǎo)航選項平分導(dǎo)航欄;而每個導(dǎo)航選項,是一個方向為flex-direction: column;布局方式橫向為align-items: center;,豎向為justify-content: space-around;

<template>
  <div class="taber">
    <div class="taber-item">
      <div class="icon"></div>
      <span>選項1</span>
    </div>
    <div class="taber-item">
      <div class="icon"></div>
      <span>選項2</span>
    </div>
    <div class="taber-item">
      <div class="icon"></div>
      <span>選項3</span>
    </div>
    <div class="taber-item">
      <div class="icon"></div>
      <span>選項4</span>
    </div>
  </div>
</template>
<script>
export default {
  name: 'BottomTaber',
  data () {
    return {
    }
  }
}
</script>
<style lang="scss" scoped>
.taber {
  background-color: #42b983;
  color: #fff;
  height: 88px;
  display: flex;
  .taber-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: center;
  }
  .icon {
    width: 36px;
    height: 36px;
    background-color: #fff;
  }
}
</style>

頁面跳轉(zhuǎn)

轉(zhuǎn)場動畫

在vue中我們通過vue-router來管理路由,每個路由跳轉(zhuǎn)類似與在不同的頁面之間進行切換,從用戶友好的角度來說,每次切換頁面的時候最好添加一個轉(zhuǎn)場效果。如果轉(zhuǎn)場動畫不區(qū)分路由是打開新頁面、還是返回之前頁面我們只需要在<router-view>外使用<transition>添加一個動畫效果即可;但是一般打開和返回是應(yīng)用不同的動畫效果的,所以我們需要在切換路由的時候區(qū)分路由是前進還是后退。為了區(qū)分路由的動作,我們在路由文件中設(shè)置meta為數(shù)字,meta表示其路由的深度,然后監(jiān)聽$route,根據(jù)to、from meta值的大小設(shè)置不同的跳轉(zhuǎn)動畫。如果應(yīng)用到多種跳轉(zhuǎn)動畫,可以根據(jù)詳情,具體情況具體應(yīng)用。

<template>
  <transition :name="transitionName">
    <router-view></router-view>
  </transition>
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      transitionName: 'fade'
    }
  },
  watch: {
    '$route' (to, from) {
      let toDepth = to.meta
      let fromDepth = from.meta
      if (fromDepth > toDepth) {
        this.transitionName = 'fade-left'
      } else if (fromDepth < toDepth) {
        this.transitionName = 'fade-right'
      } else {
        this.transitionName = 'fade'
      }
    }
  }
}
</script>

登錄跳轉(zhuǎn)

雖然這樣能夠?qū)崿F(xiàn)跳轉(zhuǎn)效果,但是需要在編寫router時添加設(shè)置,比較麻煩;我們可以使用開源項目vue-navigation來實現(xiàn),更加方便,無須對router進行多余的設(shè)置。npm i -S vue-navigation安裝,在main.js中導(dǎo)入:

import Navigation from 'vue-navigation'
Vue.use(Navigation, {router}) // router為路由文件

在App.vue中設(shè)置:

this.$navigation.on('forward', (to, from) => {
    this.transitionName = 'fade-right'
 })
 this.$navigation.on('back', (to, from) => {
    this.transitionName = 'fade-left'
 })
 this.$navigation.on('replace', (to, from) => {
    this.transitionName = 'fade'
 })

vue-navigation插件還有一個重要的功能就是保存頁面狀態(tài),與keep-alive相似,但是keep-alive保存狀態(tài)無法識別路由的前進后退,而實際應(yīng)用中,我們的需求是返回頁面時,希望頁面狀態(tài)保存,當(dāng)進入頁面時希望獲取新的數(shù)據(jù),使用vue-navigation可以很好的實現(xiàn)這個效果。具體使用可以查看vue-navigation有詳細(xì)使用說明與案例。另外也可以嘗試vue-page-stack,兩個項目都能實現(xiàn)我們需要的效果,vue-page-stack借鑒了vue-navigation,也實現(xiàn)了更多的功能,并且最近也一直在更新。

PS:
這里的動畫效果引用自animate.scss;

底部導(dǎo)航欄

之前我們已經(jīng)實現(xiàn)了底部導(dǎo)航欄的基本樣式,這里我們再做一些說明。當(dāng)頁面路由路徑與router-link的路由匹配時,router-link將會被設(shè)置為激活狀態(tài),我們可以通過設(shè)置active-class來設(shè)置路徑激活時應(yīng)用的類名,默認(rèn)為router-link-active,而激活的類名還有一個router-link-exact-active,這個類名是由exact-active-class來設(shè)置的,同樣是設(shè)置路徑激活時應(yīng)用的類名;active-classexact-active-class其實是由路由的匹配方式?jīng)Q定的。

一般路由的匹配方式是包含匹配。 舉個例子,如果當(dāng)前的路徑是 /a 開頭的,那么 <router-link to="/a"> 也會被設(shè)置 CSS 類名。按照這個規(guī)則,每個路由都會激活 <router-link to="/">,而使用exact屬性可以使用“精確匹配模式”。精確匹配只有當(dāng)路由完全相同的時候才會被激活。

路由守衛(wèi)

移動端的路由守衛(wèi)一般不會太復(fù)雜,主要是登錄權(quán)限的判斷,我們設(shè)置一個路由白名單,將所有不需要登錄權(quán)限的路由放入其中;對于需要登錄的路由做判斷,沒有登錄就跳轉(zhuǎn)登錄頁面,要求用戶進行登錄后在訪問,如果登錄后需要返回原有路由就把目標(biāo)頁面的路由作為參數(shù)傳遞給登錄頁面,再在登錄后進行判斷,如果存在目標(biāo)頁面參數(shù)就跳轉(zhuǎn)目標(biāo)頁面,沒有就跳轉(zhuǎn)首頁。

如果你的應(yīng)用涉及到權(quán)限,那需要標(biāo)注每個路由需要的權(quán)限,在meta中設(shè)置roles,roles是數(shù)組來保存需要的權(quán)限;從后臺的接口中獲取用戶擁有的權(quán)限和roles進行對比就可以判斷是否具有相關(guān)權(quán)限了。

const whiteList = ['/login']
router.beforeEach((to, from, next) => {
  const hasToken = store.getters.auth
  if (hasToken) {
    if (to.path === '/login') {
      next({ path: '/' })
    } else {
      const needRoles = to.meta && to.meta.roles && to.meta.roles.length > 0
      if (needRoles) {
        const hasRoles = store.state.user.roles.some(role => to.meta.roles.includes(role))
        if (hasRoles) {
          next()
        } else {
          next('/403')
        }
      } else {
        next()
      }
    }
  } else {
    if (whiteList.includes(to.path)) {
      next()
    } else {
      next('/login')
    }
  }
})

組件

自動加載

在我們的項目中,往往會使用的許多組件,一般使用頻率比較高的組件為了避免重復(fù)導(dǎo)入的繁瑣一般是作為全局組件在項目中使用的。而注冊全局組件我們首先需要引入組件,然后使用Vue.component進行注冊;這是一個重復(fù)的工作,我們每次創(chuàng)建組件都會進行,如果我們的項目是使用webpack構(gòu)建(vue-cli也是使用webpack),我們就可以通過require.context自動將組件注冊到全局。創(chuàng)建components/index.js文件:

export default function registerComponent (Vue) {
  /**
   * 參數(shù)說明:
   * 1. 其組件目錄的相對路徑
   * 2. 是否查詢其子目錄
   * 3. 匹配基礎(chǔ)組件文件名的正則表達式
   **/
  const modules = require.context('./', false, /\w+.vue$/)
  modules.keys().forEach(fileName => {
    // 獲取組件配置
    const component = modules(fileName)
    // 獲取組件名稱,去除文件名開頭的 `./` 和結(jié)尾的擴展名
    const name = fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
    // 注冊全局組件
    // 如果這個組件選項是通過 `export default` 導(dǎo)出的,
    // 那么就會優(yōu)先使用 `.default`,
    // 否則回退到使用模塊的根。
    Vue.component(name, component.default || component)
  })
}

之后在main.js中導(dǎo)入注冊模塊進行注冊,使用require.context我們也可以實現(xiàn)vue插件和全局filter的導(dǎo)入。

import registerComponent from './components'
registerComponent(Vue)

通過v-model綁定數(shù)據(jù)

v-model是語法糖,它的本質(zhì)是對組件事件進行監(jiān)聽和數(shù)據(jù)進行更新,是props和$on監(jiān)聽事件的縮寫,v-model默認(rèn)傳遞value,監(jiān)聽input事件。現(xiàn)在我們使用v-model來實現(xiàn)下數(shù)字輸入框,這個輸入框只能輸入數(shù)字,在組件中我們只需要定義value來接受傳值,然后在輸入值滿足我們輸入條件(輸入為數(shù)字)的時候使用$emit觸發(fā)input事件。

<template>
  <div>
    <input type="text" :value="value" @input="onInput">
  </div>
</template>
<script>
export default {
  name: 'NumberInput',
  props: {
    value: String
  },
  methods: {
    onInput (event) {
      if (/^\d+$/.test(event.target.value)) {
        this.$emit('input', event.target.value)
      } else {
        event.target.value = this.value
      }
    }
  }
}
</script>

使用的時候,我們只需要使用v-model綁定值就可以了。
v-model默認(rèn)會利用名為valueprop和名為input的事件,但是很多時候我們想使用不同的prop和監(jiān)聽不同的事件,我們可以使用model選項進行修改。

Vue.component('my-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    // this allows using the `value` prop for a different purpose
    value: String,
    // use `checked` as the prop which take the place of `value`
    checked: {
      type: Number,
      default: 0
    }
  },
  // ...
})
<my-checkbox v-model="foo" value="some value"></my-checkbox>

上述代碼相當(dāng)于:

<my-checkbox
  :checked="foo"
  @change="val => { foo = val }"
  value="some value">
</my-checkbox>

通過插件的方式來使用組件

在很多第三方組件庫中,我們經(jīng)常看到直接使用插件的方式調(diào)用組件的方式,比如VantUI的Dialog彈出框組件,我們不但可以使用組件的方式進行使用,也可以通過插件的形式進行調(diào)用。

this.$dialog.alert({
  message: '彈窗內(nèi)容'
});

將組件作為插件使用的原理其實并不復(fù)雜,就是使用手動掛載Vue組件實例。

import Vue from 'vue';
export default function create(Component, props) {
    // 先創(chuàng)建實例
    const vm = new Vue({
        render(h) {
            // h就是createElement,它返回VNode
            return h(Component, {props})
        }
    }).$mount();
    // 手動掛載
    document.body.appendChild(vm.$el);
    // 銷毀方法
    const comp = vm.$children[0];
    comp.remove = function() {
        document.body.removeChild(vm.$el);
        vm.$destroy();
    }
    return comp;
}

調(diào)用create傳入組件和props參數(shù)就可以獲取組件的實例,通過組件實例我們就可以調(diào)用組件的各種功能了。

<template>
  <div class="loading-wrapper" v-show="visible">
    加載中
  </div>
</template>
<script>
export default {
  name: 'Loading',
  data () {
    return {
      visible: false
    }
  },
  methods: {
    show () {
      this.visible = true
    },
    hide () {
      this.visible = false
    }
  }
}
</script>
<style lang="css" scoped>
.loading-wrapper {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
  background-color: rgba(0, 0, 0, .4);
  z-index: 999;
}
</style>
<!--使用-->
const loading = create(Loading, {})
loading.show() // 顯示
loading.hide() // 關(guān)閉

第三方組件

移動端各種組件、插件已經(jīng)相對完善,在項目開發(fā)中重復(fù)造輪子是一件很不明智的事情;開發(fā)項目時我們可以借助第三方組件、插件提高我們的開發(fā)效率。

常用組件庫

VantUI是有贊開源的一套輕量、可靠的移動端Vue組件庫;支持按需引入、主題定制、SSR,除了常用組件外,針對電商場景還有專門的業(yè)務(wù)組件,如果是開發(fā)電商項目的話,推薦使用。官方文檔關(guān)于主題定制是在webpack.config.js中進行設(shè)置的:

// webpack.config.js
module.exports = {
  rules: [
    {
      test: /\.less$/,
      use: [
        // ...其他 loader 配置
        {
          loader: 'less-loader',
          options: {
            modifyVars: {
              // 直接覆蓋變量
              'text-color': '#111',
              'border-color': '#eee'
              // 或者可以通過 less 文件覆蓋(文件路徑為絕對路徑)
              'hack': `true; @import "your-less-file-path.less";`
            }
          }
        }
      ]
    }
  ]
};

但我們的項目可能是使用vue-cli構(gòu)建,這時我們需要在vue.config.js中進行設(shè)置:

module.exports = {
  css: {
    loaderOptions: {
      less: {
        modifyVars: {
          'hack': `true; @import "~@/assets/less/vars.less";`
        }
      }
    }
  }
}

另外vuxmint-ui也是很好的選擇。

常用插件

better-scroll是一個為移動端各種滾動場景提供絲滑的滾動效果的插件,如果在vue中使用可以參考作者的文章當(dāng) better-scroll 遇見 Vue

swiper是一個輪播圖插件,如果是在vue中使用可以直接使用vue-awesome-swipervue-awesome-swiper基于Swiper4,并且支持SSR。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,643評論 2 380

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

  • 響應(yīng)式布局的理解 響應(yīng)式開發(fā)目的是一套代碼可以在多種終端運行,適應(yīng)不同屏幕的大小,其原理是運用媒體查詢,在不同屏幕...
    懶貓_6500閱讀 800評論 0 0
  • 前端開發(fā)面試題 面試題目: 根據(jù)你的等級和職位的變化,入門級到專家級,廣度和深度都會有所增加。 題目類型: 理論知...
    怡寶丶閱讀 2,605評論 0 7
  • UI組件 element- 餓了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的組件庫 m...
    你猜_3214閱讀 11,129評論 0 118
  • 隨著新年的鐘聲,滿載機遇,滿載夢想的2020向我們翩翩走來。清晨7點半醒來,手機里滿滿的新年祝福,群里更是下...
    麥依20閱讀 468評論 4 4