element-plus form表單的二次封裝

1. 首先谋作,我們需要在components新建一個(gè)文件夾CustomForm洲鸠,然后新建一個(gè)index.vue的文件
// element-plus form表單的二次封裝 自定義form表單
<template>
  <el-form :model="model" v-bind="_options" ref="formRef">
    <template v-for="(item, index) in fieldList" :key="index">
      <!-- 單選框 -->
      <el-form-item :label="item.label" v-if="item.type === 'radio'" :rules="item.rules" :prop="[item.field]">
        <el-radio-group v-model="model[item.field]" :disabled="item.disabled">
          <el-radio :label="val[item.options?.valueKey || 'value']" size="large" v-for="val in item.options?.data"
            :key="val[item.options?.valueKey || 'value']">
            {{ val[item.options?.labelkey || 'label'] }}
          </el-radio>
        </el-radio-group>
      </el-form-item>
      <!-- 復(fù)選框 -->
      <el-form-item :label="item.label" v-else-if="item.type === 'checkbox'" :rules="item.rules" :prop="[item.field]">
        <el-checkbox-group v-model="model[item.field]" :disabled="item.disabled">
          <el-checkbox v-for="c in item.options?.data" :key="c[item.options?.valueKey || 'value']"
            :label="c[item.options?.valueKey || 'value']">{{ c[item.options?.labelkey || 'label'] }}</el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <!-- 下拉框 -->
      <el-form-item :label="item.label" v-else-if="item.type === 'select'" :rules="item.rules" :prop="[item.field]">
        <el-select v-model="model[item.field]" :placeholder="item.options?.placeholder || '請(qǐng)選擇'" clearable>
          <el-option v-for="s in item.options?.data" :key="s[item.options?.valueKey || 'value']"
            :label="s[item.options?.labelkey || 'label']" :value="s[item.options?.valueKey || 'value']" />
        </el-select>
      </el-form-item>
      <!-- 默認(rèn)輸入框 -->
      <el-form-item :label="item.label" :rules="item.rules" :prop="[item.field]" v-else>
        <el-input v-model="model[item.field]" :readonly="item.readonly" :type="item.type ?? 'text'"
          :placeholder="item.label" :disabled="item.disabled" />
      </el-form-item>
    </template>
    <el-form-item>
      <slot name="buttons" :model="model" :formRef="formRef">
        <el-button type="primary" @click="onSubmit(formRef)">{{ _options.submitButtonText }}</el-button>
        <el-button v-if="_options.showResetButton" type="info" @click="resetForm(formRef)">
          {{ _options.resetButtonText }}
        </el-button>
        <el-button v-if="_options.showCancelButton" @click="emit('cancel')">
          {{ _options.cancelButtonText }}
        </el-button>
      </slot>
    </el-form-item>
  </el-form>
</template>
<script lang="ts" setup>
import type { FormInstance } from "element-plus";
import { ComputedRef, ref, computed } from "vue";
// 父組件傳遞的值
interface Props {
  fieldList: Form.FieldItem[];
  model?: Record<string, any>;
  options?: Form.Options;
}
// 表單的數(shù)據(jù)
const model = ref<Record<string, any>>({});
const formRef = ref<FormInstance>();
const props = defineProps<Props>();
// 設(shè)置option默認(rèn)值疯兼,如果傳入自定義的配置則合并option配置項(xiàng)
const _options: ComputedRef<Form.Options> = computed(() => {
  const option = {
    labelWidth: 120,
    labelPosition: "right",
    disabled: false,
    submitButtonText: "提交",
    resetButtonText: "重置",
    cancelButtonText: "取消",
    showResetButton: false,
    showCancelButton: false,
  };
  return Object.assign(option, props?.options);
});
interface EmitEvent {
  (e: "submit", params: any): void;
  (e: "reset"): void;
  (e: "cancel"): void;
}
const emit = defineEmits<EmitEvent>();
defineExpose({
  formRef,
});
// 根據(jù)fieldList初始化model乔遮, 如果model有傳值就用傳遞的model數(shù)據(jù)模型扮超,否則就給上面聲明的model設(shè)置相應(yīng)的(key,value) [item.field], item.value是表單的默認(rèn)值(選填)
props.fieldList.map((item: Form.FieldItem) => {
  // 如果類型為checkbox蹋肮,默認(rèn)值需要設(shè)置一個(gè)空數(shù)組
  const value = item.type === "checkbox" ? [] : "";
  props.model
    ? (model.value = props.model)
    : (model.value[item.field] = item.value || value);
});
// 提交按鈕
const onSubmit = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.validate((valid) => {
    if (valid) {
      emit("submit", model);
    } else {
      return false;
    }
  });
};
// 重置按鈕
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
};
</script>
<style lang="less" scoped></style>

寫完Form組件的代碼后出刷,會(huì)報(bào)紅線,F(xiàn)orm.XXXXX 找不到坯辩,這個(gè)是Form表單的全局類型聲明馁龟。

聲明文件在下方,直接復(fù)制進(jìn)項(xiàng)目中漆魔, 紅色警告自然消失坷檩。

聲明文件可以直接放在src下即可。(因?yàn)楹罄m(xù)我們項(xiàng)目可能需要二次封裝多個(gè)組件改抡,例如table, pagination, date-picker等矢炼,所以在此我們新建一個(gè)type文件夾,里面再創(chuàng)建各個(gè)組件的聲明文件)

// src/type/form/index.d.ts
declare namespace Form {
  type ItemType = 'password' | 'text' | 'textarea' | 'radio' | 'checkbox' | 'select'
  // 當(dāng)FiledItem的type === 'radio' | 'checkbox'時(shí)阿纤,options的參數(shù)類型
  interface IFieldOptions {
    labelkey?: string,
    valueKey?: string,
    placeholder?: string,
    data: Recode<string, any>[]
  }
  interface Options {
    labelWidth?: string | number,
    labelPosition?: 'left' | 'right' | 'top',
    disabled?: boolean,
    size?: 'large' | 'small' | 'default',
    showResetButton?: boolean, // 是否展示重置按鈕
    showCancelButton?: boolean, // 是否展示取消按鈕
    submitButtonText?: string,
    resetButtonText?: string,
    cancelButtonText?: string
  }
  interface FieldItem {
    label: string,
    field: string,
    type?: ItemType,
    value?: any,
    placeholder?: string,
    disabled?: boolean,
    readonly?: boolean,
    options?: IFieldOptions,
    rules?: RuleItem[]
  }
  interface RuleItem {
    type?: RuleType;
    required?: boolean;
    pattern?: RegExp | string;
    min?: number;
    max?: number;
    len?: number;
    enum?: Array<string | number | boolean | null | undefined>;
    whitespace?: boolean;
    fields?: Record<string, Rule>;
    options?: ValidateOption;
    defaultField?: Rule;
    transform?: (value: Value) => Value;
    message?: string | ((a?: string) => string);
    asyncValidator?: (rule: InternalRuleItem, value: Value, callback: (error?: string | Error) => void, source: Values, options: ValidateOption) => void | Promise<void>;
    validator?: (rule: InternalRuleItem, value: Value, callback: (error?: string | Error) => void, source: Values, options: ValidateOption) => SyncValidateResult | void;
    trigger?: 'blur' | 'change'
  }
}
2. 然后我們需要配置form的基本信息(基本表單信息句灌,驗(yàn)證規(guī)則,Options等)
// 自定義驗(yàn)證郵箱方法
const checkEmail = (rule: any, value: any, callback: any) => {
  if (!value) callback(new Error('Please input the email'))
  const regExp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(com|cn|net)$/
  regExp.test(value) ? callback() : callback(new Error('Please input the correct email address'))
}
// // 自定義驗(yàn)證表單配置數(shù)據(jù)
// export const validationFormFieldList = [
//     { label: '姓名', field: 'name', rules: [{ required: true, message: 'name is required' }] },
//     { label: '郵箱', field: 'email', rules: [{ required: true, validator: checkEmail }] },
// ] as Form.FieldItem[]

// 表單配置示例
export const exampleForm = {
  base: [
    { label: '姓名', field: 'name', disabled: false },
    { label: '性別', field: 'gender', type: 'radio', options: { data: [{ label: '男', value: 1 }, { label: '女', value: 0 }] } },
    {
      label: '愛(ài)好',
      field: 'hobbies', type: 'checkbox',
      options: {
        data: [
          { label: '吃飯', value: 1 },
          { label: '睡覺(jué)', value: 2 },
          { label: '寫代碼', value: 3 }
        ]
      }
    },
    {
      label: '工作', field: 'job', type: 'select',
      options: {
        data: [{ label: '吃飯', value: 1 }, { label: '睡覺(jué)', value: 2 }, { label: '寫代碼', value: 3 }]
      }
    },
    { label: '密碼', field: 'password', type: 'password', placeholder: '這是一個(gè)密碼輸入框' },
    { label: '只讀', field: 'readonly', readonly: true, placeholder: '這是一個(gè)只讀輸入框' },
    { label: '留言板', field: 'summary', type: 'textarea', placeholder: '留言板' },
  ],
  customkeyForm: [
    { label: '標(biāo)題', field: 'name' },
    { label: '性別', field: 'gender', type: 'radio', options: { labelkey: 'title', valueKey: 'val', data: [{ title: '男', val: 1 }, { title: '女', val: 0 }] } },
  ],
  ruleForm: [
    { label: '姓名', field: 'name', rules: [{ required: true, message: 'name is required' }] },
    { label: '郵箱', field: 'email', rules: [{ required: true, validator: checkEmail }] },
  ]
} as Record<string, Form.FieldItem[]>

export const Options = {
  // 自定義form1表單
  form1: {
    showResetButton: true,
    showCancelButton: false,
    resetButtonText: "重置1212",
  }
}

3. 接下來(lái)欠拾,我們就到了使用環(huán)節(jié)
// src/views/form/index.vue
<template>
    <el-card class="mb-5">
        <template #header> 基本表單 </template>
        <custom-form :fieldList="fieldList" :model="model" @submit="handleBaseSubmit">
            <!-- 如果不使用默認(rèn)的按鈕可以使用插槽自定義內(nèi)容胰锌, 插槽返回的model就是當(dāng)前表單的數(shù)據(jù) -->
            <!-- <template #buttons="{ model }">
                    <el-button">提交</el-button>
                </template> -->
        </custom-form>
    </el-card>
</template>
<script lang="ts" setup>
    import { exampleForm } from '@/config/form' 
    import { ref } from 'vue'
    // 本項(xiàng)目EasyForm組件自動(dòng)引入骗绕,如復(fù)制此代碼,需根據(jù)路徑引入Form組件后使用
    const fieldList: Form.FieldItem[] = exampleForm.base
    const model = ref<Record<string, any>>({
        name: '張三',
        gender: 1,
        hobbies: [1],
        job: 3,
        readonly: '只讀輸入框',
        summary: '尤雨溪懂個(gè)錘子vue是什么梗'
    })
    /**
     * 注意: model數(shù)據(jù)模型非必填項(xiàng)匕荸,如果僅僅是用于數(shù)據(jù)收集爹谭,model參數(shù)可以不用填枷邪,表單的submit事件會(huì)返回所有搜集的數(shù)據(jù)對(duì)象
     *       如果是編輯的情況下榛搔,頁(yè)面需要回顯數(shù)據(jù),則model數(shù)據(jù)模型必須要填寫
     */
    const handleBaseSubmit = (model: Record<string, any>) => {
        console.log(model.value)
    }
</script>
<style lang="less" scoped></style>

此時(shí)運(yùn)行項(xiàng)目东揣,我們可以得到的界面

基礎(chǔ)表單
image.png

自定義key

// src/views/form/index.vue
<template>
    <el-card class="mb-5">
        <template #header> 自定義key </template>
        <custom-form :fieldList="customKeyFieldList" :model="model2" />
    </el-card>
</template>
<script lang="ts" setup>
    import { exampleForm } from '@/config/form'
    import { ref } from 'vue'
    // import EasyForm from '@/components/EasyForm/index.vue'
    // 本項(xiàng)目EasyForm組件自動(dòng)引入践惑,如復(fù)制此代碼,需根據(jù)路徑引入Form組件后使用
    const customKeyFieldList: Form.FieldItem[] = exampleForm.customkeyForm
    const model2 = ref<Record<string, any>>({
        name: '自定義key',
        gender: 1
    })
    /**
     * 注意: 如果使用到checkbox嘶卧,radio尔觉,或者select等組件,需要傳入組件額外需要的數(shù)據(jù)芥吟,本組件默認(rèn)設(shè)定的讀取數(shù)據(jù)的字段是 label侦铜, value
     *       可參考下方聲明文件 FiledItem options的參數(shù)類型描述
     *       比如,當(dāng)前傳入的data數(shù)據(jù)字段名和label钟鸵、value不匹配钉稍,可使用預(yù)留的參數(shù) labelkey, valueKey指定字段名
     *         customkeyForm: [
                    { label: '標(biāo)題', field: 'name' },
                    { label: '性別', field: 'gender', type: 'radio', options: { labelkey: 'title', valueKey: 'val', data: [{ title: '男', val: 1 }, { title: '女', val: 0 }] } },
                ],
     */
    const handleBaseSubmit = (model: Record<string, any>) => {
        console.log(model.value)
    }
</script>
<style lang="less" scoped></style>

界面效果如下
image.png

自定義表單驗(yàn)證

// src/views/form/index.vue
<template>
    <el-card class="mb-5">
        <template #header> 自定義驗(yàn)證的表單 (使用slot自定義按鈕) </template>
        <custom-form :fieldList="ruleFieldList">
            <!-- 如果不使用默認(rèn)的按鈕可以使用插槽自定義內(nèi)容, 插槽返回的model就是當(dāng)前表單的數(shù)據(jù)棺耍, formRef是當(dāng)前表單的FormInstance -->
            <template #buttons="{ model, formRef }">
                <el-button @click="handleSubmit(model, formRef)">保存</el-button>
            </template>
        </custom-form>
    </el-card>
</template>
<script lang="ts" setup>
    import type { FormInstance } from 'element-plus'
    import { exampleForm } from '@/config/form' 
    // import EasyForm from '@/components/EasyForm/index.vue'
    // 本項(xiàng)目EasyForm組件自動(dòng)引入贡未,如復(fù)制此代碼,需根據(jù)路徑引入Form組件后使用
    const ruleFieldList: Form.FieldItem[] = exampleForm.ruleForm
    /**
     *  如果用到了表單驗(yàn)證蒙袍,又使用slot自定義按鈕的話俊卤,需要自行實(shí)現(xiàn)驗(yàn)證邏輯
     *  組件內(nèi)部已經(jīng)集成驗(yàn)證,及重置邏輯害幅。表單驗(yàn)證建議使用內(nèi)置的提交按鈕消恍。當(dāng)通過(guò)驗(yàn)證規(guī)則,內(nèi)置提交按鈕才會(huì)出發(fā)submit事件
     */
    // 下方是使用slot自定義按鈕以现,需要自己實(shí)現(xiàn)驗(yàn)證邏輯
    const handleSubmit = (model: any, formEl: FormInstance | undefined) => {
        if (!formEl) return
        formEl.validate((valid) => {
            if (valid) {
                console.log('submit!', model)
            } else {
                console.log('error submit!')
                return false
            }
        })
    }
</script>
<style lang="less" scoped></style>

頁(yè)面效果如下
image.png

4. 如果我們需要根據(jù)不同表單狠怨,展示不一樣的效果,我們可以通過(guò)options去設(shè)置

比如叼风,由于我們?cè)赾ustomForm中取董,默認(rèn)是不展示重置和取消按鈕的

// 改變這兩個(gè)值的屬性,可顯示隱藏按鈕
showResetButton: false,
showCancelButton: false,

從下面參數(shù)介紹无宿,我們可以看到options是一個(gè)對(duì)象茵汰,所以我們可以這樣寫

<template>
  <div class="home">
    <el-card class="mb-5">
      <template #header> 基本表單 </template>
      <custom-form :fieldList="ruleFieldList" :options="options" @submit="handleSubmit">
        <!-- 如果不使用默認(rèn)的按鈕可以使用插槽自定義內(nèi)容, 插槽返回的model就是當(dāng)前表單的數(shù)據(jù) -->
        <!-- <template #buttons="{ model, formRef }">
          <el-button @click="handleSubmit(model, formRef)">保存</el-button>
        </template> -->
      </custom-form>
    </el-card>
  </div>
</template>

<script lang="ts" setup>
import type { FormInstance } from "element-plus";
import { exampleForm, Options } from "@/config/form";
import { ref } from "vue";
// 本項(xiàng)目EasyForm組件自動(dòng)引入孽鸡,如復(fù)制此代碼蹂午,需根據(jù)路徑引入Form組件后使用
const options: Form.Options = Options.form1;
const ruleFieldList: Form.FieldItem[] = exampleForm.ruleForm;
console.log("options", options);
/**
 * 注意: model數(shù)據(jù)模型非必填項(xiàng)栏豺,如果僅僅是用于數(shù)據(jù)收集,model參數(shù)可以不用填豆胸,表單的submit事件會(huì)返回所有搜集的數(shù)據(jù)對(duì)象
 *       如果是編輯的情況下奥洼,頁(yè)面需要回顯數(shù)據(jù),則model數(shù)據(jù)模型必須要填寫
 */
const handleSubmit = (model: Record<string, any>) => {
  console.log(model.value)
}
</script>

頁(yè)面效果如下
image.png

參數(shù)介紹

Form 屬性

參數(shù) 說(shuō)明 類型 是否必填 默認(rèn)值
model 表單數(shù)據(jù)對(duì)象 Record<string, any>
options 自定義配置 object
fieldList formItem 配置數(shù)組 Array<object>

Options 配置項(xiàng)

參數(shù) 說(shuō)明 類型 是否必填 默認(rèn)值
labelWidth 標(biāo)簽的長(zhǎng)度晚胡,例如 ‘50px’灵奖。 作為 Form 直接子元素的 form-item 會(huì)繼承該值。 可以使用 auto估盘。 string / number
labelPosition 表單域標(biāo)簽的位置瓷患, 當(dāng)設(shè)置為 left 或 right 時(shí),則也需要設(shè)置 label-width 屬性‘left’ / ‘right’ / ‘top’ right
size 用于控制該表單內(nèi)組件的尺寸 large / default /small
disabled 是否禁用該表單內(nèi)的所有組件遣妥。 如果設(shè)置為 true, 它將覆蓋內(nèi)部組件的 disabled 屬性擅编。 boolean false
submitButtonText 提交按鈕默認(rèn)顯示的文本內(nèi)容 string 提交
resetButtonText 重置按鈕默認(rèn)顯示的文本內(nèi)容 string 重置
cancelButtonText 取消按鈕默認(rèn)顯示的文本內(nèi)容 string 取消
showResetButton 是否顯示重置按鈕 boolean
showCancelButton 是否顯示取消按鈕 boolean

fieldItem 配置項(xiàng)

參數(shù) 說(shuō)明 類型 是否必填 默認(rèn)值
field model 的鍵名 string
label 標(biāo)簽文本 string
type 當(dāng)前 fieldItem 的類型 ‘password’ / ‘text’ / ‘textarea’ / ‘radio’ / ‘checkbox’ / ‘select’ text
value 默認(rèn)顯示的值 any
placeholder 輸入框占位文本 string
disabled 是否禁用 boolean false
options 如果 type=‘checkbox’ / ‘radio’ / 'select’時(shí),需傳入此配置項(xiàng)箫踩。格式參考 fieldItem options 配置項(xiàng) object -
rules 表單驗(yàn)證規(guī)則爱态。格式參考element-plus form 表單 或者參數(shù)類型聲明 Array<RuleItem> -

fieldItem options 配置項(xiàng)

參數(shù) 說(shuō)明 類型 是否必填 默認(rèn)值
labelkey label 自定義字段名 string label
value value 自定義字段名 string value
placeholder 當(dāng) fieldItem type= 'select’時(shí),選擇框的提示語(yǔ) string -
data type=‘checkbox’ / ‘radio’ / 'select’時(shí), 需要的數(shù)據(jù) Array<object> -

Form 插槽

插槽名 說(shuō)明 插槽作用域
buttons 自定義按鈕區(qū)域的內(nèi)容 { model, formRef }

Form 事件

事件名 說(shuō)明 回調(diào)參數(shù)
submit 點(diǎn)擊默認(rèn)的提交按鈕觸發(fā) model
cancel 點(diǎn)擊取消按鈕觸發(fā) -
reset 重置該表單項(xiàng)境钟,將其值重置為初始值锦担,并移除校驗(yàn)結(jié)果 -
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吱韭,隨后出現(xiàn)的幾起案子吆豹,更是在濱河造成了極大的恐慌,老刑警劉巖理盆,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痘煤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡猿规,警方通過(guò)查閱死者的電腦和手機(jī)衷快,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)姨俩,“玉大人蘸拔,你說(shuō)我怎么就攤上這事』房” “怎么了调窍?”我有些...
    開(kāi)封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)张遭。 經(jīng)常有香客問(wèn)我邓萨,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任缔恳,我火速辦了婚禮宝剖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歉甚。我一直安慰自己万细,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布纸泄。 她就那樣靜靜地躺著赖钞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刃滓。 梳的紋絲不亂的頭發(fā)上仁烹,一...
    開(kāi)封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天耸弄,我揣著相機(jī)與錄音咧虎,去河邊找鬼。 笑死计呈,一個(gè)胖子當(dāng)著我的面吹牛砰诵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捌显,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼茁彭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了扶歪?” 一聲冷哼從身側(cè)響起理肺,我...
    開(kāi)封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎善镰,沒(méi)想到半個(gè)月后妹萨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炫欺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年乎完,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片品洛。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡树姨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出桥状,到底是詐尸還是另有隱情帽揪,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布辅斟,位于F島的核電站转晰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜挽霉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一防嗡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧侠坎,春花似錦蚁趁、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至庐完,卻和暖如春钢属,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背门躯。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工淆党, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人讶凉。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓染乌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親懂讯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子荷憋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

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