Vue2 element-ui 框架中集成國際化 vue-i18n 并封裝成可切換語言的組件

在 Vue 2 中配置國際化总寒,您可以使用 Vue I18n 插件扶歪。Vue I18n 是 Vue.js 官方推薦的國際化插件,它可以幫助您輕松地實現(xiàn)多語言支持摄闸。

安裝 vue-i18n

項目根目錄下打開終端或命令行工具善镰,運行以下命令來安裝相關依賴包:

npm install vue-i18n@8.27.1 --save

使用

1. 在 src/components 目錄中新增一個名為 i18n 的目錄,并添加以下3個文件:

src/components/i18n/locales/en/index.js 英語語言包:

export default {
  'Language': 'English'
}

src/components/i18n/locales/zh-CN/index.js 中文語言包:

export default {
  'Language': '中文'
}

src/components/i18n/index.js 語言包入口文件:

import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)

// 各個國家的key
const localeKeys = ['en', 'zh-CN']

// 各個國家語言包
const messages = {}
for (const key of localeKeys) {
  messages[key] = require(`./locales/${key}/index.js`).default
}

export default new VueI18n({
  locale: 'en',
  messages,
  silentTranslationWarn: true // 忽略翻譯警告
})
2. 打開 src/main.js 文件,掛載到Vue實例:
import i18n from './components/i18n'

new Vue({
  i18n
})

修改后的代碼如下:

import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import App from './App.vue'
import router from './router'
import store from './store'
import i18n from './components/i18n'
import '@css/index.less'

// 禁用生產(chǎn)環(huán)境提示
Vue.config.productionTip = false

// Element掛載到Vue
Vue.$message = Element.Message
Vue.use(Element)

new Vue({
  router,
  store,
  i18n,
  render: (h) => h(App)
}).$mount('#app')
3. 在頁面年枕、js代碼中使用:

一旦將 VueI18n 實例掛載到 Vue 實例上炫欺,在 Vue 組件中直接使用 $t 方法,可以通過指定鍵(key)來獲取對應語言的翻譯文本熏兄。這個鍵可以是簡單的字符串品洛,也可以是一個對象,用于支持更復雜的翻譯需求摩桶。

以下是使用 $t 方法獲取翻譯文本的示例:

<template>
  <div>
    <p>{{ $t('Language') }}</p>
  </div>
</template>

<script>
export default {
  mounted() {
    console.log(this.$t('Language'))
  }
}
</script>

Element 語言包

完成上述步驟后桥状,我們在使用 Element 組件時可能會遇到一個問題:雖然我們成功切換了自定義的語言,在應用中自定義的文本已經(jīng)被正確翻譯典格,但是 Element UI 組件的顯示內(nèi)容并沒有隨之切換岛宦。

這是因為 Element UI 組件庫本身并不直接集成 vue-i18n 插件台丛,因此它并不會自動根據(jù)我們設置的語言環(huán)境來翻譯組件的顯示文本耍缴。

解決這個問題的辦法是,我們需要手動為 Element UI 組件進行國際化配置和翻譯挽霉。

以下是解決方案的基本步驟:

1. 創(chuàng)建 Element 語言包文件

src/components/i18n 目錄下添加一個名為 element 的目錄防嗡,并在目錄中添加以下兩個文件:

en.js

// 英語
exports.default = {
  el: {
    colorpicker: {
      confirm: 'OK',
      clear: 'Clear'
    },
    datepicker: {
      now: 'Now',
      today: 'Today',
      cancel: 'Cancel',
      clear: 'Clear',
      confirm: 'OK',
      selectDate: 'Select date',
      selectTime: 'Select time',
      startDate: 'Start Date',
      startTime: 'Start Time',
      endDate: 'End Date',
      endTime: 'End Time',
      prevYear: 'Previous Year',
      nextYear: 'Next Year',
      prevMonth: 'Previous Month',
      nextMonth: 'Next Month',
      year: '',
      month1: 'January',
      month2: 'February',
      month3: 'March',
      month4: 'April',
      month5: 'May',
      month6: 'June',
      month7: 'July',
      month8: 'August',
      month9: 'September',
      month10: 'October',
      month11: 'November',
      month12: 'December',
      week: 'week',
      weeks: {
        sun: 'Sun',
        mon: 'Mon',
        tue: 'Tue',
        wed: 'Wed',
        thu: 'Thu',
        fri: 'Fri',
        sat: 'Sat'
      },
      months: {
        jan: 'Jan',
        feb: 'Feb',
        mar: 'Mar',
        apr: 'Apr',
        may: 'May',
        jun: 'Jun',
        jul: 'Jul',
        aug: 'Aug',
        sep: 'Sep',
        oct: 'Oct',
        nov: 'Nov',
        dec: 'Dec'
      }
    },
    select: {
      loading: 'Loading',
      noMatch: 'No matching data',
      noData: 'No data',
      placeholder: 'Select'
    },
    cascader: {
      noMatch: 'No matching data',
      loading: 'Loading',
      placeholder: 'Select',
      noData: 'No data'
    },
    pagination: {
      goto: 'Go to',
      pagesize: '/page',
      total: 'Total {total}',
      pageClassifier: ''
    },
    messagebox: {
      title: 'Message',
      confirm: 'OK',
      cancel: 'Cancel',
      error: 'Illegal input'
    },
    upload: {
      deleteTip: 'press delete to remove',
      delete: 'Delete',
      preview: 'Preview',
      continue: 'Continue'
    },
    table: {
      emptyText: 'No Data',
      confirmFilter: 'Confirm',
      resetFilter: 'Reset',
      clearFilter: 'All',
      sumText: 'Sum'
    },
    tree: {
      emptyText: 'No Data'
    },
    transfer: {
      noMatch: 'No matching data',
      noData: 'No data',
      titles: ['List 1', 'List 2'], // to be translated
      filterPlaceholder: 'Enter keyword', // to be translated
      noCheckedFormat: '{total} items', // to be translated
      hasCheckedFormat: '{checked}/{total} checked' // to be translated
    },
    image: {
      error: 'FAILED'
    },
    pageHeader: {
      title: 'Back' // to be translated
    },
    popconfirm: {
      confirmButtonText: 'Yes',
      cancelButtonText: 'No'
    },
    empty: {
      description: 'No Data'
    }
  }
}

zh-CN.js

// 中文
exports.default = {
  el: {
    colorpicker: {
      confirm: '確定',
      clear: '清空'
    },
    datepicker: {
      now: '此刻',
      today: '今天',
      cancel: '取消',
      clear: '清空',
      confirm: '確定',
      selectDate: '選擇日期',
      selectTime: '選擇時間',
      startDate: '開始日期',
      startTime: '開始時間',
      endDate: '結(jié)束日期',
      endTime: '結(jié)束時間',
      prevYear: '前一年',
      nextYear: '后一年',
      prevMonth: '上個月',
      nextMonth: '下個月',
      year: '年',
      month1: '1 月',
      month2: '2 月',
      month3: '3 月',
      month4: '4 月',
      month5: '5 月',
      month6: '6 月',
      month7: '7 月',
      month8: '8 月',
      month9: '9 月',
      month10: '10 月',
      month11: '11 月',
      month12: '12 月',
      // week: '周次',
      weeks: {
        sun: '日',
        mon: '一',
        tue: '二',
        wed: '三',
        thu: '四',
        fri: '五',
        sat: '六'
      },
      months: {
        jan: '一月',
        feb: '二月',
        mar: '三月',
        apr: '四月',
        may: '五月',
        jun: '六月',
        jul: '七月',
        aug: '八月',
        sep: '九月',
        oct: '十月',
        nov: '十一月',
        dec: '十二月'
      }
    },
    select: {
      loading: '加載中',
      noMatch: '無匹配數(shù)據(jù)',
      noData: '無數(shù)據(jù)',
      placeholder: '請選擇'
    },
    cascader: {
      noMatch: '無匹配數(shù)據(jù)',
      loading: '加載中',
      placeholder: '請選擇',
      noData: '暫無數(shù)據(jù)'
    },
    pagination: {
      goto: '前往',
      pagesize: '條/頁',
      total: '共 {total} 條',
      pageClassifier: '頁'
    },
    messagebox: {
      title: '提示',
      confirm: '確定',
      cancel: '取消',
      error: '輸入的數(shù)據(jù)不合法!'
    },
    upload: {
      deleteTip: '按 delete 鍵可刪除',
      delete: '刪除',
      preview: '查看圖片',
      continue: '繼續(xù)上傳'
    },
    table: {
      emptyText: '暫無數(shù)據(jù)',
      confirmFilter: '篩選',
      resetFilter: '重置',
      clearFilter: '全部',
      sumText: '合計'
    },
    tree: {
      emptyText: '暫無數(shù)據(jù)'
    },
    transfer: {
      noMatch: '無匹配數(shù)據(jù)',
      noData: '無數(shù)據(jù)',
      titles: ['列表 1', '列表 2'],
      filterPlaceholder: '請輸入搜索內(nèi)容',
      noCheckedFormat: '共 {total} 項',
      hasCheckedFormat: '已選 {checked}/{total} 項'
    },
    image: {
      error: '加載失敗'
    },
    pageHeader: {
      title: '返回'
    },
    popconfirm: {
      confirmButtonText: '確定',
      cancelButtonText: '取消'
    },
    empty: {
      description: '暫無數(shù)據(jù)'
    }
  }
}

以上兩個文件來源于 Element官方。在當前項目中侠坎,將Element語言包放到本地的目的是為了便于后期對語言包進行修改拓展蚁趁。

如果不想在本地創(chuàng)建這兩個文件,也可以通過引入的方式直接獲取到對應的文件实胸,例如:import elementLang from 'element-ui/src/locale/lang/en'他嫡。

2. 在語言包入口文件引入 Element 語言包

src/components/i18n/index.js 文件中找到以下代碼塊:

// 各個國家語言包
const messages = {}
for (const key of localeKeys) {
  messages[key] = require(`./locales/${key}/index.js`).default
}

將其修改為:

// 各個國家語言包
const messages = {}
for (const key of localeKeys) {
  const langObj = require(`./locales/${key}/index.js`).default
  const langElement = require(`./element/${key}`)
  messages[key] = {
    ...langObj,
    ...langElement ? langElement.default : {}
  }
}

修改后的代碼如下:

import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)

// 各個國家的key
const localeKeys = ['en', 'zh-CN']

// 各個國家語言包
const messages = {}
for (const key of localeKeys) {
  const langObj = require(`./locales/${key}/index.js`).default
  const langElement = require(`./element/${key}`)
  messages[key] = {
    ...langObj,
    ...langElement ? langElement.default : {}
  }
}

export default new VueI18n({
  locale: 'en',
  messages,
  silentTranslationWarn: true // 忽略翻譯警告
})

通過這種方式番官,Element語言包與我們自定義的語言包便合并在一起了。

3. 掛載 Element 到 Vue 實例中時將語言包注入

src/main.js 中找到以下代碼塊

Vue.use(Element)

將其修改為:

Vue.use(Element, {
  i18n: (key, value) => i18n.t(key, value)
})

修改后的代碼如下:

import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import App from './App.vue'
import router from './router'
import store from './store'
import i18n from './components/i18n'
import '@css/index.less'

// 禁用生產(chǎn)環(huán)境提示
Vue.config.productionTip = false

// Element掛載到Vue
Vue.$message = Element.Message
Vue.use(Element, {
  i18n: (key, value) => i18n.t(key, value)
})

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

完成后 Element 相關組件就能正常的顯示翻譯后的內(nèi)容了钢属。

切換組件的封裝

在我們的UI組件中徘熔,我們使用了 Element 中的下拉菜單組件。如果想了解更多關于下拉菜單組件的用法淆党,請訪問 Dropdown下拉菜單文檔地址 查看詳細文檔內(nèi)容酷师。

新建組件文件

src/components/i18n目錄中,新建一個名為change-language.vue 的文件染乌,并添加以下內(nèi)容:

<template>
  <el-dropdown @command="handle">
    <span class="el-dropdown-link">
      {{$t('Language')}}<i class="el-icon-caret-bottom el-icon--right"></i>
    </span>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item v-for="(item, index) of list" :key="index" :command="item.key">{{item.name}}</el-dropdown-item>
    </el-dropdown-menu>
  </el-dropdown>
</template>

<script>
export default {
  name: 'change-language',
  data() {
    return {
      list: [
        { key: 'en', name: 'English' }, // 英語
        { key: 'zh-CN', name: '中文' } // 中文
      ]
    }
  },
  methods: {
    handle(value) {
    }
  }
}
</script>
<style scoped lang="less">
</style>

然后山孔,我們可以找一個Vue文件,在其中使用這個組件進行觀察荷憋。使用方式如下(以Vue單文件組件為例):

  • 引入組件
import ChangeLanguage from '@/components/i18n/change-language'
  • 注冊組件
components: {
  ChangeLanguage
}
  • 使用
<ChangeLanguage />

這樣一個基本的語言包下拉單組件樣式就完成了台颠,之后還需要對組件進行功能上的開發(fā)。

切換語言

在組件handle函數(shù)代碼中添加代碼台谊,如下:

handle(value) {
  this.$i18n.locale = value
}

通過將value賦給this.$i18n.locale蓉媳,我們可以動態(tài)地切換當前語言為下拉菜單中所選中的語言。

現(xiàn)在雖然基本的切換功能已經(jīng)完成锅铅,但是當我們在網(wǎng)頁中切換語言包并刷新頁面后酪呻,之前選擇的語言包不會被保留,而是重新加載頁面時返回到默認的語言包盐须。這是因為在刷新頁面時玩荠,瀏覽器會重新加載整個應用程序,并重置Vue實例的狀態(tài)贼邓,包括設置的語言包阶冈。這時候我們就需要做切換數(shù)據(jù)的持久化處理,來保證我們切換后的內(nèi)容顯示不會出錯塑径。

數(shù)據(jù)持久化

數(shù)據(jù)持久化的方式有很多種女坑,這里我們采用了瀏覽器的本地存儲 LocalStorage 來實現(xiàn)。

在組件handle函數(shù)代碼中添加代碼统舀,如下:

handle(value) {
  this.$i18n.locale = value
  localStorage.setItem('change-language', value)
}

找到 src/components/i18n/index.js 文件中以下代碼塊:

export default new VueI18n({
  locale: 'en',
  messages,
  silentTranslationWarn: true // 忽略翻譯警告
})

將其中 locale 寫死的值 'en' 改為 localStorage 獲取的值匆骗,如下:

export default new VueI18n({
  locale: localStorage.getItem('change-language') || 'zh-CN',
  messages,
  silentTranslationWarn: true // 忽略翻譯警告
})

上述代碼中,語言包的key值會先從本地存儲中獲取誉简,如果獲取不到則設置為默認值'zh-CN'碉就。

這樣,我們切換語言包再刷新頁面后闷串,仍然可以正確地顯示之前選擇的語言包瓮钥。

后端語言包

在一般情況下,僅僅使用前端的語言包是無法涵蓋整個系統(tǒng)的翻譯需求的。例如碉熄,后端接口返回的菜單桨武、下拉列表的數(shù)據(jù)等。針對這種情況锈津,我們可以采取一種方案玻募,即在切換語言后調(diào)用location.reload()方法刷新頁面以重新獲取后端的翻譯數(shù)據(jù)。

使用這種方案時一姿,我們需要與后端約定好國際化的翻譯key的格式七咧,并在語言切換時通過前端與后端接口進行數(shù)據(jù)交互。前端可以將當前選擇的語言作為參數(shù)傳遞給后端叮叹,后端將返回相應語言的翻譯數(shù)據(jù)艾栋。然后在前端刷新頁面時,通過重新加載頁面來獲取更新后的翻譯內(nèi)容蛉顽。

請注意蝗砾,使用location.reload()方法會導致整個頁面重新加載,這可能會對用戶的體驗產(chǎn)生一定影響携冤,特別是在數(shù)據(jù)量較大或網(wǎng)絡較慢的情況下悼粮。因此,在實施這種方案之前曾棕,請確保綜合考慮用戶體驗和性能方面的因素扣猫。

總結(jié)來說,為了在整個系統(tǒng)中實現(xiàn)翻譯需求翘地,我們可以通過與后端接口協(xié)作申尤,傳遞語言選擇,并在需要時重新加載頁面來獲取最新的翻譯內(nèi)容衙耕。這樣就能夠在前后端協(xié)同工作下昧穿,正確顯示經(jīng)過翻譯的內(nèi)容。

在組件handle函數(shù)中添加 location.reload()

handle(value) {
  this.$i18n.locale = value
  localStorage.setItem('change-language', value)
  location.reload()
}
小小的優(yōu)化一下

上述步驟完成橙喘,我們的組件整體功能就已經(jīng)開發(fā)完畢了时鸵,但是代碼中有一部部分內(nèi)容可以復用簡化。

組件代碼中的以下部分:

list: [
  { key: 'en', name: 'English' }, // 英語
  { key: 'zh-CN', name: '中文' } // 中文
]

src/components/i18n/index.js 代碼中的以下部分:

// 各個國家的key
const localeKeys = ['en', 'zh-CN']

以上兩部分代碼對比厅瞎,就能夠發(fā)現(xiàn)他們有兩個相同點:都是數(shù)組饰潜、內(nèi)容中都有一樣的值。

這樣我們就能將組件代碼中的內(nèi)容移動到 src/components/i18n/index.js 文件中磁奖,避免后期維護需要新增國家時囊拜,還要同時維護兩個文件的列表了某筐。

根據(jù)以下步驟進行優(yōu)化:

  1. 找到 src/components/i18n/index.js 文件中以下內(nèi)容:
// 各個國家的key
const localeKeys = ['en', 'zh-CN']

// 各個國家語言包
const messages = {}
for (const key of localeKeys) {
  const langObj = require(`./locales/${key}/index.js`).default
  const langElement = require(`./element/${key}`)
  messages[key] = {
    ...langObj,
    ...langElement ? langElement.default : {}
  }
}
  1. 將其修改為:
// 各個國家的key
export const localeKeys = [
  { key: 'en', name: 'English' }, // 英語
  { key: 'zh-CN', name: '中文' } // 中文
]

// 各個國家語言包
const messages = {}
for (const item of localeKeys) {
  const key = item.key
  const langObj = require(`./locales/${key}/index.js`).default
  const langElement = require(`./element/${key}`)
  messages[key] = {
    ...langObj,
    ...langElement ? langElement.default : {}
  }
}
  1. 在組件中引入 src/components/i18n/index.js 文件中的 localeKeys
import { localeKeys } from './index'
  1. localeKeys賦值給 list
return {
  list: localeKeys
}

這樣比搭,這個小小的優(yōu)化就完成了。

完整代碼

src/components/i18n/change-language.vue 組件代碼:

<!--
@Descripttion 國際化語言切換
@version 1.0.0
@Author Bell
@ 使用
  引入組件
    import ChangeLanguage from '@/components/i18n/change-language'
  注冊組件
    components: {
      ChangeLanguage
    }
  使用
    <ChangeLanguage />
 -->
<template>
  <el-dropdown @command="handle">
    <span class="el-dropdown-link">
      {{$t('Language')}}<i class="el-icon-caret-bottom el-icon--right"></i>
    </span>
    <el-dropdown-menu slot="dropdown">
      <el-dropdown-item v-for="(item, index) of list" :key="index" :command="item.key">{{item.name}}</el-dropdown-item>
    </el-dropdown-menu>
  </el-dropdown>
</template>

<script>
import { localeKeys } from './index'

export default {
  name: 'change-language',
  data() {
    return {
      list: localeKeys
    }
  },
  methods: {
    handle(value) {
      this.$i18n.locale = value
      localStorage.setItem('change-language', value)
      location.reload()
    }
  }
}
</script>
<style scoped lang="less">
</style>

src/components/i18n/index.js 國際化入口文件:

import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)

// 各個國家的key
export const localeKeys = [
  { key: 'en', name: 'English' }, // 英語
  { key: 'zh-CN', name: '中文' } // 中文
]

// 各個國家語言包
const messages = {}
for (const item of localeKeys) {
  const key = item.key
  const langObj = require(`./locales/${key}/index.js`).default
  const langElement = require(`./element/${key}`)
  messages[key] = {
    ...langObj,
    ...langElement ? langElement.default : {}
  }
}

export default new VueI18n({
  locale: localStorage.getItem('change-language') || 'zh-CN',
  messages,
  silentTranslationWarn: true // 忽略翻譯警告
})



框架搭建整體流程

點擊下載步驟 1-7 配置完成的完整 Demo



本框架更多功能 Demo 下載

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末身诺,一起剝皮案震驚了整個濱河市蜜托,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霉赡,老刑警劉巖橄务,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異穴亏,居然都是意外死亡蜂挪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門嗓化,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棠涮,“玉大人,你說我怎么就攤上這事刺覆⊙戏荆” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵谦屑,是天一觀的道長驳糯。 經(jīng)常有香客問我,道長氢橙,這世上最難降的妖魔是什么酝枢? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮悍手,結(jié)果婚禮上隧枫,老公的妹妹穿的比我還像新娘。我一直安慰自己谓苟,他們只是感情好官脓,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著涝焙,像睡著了一般卑笨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仑撞,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天赤兴,我揣著相機與錄音,去河邊找鬼隧哮。 笑死桶良,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的沮翔。 我是一名探鬼主播陨帆,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了疲牵?” 一聲冷哼從身側(cè)響起承二,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纲爸,沒想到半個月后亥鸠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡识啦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年负蚊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颓哮。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡盖桥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出题翻,到底是詐尸還是另有隱情揩徊,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布嵌赠,位于F島的核電站塑荒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏姜挺。R本人自食惡果不足惜齿税,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炊豪。 院中可真熱鬧凌箕,春花似錦、人聲如沸词渤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缺虐。三九已至芜壁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間高氮,已是汗流浹背慧妄。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剪芍,地道東北人塞淹。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像罪裹,于是被迫代替她去往敵國和親饱普。 傳聞我的和親對象是個殘疾皇子运挫,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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