vue項(xiàng)目打包成exe桌面程序

總結(jié)

主要執(zhí)行以下命令

全局安裝electron:npm install electron -g

安裝electron-builder依賴:vue add electron-builder

運(yùn)行桌面程序:npm run electron:serve

打包應(yīng)用程序:npm run electron:build

更新應(yīng)用程序:npm i electron-updater --save

electron-builder 教程

一、本人比較笨,拷貝原始項(xiàng)目后譬巫,安轉(zhuǎn)依賴并啟動(dòng)

執(zhí)行命令:npm install

執(zhí)行命令:npm run serve

二糟袁、全局安裝electron:

執(zhí)行命令:npm install electron -g

三、安裝electron-builder依賴:

執(zhí)行命令:vue add electron-builder

electron-builder安裝成功后項(xiàng)目目錄如下:

electron-builder安裝成功后項(xiàng)目目錄

會(huì)發(fā)現(xiàn)目錄里多了一個(gè)background.js 的文件,并且package.json 里多了依賴和執(zhí)行命令其中這個(gè)“main”: “background.js” 是electron的入口文件

四、運(yùn)行桌面程序

執(zhí)行命令:npm run electron:serve

執(zhí)行以上命令后項(xiàng)目啟動(dòng)速度較慢,可以注釋掉background.js文件中await installExtension(VUEJS_DEVTOOLS) 這一句代碼

注釋掉background.js文件中內(nèi)容

項(xiàng)目運(yùn)行后顯示界面如下:

運(yùn)行后的桌面程序


五格侯、打包

執(zhí)行命令:npm run electron:build

執(zhí)行打包命令后報(bào)錯(cuò):"directories" in the root is deprecated, please specify in the "build",如下圖顯示:

打包報(bào)錯(cuò)

解決辦法财著,刪掉“directories”這部分內(nèi)容:

刪除紅線圈住內(nèi)容

打包成功后exe程序所在位置:

根目錄/dist_electron/win-unpacked/vue-antd-pro.exe 联四,如下圖所示:

打包成功后exe程序所在位置

六、在vue.config.js中module.exports中添加pluginOptions配置:更換exe應(yīng)用程序中的名稱和圖標(biāo)

打包教程地址:https://blog.csdn.net/Assassin_EZI0/article/details/107144377

pluginOptions配置

執(zhí)行打包命令:npm run electron:build撑教,重新打包后

七朝墩、更新應(yīng)用程序?參考網(wǎng)址

客戶安裝應(yīng)用以后,如果有新功能更新伟姐,那客戶那邊如何更新收苏?解決方案亿卤,安裝:electron-updater

執(zhí)行命令:npm i electron-updater --save

介紹一下原理:使用electron-updater, 打包后會(huì)生成一個(gè)latest.yml 的文件鹿霸,里面包含了版本號(hào)等描述信息排吴,

并且electron-updater 提供了一系列監(jiān)聽事件,允許應(yīng)用向服務(wù)器檢測(cè)當(dāng)前版本是否可以更新懦鼠,

如果可以更新钻哩,在對(duì)應(yīng)的監(jiān)聽事件里做了相關(guān)處理(下載最新版本,下載完成后退出并重新安裝)

?在目錄下新增一個(gè)目錄_main, 里面有兩個(gè)文件肛冶,events.js(定義了事件名稱) 和 updater.js (處理接收)和 helper.js(是封裝的持久化數(shù)據(jù)相關(guān)操作方法)街氢。

helper.js

import { join } from 'path'

import fs from 'fs'

import { app } from 'electron'

const dataPath = join(app.getPath('userData'), 'data.json')

export function getLocalData(key) {

? if (!fs.existsSync(dataPath)) {

? ? fs.writeFileSync(dataPath, JSON.stringify({}), { encoding: 'utf-8' })

? }

? let data = fs.readFileSync(dataPath, { encoding: 'utf-8' })

? let json = JSON.parse(data)

? return key ? json[key] : json

}

export function setLocalData(key, value) {

? let args = [...arguments]

? let data = fs.readFileSync(dataPath, { encoding: 'utf-8' })

? let json = JSON.parse(data)

? if (args.length === 0 || args[0] === null) {

? ? json = {}

? } else if (args.length === 1 && typeof key === 'object' && key) {

? ? json = {

? ? ? ...json,

? ? ? ...args[0],

? ? }

? } else {

? ? json[key] = value

? }

? fs.writeFileSync(dataPath, JSON.stringify(json), { encoding: 'utf-8' })

}

export async function sleep(ms) {

? return new Promise((resolve) => {

? ? const timer = setTimeout(() => {

? ? ? resolve()

? ? ? clearTimeout(timer)

? ? }, ms)

? })

}

events.js:

// ipc通信事件, main 和 render都會(huì)用

export default {

downLoadUpdate: 'downLoadUpdate', // 手動(dòng)下載更新

checkUpdate: 'checkUpdate', // 請(qǐng)求檢查更新

startCheckUpdate: 'startCheckUpdate', // 開始檢查更新

checkUpdateError: 'checkUpdateError', // 檢查更新出錯(cuò)

checkingUpdate: 'checkingUpdate', // 正在檢查更新

updateAvailable: 'updateAvailable', // 有新版本更新

updateNotAvailable: 'updateNotAvailable', // 沒(méi)有新版本更新

updateDownloading: 'updateDownloading', // 正在下載中

updateDownloaded: 'updateDownloaded' // 下載完成

}

updater.js:

import { autoUpdater } from 'electron-updater'

// import { ipcMain } from 'electron'

// import logger from 'electron-log'

import Events from './events'

import { getLocalData, setLocalData, sleep } from './helper' // 是封裝的持久化數(shù)據(jù)相關(guān)操作方法。

import { app, dialog } from 'electron'

// // 主進(jìn)程接收渲染進(jìn)程(頁(yè)面)派發(fā)過(guò)來(lái)的 檢測(cè)更新事件

// ipcMain.on(Events.checkUpdate, () => {

//? // 向服務(wù)端查詢現(xiàn)在是否有可用的更新睦袖。在調(diào)用這個(gè)方法之前珊肃,必須要先調(diào)用 setFeedURL

//? autoUpdater.checkForUpdates()

// })

// // 主進(jìn)程接收渲染進(jìn)程(頁(yè)面)派發(fā)過(guò)來(lái)的 下載更新事件

// ipcMain.on(Events.downLoadUpdate, () => {

//? autoUpdater.downloadUpdate()

// })

export async function listenUpdater(mainWindow, feedUrl) {

? autoUpdater.setFeedURL(feedUrl)

? await sleep(5000)

? //每次啟動(dòng)自動(dòng)更新檢查 更新版本 --可以根據(jù)自己方式更新、定時(shí)或者什么

? autoUpdater.checkForUpdates()

? autoUpdater.autoDownload = false

? // 當(dāng)更新發(fā)生錯(cuò)誤的時(shí)候觸發(fā)

? autoUpdater.on('error', function(error) {

? ? mainWindow.webContents.send(Events.checkUpdateError, JSON.stringify(error))

? })

? // 當(dāng)開始檢查更新的時(shí)候觸發(fā)

? autoUpdater.on('checking-for-update', function() {

? ? mainWindow.webContents.send(Events.checkingUpdate)

? ? // const { version } = info

? ? // askUpdate(version)

? })

? // 當(dāng)發(fā)現(xiàn)一個(gè)可用更新的時(shí)候觸發(fā)扣泊,更新包下載會(huì)自動(dòng)開始

? autoUpdater.on('update-available', function(info) {

? ? mainWindow.webContents.send(Events.updateAvailable, info)

? ? // logger.info('檢查到有更新近范,開始下載新版本')

? ? // logger.info(info)

? ? const { version } = info

? ? askUpdate(version)

? })

? // 當(dāng)沒(méi)有可用更新的時(shí)候觸發(fā)

? autoUpdater.on('update-not-available', function(info) {

? ? mainWindow.webContents.send(Events.updateNotAvailable, info)

? })

? // 更新下載進(jìn)度事件

? autoUpdater.on('download-progress', function(progressObj) {

? ? mainWindow.webContents.send(Events.updateDownloading, progressObj)

? })

? // 下載完成

? autoUpdater.on('update-downloaded', function() {

? ? // mainWindow.webContents.send(Events.updateDownloaded)

? ? // autoUpdater.quitAndInstall()

? ? // logger.info('下載完畢嘶摊!提示安裝更新')

? ? // logger.info(res)

? ? //dialog 想要使用,必須在BrowserWindow創(chuàng)建之后

? ? dialog

? ? ? .showMessageBox({

? ? ? ? title: '升級(jí)提示!',

? ? ? ? message: '已為您下載最新應(yīng)用剑辫,點(diǎn)擊確定馬上替換為最新版本摘昌!',

? ? ? })

? ? ? .then(() => {

? ? ? ? // logger.info('退出應(yīng)用,安裝開始虱颗!')

? ? ? ? //重啟應(yīng)用并在下載后安裝更新沥匈。 它只應(yīng)在發(fā)出 update-downloaded 后方可被調(diào)用。

? ? ? ? mainWindow.webContents.send(Events.updateDownloaded)

? ? ? ? autoUpdater.quitAndInstall()

? ? ? })

? })

}

async function askUpdate(version) {

? // logger.info(`最新版本 ${version}`)

? let { updater } = getLocalData()

? let { auto, version: ver, skip } = updater || {}

? // logger.info(

? //? JSON.stringify({

? //? ? ...updater,

? //? ? ver: ver,

? //? })

? // )

? if (skip && version === ver) return

? if (auto) {

? ? // 不再詢問(wèn) 直接下載更新

? ? autoUpdater.downloadUpdate()

? } else {

? ? const { response, checkboxChecked } = await dialog.showMessageBox({

? ? ? type: 'info',

? ? ? buttons: ['關(guān)閉', '跳過(guò)這個(gè)版本', '安裝更新'],

? ? ? title: '軟件更新提醒',

? ? ? message: `最新版本是 ${version}忘渔,您現(xiàn)在的版本是 ${app.getVersion()}高帖,現(xiàn)在要下載更新嗎?`,

? ? ? defaultId: 2,

? ? ? cancelId: -1,

? ? ? checkboxLabel: '以后自動(dòng)下載并安裝更新',

? ? ? checkboxChecked: false,

? ? ? textWidth: 300,

? ? })

? ? if ([1, 2].includes(response)) {

? ? ? let updaterData = {

? ? ? ? version: version,

? ? ? ? skip: response === 1,

? ? ? ? auto: checkboxChecked,

? ? ? }

? ? ? setLocalData({

? ? ? ? updater: {

? ? ? ? ? ...updaterData,

? ? ? ? },

? ? ? })

? ? ? if (response === 2) autoUpdater.downloadUpdate()

? ? ? // logger.info(['更新操作', JSON.stringify(updaterData)])

? ? } else {

? ? ? // logger.info(['更新操作', '關(guān)閉更新提醒'])

? ? }

? }

}

在background.js 里執(zhí)行監(jiān)聽

ackground.js 里執(zhí)行監(jiān)聽


每次更新時(shí)只需把exe文件和 latest.yml 文件放到服務(wù)器上就行了畦粮!

為了打包時(shí)生成latest.yml文件散址,須要在 build 參數(shù)中添加 publish 配置

八:自定義electron窗口導(dǎo)航欄

方法一:自定義electron窗口

1、在background.js文件中找到BrowserWindow中設(shè)置frame為false宣赔,關(guān)閉原生導(dǎo)航欄

background.js文件中找到BrowserWindow中設(shè)置frame為false

2预麸、在App.vue中引入窗口組件mainHeader.vue

App.vue中引入窗口組件mainHeader.vue

3、mainHeader.vue代碼如下

<template>

? <div id="app">

? ? <div class="titleBar">

? ? ? <div class="title">

? ? ? ? <div class="logo">

? ? ? ? ? <img src="@/assets/logo.png">

? ? ? ? </div>

? ? ? ? <div class="txt">窗口標(biāo)題</div>

? ? ? </div>

? ? <div class="windowTool">

? ? ? <div @click="minisize">

? ? ? ? <i class="iconfont iconminisize"></i>

? ? ? </div>

? ? ? <div v-if="!isMaxSize" @click="restore">

? ? ? ? <i class="iconfont iconrestore"></i>

? ? ? </div>

? ? ? <div v-else @click="maxsize">

? ? ? ? <i class="iconfont iconmaxsize"></i>

? ? ? </div>

? ? ? <div @click="close" class="close">

? ? ? ? <i class="iconfont iconclose"></i>

? ? ? </div>

? ? </div>

? ? </div>

? ? <div id="nav">

? ? ? <router-link to="/about">Home</router-link> |

? ? ? <router-link to="/about">About</router-link>

? ? </div>

? ? <router-view/>

? </div>

</template>

<script>

const {remote}=window.require('electron')

export default {

? data(){

? ? return{isMaxSize:true}

? },

? methods:{

//最小化

? ? minisize(){

? ? ? var win=remote.getCurrentWindow()

? ? ? win.minimize()

? ? },

//恢復(fù)

? ? restore(){

? ? remote.getCurrentWindow().restore()

? ? this.isMaxSize=!this.isMaxSize

? ? },

//最大化

? ? maxsize(){

? ? ? console.log(remote.getCurrentWindow())

? ? ? var win=remote.getCurrentWindow()

? ? ? win.maximize()

? ? ? this.isMaxSize=!this.isMaxSize

? ? },

//關(guān)閉

? ? close(){

? ? remote.getCurrentWindow().hide()

? ? }

? },

}

</script>

<style>

@import url(https://at.alicdn.com/t/font_1378132_s4e44adve5.css);

.titleBar{

? height:38px;

? line-height: 36px;

? background: #fff1f0;

? display: flex;

? border-bottom: 1px solid #f5222d;

}

.title{flex:1;

? ? ? display: flex;

? ? ? -webkit-app-region:drag;

}

.logo{padding-left:8px;

? ? ? padding-right:6px;

}

.logo img{

? width:20px;

? height:20px;

? margin-top:7px;

}

.txt{text-align: left;

? ? flex:1;

}

.close:hover{color: #fff;

? ? ? ? ? ? background-color:#ff4d4f;

}

.windowTool div{

? color:#888;

? height:100%;

? width:38px;

? display: inline-block;

? cursor:pointer;

}

i{font-size:12px;}

.windowTool div:hover{background: #ffccc7;}

body{margin:0;

? ? padding:0;

? ? overflow: hidden;

? ? height:100%;

? ? }

#app {

? font-family: Avenir, Helvetica, Arial, sans-serif;

? -webkit-font-smoothing: antialiased;

? -moz-osx-font-smoothing: grayscale;

? text-align: center;

? color: #2c3e50;

? display: flex;

? flex-direction: column;

}

#nav {

? padding: 30px;

}

#nav a {

? font-weight: bold;

? color: #2c3e50;

}

#nav a.router-link-exact-active {

? color: #42b983;

}

</style>

注意:使用上述代碼方法時(shí)需要注意在background.js文件中找到BrowserWindow將enableRemoteModule設(shè)置為true

enableRemoteModule設(shè)置為true

方法二:Electron自定義導(dǎo)航欄

1儒将、在主進(jìn)程background.js文件中配置frame: false? 關(guān)閉原生導(dǎo)航欄

配置frame: false? 關(guān)閉原生導(dǎo)航欄

2吏祸、在App.vue中引入窗口組件mainHeader.vue

App.vue中引入窗口組件mainHeader.vue

3、mainHeader.vue代碼如下

<template>

? ? <section class="MainHeader">

? ? ? ? <div style="display: flex;">

? ? ? ? ? ? <router-link :to="'/timetables'" class="logo noDrag" v-stat="{action:'logo'}"/>

? ? ? ? ? ? <div class="userInfo noDrag" v-if="userInfo">

? ? ? ? ? ? ? ? <div class="name " @click="path" v-stat="{action:'userInfo'}">

? ? ? ? ? ? ? ? ? ? <img src="~assets/images/user.png"/>

? ? ? ? ? ? ? ? ? ? <span>{{userInfo?userInfo.name:''}}</span>

? ? ? ? ? ? ? ? </div>

? ? ? ? ? ? ? ? <span class="logout" @click="logOut">退出</span>

? ? ? ? ? ? </div>

? ? ? ? </div>

? ? ? ? <div class="systemBtn">

? ? ? ? ? ? <i class="mini noDrag" title="最小化" @click="setWin('min')"></i>

? ? ? ? ? ? <i title="最大化" class="max noDrag" @click="setWin('max')"></i>

? ? ? ? ? ? <i title="關(guān)閉" class="close noDrag" @click="setWin('close')"></i>

? ? ? ? </div>

? ? </section>

</template>

<script>

/**渲染進(jìn)程(也就是當(dāng)前頁(yè)面)通過(guò)ipcRenderer.send 將方法字段名傳遞給主進(jìn)程钩蚊。**/

const {ipcRenderer} = window.require("electron");

? ? export default {

? ? ? ? methods: {

? ? ? ? ? ? setWin(type){

? ? ? ? ? ? ? ? ipcRenderer.send(type);

? ? ? ? ? ? }

? ? ? ? }

</script>

<style>

/**自定義的導(dǎo)航欄鼠標(biāo)點(diǎn)擊是無(wú)法拖動(dòng)的贡翘,需要在css中增加-webkit-app-region: drag; 讓鼠標(biāo)可以拖動(dòng)蹈矮,若可拖動(dòng)的html結(jié)構(gòu)中有點(diǎn)擊事件,那//需要在點(diǎn)擊元素的css中另加-webkit-app-region: no-drag; 讓其可觸發(fā)點(diǎn)擊事件鸣驱,若不加該css則點(diǎn)擊事件無(wú)效含滴。**/

.MainHeader {

? ? ? ? -webkit-app-region: drag;

? ? ? ? .noDrag{

? ? ? ? ? ? -webkit-app-region: no-drag;

? ? ? ?}

}

</style>

4、在主進(jìn)程background.js中執(zhí)行ipcMain方法丐巫。

import {BrowserWindow, ipcMain} from 'electron'

mainWindow = new BrowserWindow({

? ? ? ? height: 690,

? ? ? ? useContentSize: true,

? ? ? ? width: 1100,

? ? ? ? minWidth: 1100,

? ? ? ? minHeight: 690,

? ? ? ? frame: false

? ? })

ipcMain.on('min', () => mainWindow.minimize());

ipcMain.on('max', () => {

? ? if (mainWindow.isMaximized()) {

? ? ? ? mainWindow.restore();

? ? } else {

? ? ? ? mainWindow.maximize()

? ? }

});

ipcMain.on('close', () => mainWindow.close());

主進(jìn)程background.js文件中設(shè)置

九:自定義桌面應(yīng)用程序后谈况,瀏覽器端無(wú)法識(shí)別window,客戶端無(wú)法啟動(dòng),因此可以檢查代碼是否正在Electron或?yàn)g覽器中執(zhí)行递胧,來(lái)判斷是否引用window.require('electron')

檢查代碼是否正在Electron或?yàn)g覽器中執(zhí)行

export function isElectron() {

? ? // Renderer process

? ? if (typeof window !== 'undefined' && typeof window.process === 'object' && window.process.type === 'renderer') {

? ? ? ? return true;

? ? }

? ? // Main process

? ? if (typeof process !== 'undefined' && typeof process.versions === 'object' && !!process.versions.electron) {

? ? ? ? return true;

? ? }

? ? // Detect the user agent when the `nodeIntegration` option is set to true

? ? if (typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0) {

? ? ? ? return true;

? ? }

? ? return false;

}

在mainHeader組件中引入

import {isElectron} from '@/utils/isElectron'

if(isElectron()){//檢查代碼是否正在Electron或?yàn)g覽器中執(zhí)行? ? var {remote}=window.require('electron')? ? console.log("Electron中執(zhí)行 !");}else{? ? console.log("瀏覽器中執(zhí)行");}

如圖所示:

檢查代碼是否正在Electron或?yàn)g覽器中執(zhí)行

十:去掉導(dǎo)航欄菜單

需要去掉的導(dǎo)航欄菜單
主要代碼

十一:electron修改vue項(xiàng)目打包后的exe圖標(biāo)

注意:以下生成圖標(biāo)的地址和打包牡蠣都在dist_electron文件中

1碑韵、準(zhǔn)備一張icon.png圖片保存在public目錄下

2.安裝?electron-icon-builder

npm i electron-icon-builder --D

3、在package.json的scripts文件中添加一條命令并保存:

"electron:generate-icons": "electron-icon-builder --input=./public/icon.png --output=dist_electron --flatten"

3缎脾、執(zhí)行以下命令

npm run electron:generate-icons

就會(huì)在dist_electron文件夾中生成一系列打包所需的圖標(biāo)文件祝闻,如下:

4、在vue.config.json中pluginOptions對(duì)象下配置圖標(biāo)路徑遗菠,其中directories 為打包地址联喘,win為圖標(biāo)路徑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辙纬,一起剝皮案震驚了整個(gè)濱河市豁遭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贺拣,老刑警劉巖蓖谢,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異譬涡,居然都是意外死亡闪幽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門涡匀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)盯腌,“玉大人,你說(shuō)我怎么就攤上這事陨瘩⊥蠊唬” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵拾酝,是天一觀的道長(zhǎng)燕少。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蒿囤,這世上最難降的妖魔是什么客们? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上底挫,老公的妹妹穿的比我還像新娘恒傻。我一直安慰自己,他們只是感情好建邓,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布盈厘。 她就那樣靜靜地躺著,像睡著了一般官边。 火紅的嫁衣襯著肌膚如雪沸手。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天注簿,我揣著相機(jī)與錄音契吉,去河邊找鬼。 笑死诡渴,一個(gè)胖子當(dāng)著我的面吹牛捐晶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妄辩,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼惑灵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了眼耀?” 一聲冷哼從身側(cè)響起英支,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎畔塔,沒(méi)想到半個(gè)月后潭辈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸯屿,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澈吨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寄摆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谅辣。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖婶恼,靈堂內(nèi)的尸體忽然破棺而出桑阶,到底是詐尸還是另有隱情,我是刑警寧澤勾邦,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布蚣录,位于F島的核電站,受9級(jí)特大地震影響眷篇,放射性物質(zhì)發(fā)生泄漏萎河。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虐杯。 院中可真熱鬧玛歌,春花似錦、人聲如沸擎椰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)达舒。三九已至值朋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巩搏,已是汗流浹背吞歼。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留塔猾,地道東北人篙骡。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像丈甸,于是被迫代替她去往敵國(guó)和親糯俗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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