詳解vue-router

120902.jpg

我有一碗酒亩歹,可以慰風(fēng)塵

前端路由定義

在SPA中炊汹,路由指的是URL與UI之間的映射,這種映射是單向的醋寝,即URL變化引起UI更新(無需刷新界面)

實(shí)現(xiàn)前端路由

實(shí)現(xiàn)前端路由口糕,需要解決兩個(gè)核心問題

  • 如何改變URL卻不引起頁面刷新
  • 如何檢測URL變化了

vue-router里面有hash和history兩種方式板祝,下面介紹一下這兩種方式

hash實(shí)現(xiàn)

hash指的是URL中hash(#)及后面的那一part,改變URL中的hash部分不會(huì)引起頁面刷新走净,并且可以通過hashchange事件監(jiān)聽URL的變化。改變URL的方式有如下幾種:

  • 通過瀏覽器的前進(jìn)后退改變URL
  • 通過<a>標(biāo)簽改變URL
  • 通過window.location改變URL

history實(shí)現(xiàn)

HTML5中的history提供了pushState和replaceState兩個(gè)方法孤里,這兩個(gè)方法改變URL的path部分不會(huì)引起頁面刷新
history提供類似hashchange事件的popstate事件伏伯,但又有不同之處

  • 通過瀏覽器前進(jìn)后退改變URL是會(huì)觸發(fā)popstate事件
  • 通過pushState/replaceState或者<a>標(biāo)簽改變URL不會(huì)觸發(fā)popstate事件
  • 我們可以攔截pushState/replaceState的調(diào)用和<a>標(biāo)簽的點(diǎn)擊事件來檢測URL的變化
  • 通過js調(diào)用history的back,go,forward方法來觸發(fā)該事件

實(shí)操js實(shí)現(xiàn)前端路由

基于hash

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title></title>
    </head>
    <body>
        <ul>
            <li><a href="#/home">home</a></li>
            <li><a href="#/about">about</a></li>
        </ul>   
        <!-- 路由渲染口子 -->
        <div id="routerView"></div>
    </body>
    <script>
        let routerView = document.getElementById('routerView')
        window.addEventListener('hashchange', () => {
           const hash = location.hash
           routerView.innerHTML = hash
        })
        
        window.addEventListener('DOMContentLoaded', () => {
            if (!location.hash) {
                location.hash = "/"
            } else {
                const hash = location.hash
                routerView.innerHTML = hash
            }
        })
        
    </script>
</html>

效果圖


image.png

上面的代碼干了哪些活?

  • 通過<a>標(biāo)簽的href屬性來改變URL中的hash值
  • 監(jiān)聽了hashchange事件捌袜,當(dāng)事件觸發(fā)的時(shí)候说搅,改變r(jià)outerView中的內(nèi)容
  • 監(jiān)聽了DOMContentLoaded事件,初次的時(shí)候需要渲染成對(duì)應(yīng)的內(nèi)容

基于HTML5 history實(shí)現(xiàn)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title></title>
    </head>
    <body>
        <ul>
            <li><a href="#/home">home</a></li>
            <li><a href="#/about">about</a></li>
        </ul>   
        <!-- 路由渲染口子 -->
        <div id="routerView"></div> 
        <script>
            const router = document.getElementById('routerView')
            window.addEventListener('DOMContentLoaded', () => {
                const linkList = document.querySelectorAll('a[href]')
                linkList.forEach(el => el.addEventListener('click', function(e) {
                    e.preventDefault()
                    history.pushState(null, '', el.getAttribute('href'))
                    router.innerHTML = location.pathname
                }))
            })
            
            window.addEventListener('popstate', () => {
                router.innerHTML = location.pathname
            })
            
        </script>
    </body>
</html>
  • 我們通過a標(biāo)簽的href屬性來改變URL的path值(當(dāng)然虏等,你觸發(fā)瀏覽器的前進(jìn)后退按鈕也可以弄唧,或者在控制臺(tái)輸入history.go,back,forward賦值來觸發(fā)popState事件)。這里需要注意的就是霍衫,當(dāng)改變path值時(shí)候引,默認(rèn)會(huì)觸發(fā)頁面的跳轉(zhuǎn),所以需要攔截 <a> 標(biāo)簽點(diǎn)擊事件默認(rèn)行為敦跌, 點(diǎn)擊時(shí)使用 pushState 修改 URL并更新手動(dòng) UI澄干,從而實(shí)現(xiàn)點(diǎn)擊鏈接更新 URL 和 UI 的效果。
  • 我們監(jiān)聽popState事件柠傍。一旦事件觸發(fā)麸俘,就改變r(jià)outerView的內(nèi)容

vue 中vue-router

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import About from "../views/About.vue"
Vue.use(VueRouter)
  const routes = [
  {
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
]
const router = new VueRouter({
  mode:"history",
  routes
})
export default router


// App.vue
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/home">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

截圖如下

image.png

改造vue-router文件

import Vue from 'vue'
// import VueRouter from 'vue-router'
import VueRouter from './myVueRouter'
import Home from '../views/Home.vue'
import About from "../views/About.vue"


Vue.use(VueRouter)
  const routes = [
  {
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
]
const router = new VueRouter({
  mode:"history",
  routes
})
export default router

分析vue-router文件干了啥

1, 通過import VueRouter from 'vue-router' 引入了VueRouter
2惧笛,const router = new VueRouter({})
3从媚,Vue.use(VueRouter)使得每個(gè)組件都可以擁有router實(shí)例

  • 通過new VueRouter({})獲得實(shí)例,也就是說VueRouter其實(shí)是一個(gè)類
class VueRouter {
   
}
  • 使用Vue.use()患整,而Vue.use其實(shí)就是執(zhí)行對(duì)象的install這個(gè)方法
class VueRouter {

}

VueRouter.install = function () {

}

export default VueRouter

分析Vue.use

Vue.use(plugin)
1拜效,參數(shù)

{ object | Function } plugin

2喷众,用法
安裝Vue.js插件。如果插件是一個(gè)對(duì)象拂檩,必須提供install方法侮腹。如果插件是一個(gè)函數(shù),它會(huì)被作為install方法稻励。調(diào)用install方法時(shí)父阻,會(huì)將Vue作為參數(shù)傳入。install方法被同一個(gè)插件多次調(diào)用時(shí)望抽,插件也只會(huì)被安裝一次加矛。
3, 作用
注冊插件煤篙,此時(shí)只需要調(diào)用install方法并將Vue作為參數(shù)傳入即可斟览。但在細(xì)節(jié)上有兩部分邏輯要處理:

1、插件的類型辑奈,可以是install方法苛茂,也可以是一個(gè)包含install方法的對(duì)象。

2鸠窗、插件只能被安裝一次妓羊,保證插件列表中不能有重復(fù)的插件。

4稍计,實(shí)現(xiàn)

Vue.use = function(plugin) {
    const installPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installPlugins.indexOf(plugin) > -1) {
        return
    }

    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
        plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
        plugin.apply(null, plugin, args)
    }

    installPlugins.push(plugin)
    return this    
}

1躁绸、在Vue.js上新增了use方法,并接收一個(gè)參數(shù)plugin臣嚣。
2净刮、首先判斷插件是不是已經(jīng)別注冊過,如果被注冊過硅则,則直接終止方法執(zhí)行淹父,此時(shí)只需要使用indexOf方法即可。
3抢埋、toArray方法我們在就是將類數(shù)組轉(zhuǎn)成真正的數(shù)組弹灭。使用toArray方法得到arguments。除了第一個(gè)參數(shù)之外揪垄,剩余的所有參數(shù)將得到的列表賦值給args穷吮,然后將Vue添加到args列表的最前面。這樣做的目的是保證install方法被執(zhí)行時(shí)第一個(gè)參數(shù)是Vue饥努,其余參數(shù)是注冊插件時(shí)傳入的參數(shù)捡鱼。
4、由于plugin參數(shù)支持對(duì)象和函數(shù)類型酷愧,所以通過判斷plugin.install和plugin哪個(gè)是函數(shù)驾诈,即可知用戶使用哪種方式祖冊的插件缠诅,然后執(zhí)行用戶編寫的插件并將args作為參數(shù)傳入。
5乍迄、最后管引,將插件添加到installedPlugins中,保證相同的插件不會(huì)反復(fù)被注冊闯两。

了解以上開始寫myVueRouter.js

let Vue = null

class VueRouter {

}

VueRouter.install = function (v) {
    Vue = v
    Vue.component('router-link',{
        render(h) {
            return h('a', {}, 'Home')
        }
    })
    Vue.component('router-view', {
        render(h) {
            return h('h1', {}, '我是首頁')
        }
    })
}

export default VueRouter

簡易版果然跑起來了褥伴,截圖如下


image.png

完善install方法

install 是給每個(gè)vue實(shí)例添加?xùn)|西的,在router中給每個(gè)組件添加了$route和$router

這倆的區(qū)別是:

$router是VueRouter的實(shí)例對(duì)象漾狼,$route是當(dāng)前路由對(duì)象重慢,也就是說$route是$router的一個(gè)屬性

// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

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

我們可以發(fā)現(xiàn)這里只是將router ,也就是./router導(dǎo)出的router實(shí)例逊躁,作為Vue 參數(shù)的一部分似踱。
但是這里就是有一個(gè)問題咯,這里的Vue 是根組件啊稽煤。也就是說目前只有根組件有這個(gè)router值核芽,而其他組件是還沒有的枷邪,所以我們需要讓其他組件也擁有這個(gè)router潭兽。
因此,install方法我們可以這樣完善

let Vue = null

class VueRouter {

}

VueRouter.install = function (v) {
    Vue = v

    Vue.mixin({
        beforeCreate() {
            if (this.$options && this.$options.router) { // 如果是根組件
                this._root = this // 把當(dāng)前實(shí)例掛載到_root上
                this._router = this.$options.router
            } else {
                this._root = this.$parent && this.$parent._root
            }

            Object.defineProperty(this, '$router', {
                get () {
                    return this._root._router
                }
            })
        }
    })
    Vue.component('router-link',{
        render(h) {
            return h('a', {}, 'Home')
        }
    })
    Vue.component('router-view', {
        render(h) {
            return h('h1', {}, '我是首頁')
        }
    })
}

export default VueRouter

一通操作之下的解釋

  • 參數(shù)Vue榆综,我們在分析Vue.use的時(shí)候绿店,再執(zhí)行install的時(shí)候,將Vue作為參數(shù)傳進(jìn)去庐橙。,
  • mixin的作用是將mixin的內(nèi)容混合到Vue的初始參數(shù)options中假勿。相信使用vue的同學(xué)應(yīng)該使用過mixin了。
  • 為什么是beforeCreate而不是created呢态鳖?因?yàn)槿绻窃赾reated操作的話转培,$options已經(jīng)初始化好了。
  • 如果判斷當(dāng)前組件是根組件的話浆竭,就將我們傳入的router和_root掛在到根組件實(shí)例上浸须。
  • 如果判斷當(dāng)前組件是子組件的話,就將我們_root根組件掛載到子組件邦泄。注意是引用的復(fù)制删窒,因此每個(gè)組件都擁有了同一個(gè)_root根組件掛載在它身上。

? 為啥判斷是子組件就直接取父組件的_root根組件呢
來顺囊,看一下父子組件執(zhí)行順序先
父beforeCreate-> 父created -> 父beforeMounte -> 子beforeCreate ->子create ->子beforeMount ->子 mounted -> 父mounted

在執(zhí)行子組件的beforeCreate的時(shí)候肌索,父組件已經(jīng)執(zhí)行完beforeCreate了,拿到_root那就沒問題了


在vueRouter文件中

const router = new VueRouter({
  mode:"history",
  routes
})

我們傳了兩個(gè)參數(shù),一個(gè)模式mode,一個(gè)是路由數(shù)組routes

let Vue = null

class VueRouter {
    constructor (options) {
        this.mode = options.mode || 'hash'
        this.routes = options.routes || []
        this.routesMap = this.createMap(this.routes)
        
    }
    createMap (routes) {
        return routes.reduce((pre, current) => {
            pre[current.path] = current.component
            return pre
        }, {})
    }
}

VueRouter.install = function (v) {
    Vue = v

    Vue.mixin({
        beforeCreate() {
            if (this.$options && this.$options.router) { // 如果是根組件
                this._root = this // 把當(dāng)前實(shí)例掛載到_root上
                this._router = this.$options.router
            } else {
                this._root = this.$parent && this.$parent._root
            }

            Object.defineProperty(this, '$router', {
                get () {
                    return this._root._router
                }
            })
        }
    })
    Vue.component('router-link',{
        render(h) {
            return h('a', {}, 'Home')
        }
    })
    Vue.component('router-view', {
        render(h) {
            return h('h1', {}, '我是首頁')
        }
    })
}

export default VueRouter

路由中需要存放當(dāng)前的路徑特碳,來表示當(dāng)前的路徑狀態(tài)诚亚,為了方便管理晕换,用一個(gè)對(duì)象來表示。初始化的時(shí)候判斷是那種模式站宗,并將當(dāng)前的路徑保存到current中

let Vue = null

class HistoryRoute {
    constructor () {
        this.current = null
    }
}

class VueRouter {
    constructor (options) {
        this.mode = options.mode || 'hash'
        this.routes = options.routes || []
        this.routesMap = this.createMap(this.routes)
        this.history = new HistoryRoute()
        this.init()
    }

    init () {
        if (this.mode === 'hash') {
            // 先判斷用戶打開是是否有hash值闸准,沒有跳轉(zhuǎn)到#/
            location.hash ? '' : location.hash = '/'
            window.addEventListener('load', () => {
                this.history.current = location.hash.slice(1)
            })
            window.addEventListener('hashchange', () => {
                this.history.current = location.hash.slice(1)
            })
        } else {
            location.pathname ? '' : location.pathname = '/'
            window.addEventListener('load', () => {
                this.history.current = location.pathname
            })
            window.addEventListener('popstate', () => {
                this.history.current = location.pathname
            })
        }
    }

    createMap (routes) {
        return routes.reduce((pre, current) => {
            pre[current.path] = current.component
            return pre
        }, {})
    }
}

VueRouter.install = function (v) {
    Vue = v

    Vue.mixin({
        beforeCreate() {
            if (this.$options && this.$options.router) { // 如果是根組件
                this._root = this // 把當(dāng)前實(shí)例掛載到_root上
                this._router = this.$options.router
            } else {
                this._root = this.$parent && this.$parent._root
            }

            Object.defineProperty(this, '$router', {
                get () {
                    return this._root._router
                }
            })
        }
    })
    Vue.component('router-link',{
        render(h) {
            return h('a', {}, 'Home')
        }
    })
    Vue.component('router-view', {
        render(h) {
            return h('h1', {}, '我是首頁')
        }
    })
}

export default VueRouter

完善$route

其實(shí)/$route就是獲取當(dāng)前的路徑

VueRouter.install = function (v) {
    Vue = v

    Vue.mixin({
        beforeCreate() {
            if (this.$options && this.$options.router) { // 如果是根組件
                this._root = this // 把當(dāng)前實(shí)例掛載到_root上
                this._router = this.$options.router
            } else {
                this._root = this.$parent && this.$parent._root
            }

            Object.defineProperty(this, '$router', {
                get () {
                    return this._root._router
                }
            })

            Object.defineProperty(this, '$route', {
                get () {
                    return this._root._router.history.current
                }
            })
        }
    })
    Vue.component('router-link',{
        render(h) {
            return h('a', {}, 'Home')
        }
    })
    Vue.component('router-view', {
        render(h) {
            return h('h1', {}, '我是首頁')
        }
    })
}

完善router-view

Vue.component('router-view', {
        render(h) {
            let current = this._self._root._router.history.current
            let routeMap = this._self._root._router.routesMap
            return h(routeMap[current])
        }
    })

render函數(shù)里的this指向的是一個(gè)Proxy代理對(duì)象,代理Vue組件梢灭,而我們前面講到每個(gè)組件都有一個(gè)_root屬性指向根組件夷家,根組件上有_router這個(gè)路由實(shí)例。
所以我們可以從router實(shí)例上獲得路由表或辖,也可以獲得當(dāng)前路徑瘾英。
然后再把獲得的組件放到h()里進(jìn)行渲染。
現(xiàn)在已經(jīng)實(shí)現(xiàn)了router-view組件的渲染颂暇,但是有一個(gè)問題缺谴,就是你改變路徑,視圖是沒有重新渲染的耳鸯,所以需要將_router.history進(jìn)行響應(yīng)式化湿蛔。

VueRouter.install = function (v) {
    Vue = v

    Vue.mixin({
        beforeCreate() {
            if (this.$options && this.$options.router) { // 如果是根組件
                this._root = this // 把當(dāng)前實(shí)例掛載到_root上
                this._router = this.$options.router
                // 新增
                Vue.util.defineReactive(this, 'xxx', this._router.history)
            } else {
                this._root = this.$parent && this.$parent._root
            }

            Object.defineProperty(this, '$router', {
                get () {
                    return this._root._router
                }
            })

            Object.defineProperty(this, '$route', {
                get () {
                    return this._root._router.history.current
                }
            })
        }
    })
    Vue.component('router-link',{
        render(h) {
            return h('a', {}, 'Home')
        }
    })
    Vue.component('router-view', {
        render(h) {
            let current = this._self._root._router.history.current
            let routeMap = this._self._root._router.routesMap
            return h(routeMap[current])
        }
    })
}

效果如下


image.png

image.png

完善router-link

Vue.component('router-link',{
        props: {
            to: String
        },
        render(h) {
            let mode = this._self._root._router.mode
            let to = mode === 'hash' ? '#'+this.to : this.to
            return h('a', {attrs: {href: to}}, this.$slots.default)
        }
    })

截圖如下


image.png

image.png

myVueRouter.js完整代碼

let Vue = null

class HistoryRoute {
    constructor () {
        this.current = null
    }
}

class VueRouter {
    constructor (options) {
        this.mode = options.mode || 'hash'
        this.routes = options.routes || []
        this.routesMap = this.createMap(this.routes)
        this.history = new HistoryRoute()
        this.init()
    }

    init () {
        if (this.mode === 'hash') {
            // 先判斷用戶打開是是否有hash值,沒有跳轉(zhuǎn)到#/
            location.hash ? '' : location.hash = '/'
            window.addEventListener('load', () => {
                this.history.current = location.hash.slice(1)
            })
            window.addEventListener('hashchange', () => {
                this.history.current = location.hash.slice(1)
            })
        } else {
            location.pathname ? '' : location.pathname = '/'
            window.addEventListener('load', () => {
                this.history.current = location.pathname
            })
            window.addEventListener('popstate', () => {
                this.history.current = location.pathname
            })
        }
    }

    createMap (routes) {
        return routes.reduce((pre, current) => {
            pre[current.path] = current.component
            return pre
        }, {})
    }
}

VueRouter.install = function (v) {
    Vue = v

    Vue.mixin({
        beforeCreate() {
            if (this.$options && this.$options.router) { // 如果是根組件
                this._root = this // 把當(dāng)前實(shí)例掛載到_root上
                this._router = this.$options.router
                // 新增
                Vue.util.defineReactive(this, 'xxx', this._router.history)
            } else {
                this._root = this.$parent && this.$parent._root
            }

            Object.defineProperty(this, '$router', {
                get () {
                    return this._root._router
                }
            })

            Object.defineProperty(this, '$route', {
                get () {
                    return this._root._router.history.current
                }
            })
        }
    })
    Vue.component('router-link',{
        props: {
            to: String
        },
        render(h) {
            let mode = this._self._root._router.mode
            let to = mode === 'hash' ? '#'+this.to : this.to
            return h('a', {attrs: {href: to}}, this.$slots.default)
        }
    })
    Vue.component('router-view', {
        render(h) {
            let current = this._self._root._router.history.current
            let routeMap = this._self._root._router.routesMap
            return h(routeMap[current])
        }
    })
}

export default VueRouter
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末县爬,一起剝皮案震驚了整個(gè)濱河市阳啥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌财喳,老刑警劉巖察迟,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異耳高,居然都是意外死亡扎瓶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門泌枪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來概荷,“玉大人,你說我怎么就攤上這事碌燕∥笾ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵修壕,是天一觀的道長愈捅。 經(jīng)常有香客問我,道長慈鸠,這世上最難降的妖魔是什么改鲫? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上像棘,老公的妹妹穿的比我還像新娘稽亏。我一直安慰自己,他們只是感情好缕题,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布截歉。 她就那樣靜靜地躺著,像睡著了一般烟零。 火紅的嫁衣襯著肌膚如雪瘪松。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天锨阿,我揣著相機(jī)與錄音宵睦,去河邊找鬼。 笑死墅诡,一個(gè)胖子當(dāng)著我的面吹牛壳嚎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播末早,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼烟馅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了然磷?” 一聲冷哼從身側(cè)響起郑趁,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎姿搜,沒想到半個(gè)月后寡润,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡舅柜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年悦穿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片业踢。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖礁扮,靈堂內(nèi)的尸體忽然破棺而出知举,到底是詐尸還是另有隱情,我是刑警寧澤太伊,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布雇锡,位于F島的核電站,受9級(jí)特大地震影響僚焦,放射性物質(zhì)發(fā)生泄漏锰提。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望立肘。 院中可真熱鬧边坤,春花似錦、人聲如沸谅年。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽融蹂。三九已至旺订,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間超燃,已是汗流浹背区拳。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留意乓,地道東北人樱调。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像洽瞬,于是被迫代替她去往敵國和親本涕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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