Angular學(xué)習(xí)(01)-架構(gòu)概覽

聲明

本系列文章內(nèi)容梳理自以下來源:

官方的教程,其實已經(jīng)很詳細且易懂,這里再次梳理的目的在于復(fù)習(xí)和鞏固相關(guān)知識點,剛開始接觸學(xué)習(xí) Angular 的還是建議以官網(wǎng)為主。

因為這系列文章,更多的會帶有我個人的一些理解和解讀,由于目前我也才剛開始接觸 Angular 不久,在該階段的一些理解并不一定是正確的,擔(dān)心會有所誤導(dǎo),所以還是以官網(wǎng)為主。

正文- 架構(gòu)概覽

接觸 Angular 大概一個月吧,期間寫了個項目,趁現(xiàn)在稍微有點時間,來回顧梳理一下。

其實,如果前端網(wǎng)站并不是特別復(fù)雜,那么使用 Angular 無非也就是常跟幾個重要的知識點打交道,在官網(wǎng)的核心知識的第一節(jié)中就將這些知識點羅列出來了,也就是:架構(gòu)概覽。

Angular架構(gòu)概覽.png

畫了這個圖來大概表示下 Angular 的架構(gòu)概覽,基本涉及到一些常見的重要的知識點了,比如:

  • 模塊
  • 路由
  • 組件
  • 模板
  • 服務(wù)
  • 指令
  • 管道

不同的類型,文件名通常會都按照一定的規(guī)范來命名,以便直接看出該文件的角色。

當(dāng)然,文件命名只是給開發(fā)人員來方便維護、辨別,對于 Angular 來說,這些都是一份份的 ts 文件代碼,所以,都需要在相對應(yīng)的文件中加上一些裝飾器比如:@Directive,@Pipe,@Component,@NgModel 等這些,才能夠讓 Angular 識別出該文件的角色、用途。

基本上,用 Angular 做一個簡單的前端項目,就是跟上面這些打交道,理清它們各自的用途及用法,還有之間的聯(lián)系,基本上,就可以上手進行一些開發(fā)了。

當(dāng)然,像在 Service 服務(wù)中,還會有異步編程、HttpClient 網(wǎng)絡(luò)編程的相關(guān)知識點;

在 Component 組件中,也還會有表單、動畫相關(guān)的編程知識點,這些都是需要進一步去深入學(xué)習(xí)研究,但從總體架構(gòu)上來看,就是要先了解以上這些知識點了。

模塊

一個 Angular 項目,至少會有一個模塊,即最少都會有一份用 @NgModel 聲明的 ts 文件,表明該文件作為模塊角色,來管理其他角色。

其他角色包括:組件、指令、管道、服務(wù)等等,這些角色必須在模塊文件中聲明了,才能夠被該模塊內(nèi)的其他角色所使用,而且同一個組件、指令、管道不允許同時在多個模塊中進行聲明,只能通過模塊 exports 給其他模塊使用。

Angular 里的模塊,并不等同于 Android 項目中的模塊概念。

在 Android 項目代碼中,可能我們會根據(jù)功能來進行模塊的劃分,但這個模塊僅僅是抽象上的概念,也就是建個包,把代碼都集中管理。

而 Angular 里的模塊,不僅可以在項目結(jié)構(gòu)上集中管理同一個模塊的代碼文件,還可以為模塊內(nèi)的代碼提供一個運行的上下文。

意思就是說,不同模塊在運行期間互不影響,就好像各自運行在各自的沙箱容器中一樣。舉個簡單的例子,在不同模塊中聲明相同的變量名,或相同的 css 的類選擇器,它們之間并不會起沖突。

當(dāng)然,模塊之間可以有交互,模塊可以依賴于另一模塊,模塊內(nèi)的可以共享資源等等,所以,NgModel 中有許多需要配置的聲明項,比如:

  • declarations:聲明屬于本模塊內(nèi)的組件、指令、管道
  • providers:聲明屬于本模塊內(nèi)的服務(wù)
  • imports:聲明本模塊所引用的其他模塊,通常是 imports 其他模塊在 exports 中聲明的項
  • exports:聲明本模塊對外公開的組件、指令、管道等,在這里公開的項才可以被其他模塊所使用
  • bootstrap:只有根模塊才需要配置,用來設(shè)置應(yīng)用主視圖,Angular 應(yīng)用啟動后,這里就是入口,類似于 Android 中的入口 Activity
  • 還有其他一些可選配置,比如應(yīng)用主題,或者動態(tài)的組件聲明等等

在 Angular 中,大多數(shù)的模式就是,一個根模塊管理著很多功能模塊,然后,每個模塊管理自己模塊內(nèi)部所使用到的組件、指令、管道、服務(wù)、或者需要依賴于其他模塊,如果該模塊內(nèi)部的這些角色,有些可以供其他模塊使用,那么就需要對外暴露。

路由

一個項目這么多模塊,Angular 并不會一開始就把所有模塊都加載,而是惰性加載,按需加載。

那么,什么時候會去加載呢?

就是等某個模塊內(nèi)部的組件被使用的時候會加載,而組件是什么時候會被使用的呢?

有兩個時機,一是組件被直接調(diào)用;二是觸發(fā)了路由去加載;

路由通常的配置方式是用一個 @NgModel 聲明的模塊,但只用其中兩項配置:imports 和 exports,imports 用來導(dǎo)入當(dāng)前模塊所有組件與 url 的映射表,而 exports 用來將這些映射表信息暴露,以供相對應(yīng)的模塊去引入使用。

當(dāng)然,你不想抽離路由配置,直接將其配置在對應(yīng)模塊的 imports 內(nèi)也可以,抽離的話,相對獨立,可維護。

區(qū)別于傳統(tǒng)的前端網(wǎng)頁的跳轉(zhuǎn)方式,Angular 項目是一個單頁應(yīng)用,所謂的單頁應(yīng)用就是說只有一個頁面,所有頁面的跳轉(zhuǎn),其實是將當(dāng)前頁面的顯示內(nèi)容進行替換,頁面仍舊只有一個,并不會打開新的頁面。

而頁面的跳轉(zhuǎn),通常有以下幾種場景:

  • 用戶輸入 url 進行跳轉(zhuǎn)
  • 用戶點擊交互按鈕進行跳轉(zhuǎn)
  • 用戶操作前進或后退進行跳轉(zhuǎn)

這些場景,路由的工作機制都能夠很好的支持。

如果網(wǎng)頁很簡單,只有一個首頁,并不存在頁面跳轉(zhuǎn)場景,那么可以不用配置路由,只需要在 index.html 中配置根視圖,以及在根模塊的 bootstrap 中配置根視圖組件即可。

但如果項目劃分成了多個功能模塊,那么應(yīng)該交由每個模塊管理自己的路由表,而后選擇一個上層模塊,來統(tǒng)一關(guān)聯(lián)各個模塊路由,有兩種方式:一是在上層模塊的 imports 內(nèi)按照一定順序來導(dǎo)入各個功能模塊;但這種方式想要按照路由層級來查看路由表就比較麻煩,需要到各個模塊內(nèi)部去查看或者借助一些工具。

另一種方式是,在上層模塊的路由表中使用 loadChildren 加載各個功能模塊,然后各個功能模塊默認路由都顯示成空視圖,各自內(nèi)部再通過配置 children 的路由表方式來管理各個模塊內(nèi)部自己的路由表。

組件與模板

在 Angular 中,最常接觸的應(yīng)該就是組件了。

我是這么理解的,組件可以是你在界面上看到的任何東西,可以是一個頁面,可以是頁面上的一個按鈕。

而對于瀏覽器解析并呈現(xiàn)前端頁面時,Html、CSS、JavaScript 這三分文件通常都是需要的,而 Angular 是使用了 TypeScript,所以一個組件,其實就包括了:Html,CSS,TypeScript。

在 Angular 中,可以說,是以組件為單位來組成頁面的,組件是核心,因為 Angular 提供的功能基本都是用來為組件服務(wù)的。

以上,是我的理解。

但要注意,官網(wǎng)教程中,很多地方的組件描述,更多時候是傾向于表示 TypeScript 的那份文件,因為對于組件來說,TypeScript 可以說是它的核心,CSS 只是樣式文件,Html 更類似于模板存在。

所以這里將組件和模板放在一起講,因為就像開頭那張圖一樣,組件是一份 TypeScript 文件,在該文件中,定義了這個組件的模板(template)來源和 CSS 樣式來源。

模板提供了該組件的呈現(xiàn)結(jié)構(gòu),而 TypeScript 里定義了組件的數(shù)據(jù)來源及交互行為,它們兩一起組織成一個視圖呈現(xiàn)給用戶。

既然,這份 TypeScript 的組件文件和模板文件需要共同合作,那么它們之間就少不了交互,所以就涉及到很多所謂的模板語法,也就是所謂的組件和模板之間的交互方式。

比如,當(dāng)要往模板中嵌入 TypeScript 中的變量數(shù)據(jù)時,可以使用 {{value}} 這種語法形式,同樣的,還有模板中標(biāo)簽的屬性綁定,事件回調(diào)注冊的交互方式的語法。

總之,Angular 支持雙向數(shù)據(jù)綁定,是一種以數(shù)據(jù)驅(qū)動的思想來讓頁面進行交互刷新的方式,區(qū)別于傳統(tǒng)的前端模式。在以往,如果需要動態(tài)的更新 DOM 上的信息時,需要先獲取到相對應(yīng)的元素實例對象,然后調(diào)用相應(yīng)的 DOM API 來操縱 DOM;

而使用 Angular 的話,可以直接在模板的相應(yīng)元素中,將某個屬性與 TypeScript 文件中某個變量直接進行綁定,后續(xù)這個變量值變化時,Angular 會自動去更新相應(yīng) DOM 的屬性,也就是說,原本那些操縱 DOM 的代碼,Angular 幫我們做了,我們不用再自己去處理了。

另外,注意,以上出現(xiàn)的 TypeScript 的描述,你可以理解成官網(wǎng)中的組件,我之所以不想用組件的方式來進行描述,是因為,我覺得,組件是一個整體,它本身就包括了 TypeScript 文件和模板文件,所以官網(wǎng)中說的組件和模板的交互,我覺得,換成組件中的 TypeScript 文件與模板文件的交互更為適合。

當(dāng)然,這只是我目前階段的理解。

服務(wù)

服務(wù)是一個廣義上的概念,通常用來處理那些跟 UI 交互無關(guān)的事情,比如網(wǎng)絡(luò)請求的工作等。

所以它也是為組件服務(wù),而且 Angular 有一套依賴注入機制,也就是說,組件只需要告訴 Angular,它需要哪些服務(wù),至于這些服務(wù)的實例是什么時候創(chuàng)建,交給誰去管理等這些組件內(nèi)部都不用自己去處理了。

Angular 會自動創(chuàng)建相關(guān)的服務(wù)實例,然后在組件適當(dāng)?shù)臅r候,將這個實例注入給組件去使用。

這種模式跟以前在 Android 端開發(fā)時有所區(qū)別,在 Android 端中,當(dāng)需要業(yè)務(wù)層某個實例對象時,通常都需要自己內(nèi)部去初始化,或者這個實例是個單例的話,也需要自己去實現(xiàn)單例。

但在 Angular 中,你可以借助它依賴注入的機制,來讓 Angular 幫你去做這些依賴的對象的實例管理的事,如果需要一個全局的單例服務(wù),那么可以將該服務(wù)聲明成 root 即全局可用;如果需要一個模塊內(nèi)的單例,那么可以在該模塊的 providers 中聲明該服務(wù);如果需要一個組件自己的實例對象,那么可以在組件的元數(shù)據(jù)塊的 providers 中配置該服務(wù)。

總之,就是,跟 UI 交互無關(guān)的工作,可以抽到服務(wù)中去處理,而該服務(wù)實例的管理,交給 Angular 就可以了,組件只需要告訴 Angular 它需要哪種形式的服務(wù)即可。

那么,組件是怎么告訴 Angular 的呢?

同樣在 Android 項目或者后端項目中,也有一些依賴注入框架,那些通常都是借助注解的方式來實現(xiàn)。

但在 Angular 中,不用這么麻煩,直接在組件的構(gòu)造函數(shù)的參數(shù)中,聲明某個服務(wù)類型的參數(shù)即可。

指令

指令也是為組件服務(wù)的,但是,是在組件的模板文件中來使用。

因為組件的模板,其實就是一份 HTML 文件,基于 HTML 的標(biāo)簽之上,加上一些 Angular 的模板語法,而 Angular 在將這份 HTML 文件代碼交給瀏覽器解析之前,會先自行解析一遍,去將模板中不屬于 HTML 的那些語法解析出相應(yīng)的行為。

而指令分為結(jié)構(gòu)型指令和屬性型指令,它們的區(qū)別,其實就在于,一個是改變 DOM 的結(jié)構(gòu),一個是改變 DOM 元素的樣式。

所以說,指令的目的,其實就是簡化一些操縱 DOM 的工作,比如你需要讓某些按鈕都具有統(tǒng)一的行為和樣式,當(dāng)被點擊時先做什么,再做什么。

實現(xiàn)這個,你當(dāng)然可以在 TypeScript 中去書寫這些邏輯,但要應(yīng)用到每個按鈕上,就比較繁瑣。

這個時候,就可以將這些工作都封裝到指令內(nèi)部,然后在每個按鈕標(biāo)簽上加上該指令,Angular 在解析模板時,發(fā)現(xiàn)了這個指令,就會為每個按鈕都加上這么一段程序邏輯。

我個人覺得,指令的功能,讓我們處理一些相同的行為,可以更好的去封裝,減少冗余和繁瑣。

當(dāng)然,上面舉的場景,也可以自己封裝個按鈕組件,然后在其他模板中,不使用原生按鈕,而使用封裝后的按鈕組件,也可以達到目的。

所以,組件其實也是指令的一種,但組件的實現(xiàn)方式會比較重,有時候,只需要封裝一些簡單的行為邏輯,就可以直接借助指令的方式封裝。

指令的原理也很簡單,在模板中某個元素標(biāo)簽上,添加上某個指令后,解析到這個指令時,會進入這個指令的相關(guān)工作,而指令內(nèi)部,會獲取到一個當(dāng)前指令掛載的元素標(biāo)簽對象,既然都拿到這個對象了,那么,在指令內(nèi)部想對這個元素做什么,都可以了。

指令還有另一個通途,通常用來擴展原有的功能,因為可能項目中,在模板里使用的組件或者 HTML 元素的標(biāo)簽因為種種原生無權(quán)或不方便進行修改,而又想在其基礎(chǔ)上擴展一些功能,此時就可以利用指令來實現(xiàn)。

管道

管道同樣是為組件服務(wù),也同樣是在組件的模板文件中來使用。

它的用途,在于,將數(shù)據(jù)按照一定的規(guī)則進行轉(zhuǎn)換,比如 Object 對象,轉(zhuǎn)換成 json 格式數(shù)據(jù),再比如,long 型的時間,轉(zhuǎn)換成具體的時間日期等等。

Angular 中已經(jīng)內(nèi)置了一些管道,也可以自定義管道。

示例

大概了解了 Angular 的架構(gòu)概覽,接下去就來看看一個簡單的 Angular 項目結(jié)構(gòu),以及各個文件、模塊的用途,稍微講一下。

這是用 WebStrom 創(chuàng)建一個 Angular 項目后,自動生成的簡單架構(gòu)。

在利用 Angular Cli 工具生成腳手架時,默認就已經(jīng)生成了很多配置項,而且此時,項目已經(jīng)是可以運行的,因為也自動生成了一個根模塊和根視圖,默認頁面是 Angular 的歡迎界面。

挑幾個來講講。

angular.json

這是 Angular-CLI 的配置文件,而 Angular-CLI 是自動化的工程構(gòu)建工具,也就是利用這個工具,可以幫助我們完成很多工作,比如創(chuàng)建項目、創(chuàng)建文件、構(gòu)建、打包等等。

原本的 HTML、CSS、JavaScript 的前端開發(fā)模式,并沒有工程的概念,只要用瀏覽器打開 HTML 文件就能夠運行。而 Angular 引入了 TypeScript,Scss 等瀏覽器并不無法識別的語言,自然,要讓瀏覽器運行 Angular 項目之前,需要進行一次編譯,一次轉(zhuǎn)換。

這些工作就可以借助 Angular-CLI 來進行。另外,創(chuàng)建一個模塊,創(chuàng)建一個組件,也都可以通過 Angular-CLI 來。

那么,在創(chuàng)建這些文件或者說,打包編譯這些項目文件時,該按照怎樣的規(guī)則,就是參照 angular.json 這份配置文件。

大概看一下內(nèi)容:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json", // 默認的配置項,比如默認配置了 ng g component 生成組件時應(yīng)該生成哪些文件等等
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "daView": {  // 項目的配置
      "root": "",
      "sourceRoot": "src",  // 源代碼路基
      "projectType": "application", // 項目的類型,是應(yīng)用還是三方庫(library)
      "prefix": "app", // 利用命令生成 component 和 directive 的前綴
      "schematics": {}, // 替換掉第一行的 schema.json 中的一些默認配置項,不如創(chuàng)建組件時,不要生成spec文件
      "architect": { // 執(zhí)行一些構(gòu)造工作時的配置
        "build": { // 執(zhí)行 ng build 時的一些配置項
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/daView", // 編譯后的文件輸出的位置
            "index": "src/index.html",   // 構(gòu)建所需的模板 Index.html
            "main": "src/main.ts",       // 構(gòu)建所需的文件
            "polyfills": "src/polyfills.ts", // 構(gòu)建所需的文件
            "tsConfig": "src/tsconfig.app.json", // 對 typescript 編譯的配置文件 
            "assets": [ // 構(gòu)建所需的資源
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [ // 構(gòu)建所需的樣式文件,可以是 scss
              "src/styles.css"
            ],
            "scripts": [] // 構(gòu)建所需的三方庫,比如 jQuery
          },
          "configurations": {/*...*/}
        },
        "serve": {/*...*/}, // 執(zhí)行 ng serve 時的一些配置項
        "extract-i18n": {/*...*/},
        "test": {/*...*/},
        "lint": {/*...*/}
        }
      }
    },
    "daView-e2e": {/*...*/},
  "defaultProject": "daView"
}

所以,利用 Angular-CLI 生成的初始項目中,有許多基本的文件,這些文件,基本也都在 angular.json 中被配置使用了,每個配置文件基本都有各自的用途。

比如,tslint 用來配置 lint 檢查,tsconfig 用來配置 TypeScript 的編譯配置,其他那些 html,css,ts,js 文件基本都是 Angular 項目運行所需的基礎(chǔ)文件。

package.json

對于一個工程項目來說,依賴的三方庫管理工具也很重要,在 Android 項目中,通常是借助 Gradle 或 maven 來管理三方庫。

而在 Angular 項目中,是使用 npm 來進行三方庫的管理,對應(yīng)的配置文件就是 package.json。

在這份配置文件中,配置了項目所需要的三方庫,npm 會自動去將這些三方庫下載到 node_modules 目錄中。然后,再去將一些需要一起打包的三方庫在 angular.json 中進行配置。

app/src 源碼

以上就是利用 Angular-CLI 創(chuàng)建項目生成的初始架構(gòu)中各個文件的大概用途,下面講講 Angular 項目的大概運行流程。

在 src 中的 index.html 文件就是單頁應(yīng)用的頁面文件,里面的 body 標(biāo)簽內(nèi),自動加入了一行根視圖的組件:

<app-root></app-root> 就是根組件 AppComponent (自動生成的)的組件標(biāo)簽,當(dāng) Angular 在 HTML 文件中發(fā)現(xiàn)有組件標(biāo)簽時,就會去加載該組件所屬的模塊,并去解析組件的模板文件,將其嵌入到 HTML 文件的組件標(biāo)簽中。

看一下自動生成的根模塊的部分內(nèi)容:

//app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
//app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'daView';
}

app.module.ts 文件用 @NgModule 表示該文件角色是模塊,并在內(nèi)部配置了它的組件 AppComponent,這樣 AppComponent 組件就只屬于該模塊了,并能夠在該模塊內(nèi)的其他組件中被使用。

另外,由于該模塊是根模塊,所以還需要配置 bootstrap,設(shè)置應(yīng)用的根視圖,這個配置需要和 index.html 里的 body 標(biāo)簽內(nèi)的根視圖組件是同一個組件,否則運行時就會報錯了。

當(dāng)項目中模塊多了的時候,各模塊之間基本是通過路由或者組件來進行相互關(guān)聯(lián)。

比如,我們新創(chuàng)建個 Home 模塊,然后在根模塊中創(chuàng)建個 app-routing 路由配置文件:

//app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'home', loadChildren: './home/home.module#HomeModule'
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

然后在 app.module.ts 的 imports 中將該路由配置導(dǎo)入,這樣當(dāng)路由到 home 時,會去加載 home 模塊,然后看看 home 模塊的路由配置:

//home-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {HomeComponent} from './home.component';
import {HomeCenterComponent} from './component/home-center.component';

const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: '', component: HomeCenterComponent
      }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class HomeRoutingModule { }

home 模塊的默認視圖為空,但交由其子視圖來控制,所以,當(dāng)導(dǎo)航到 home 時,home 模塊會去加載它內(nèi)部的 HomeCenterComponent 組件。

以上,是當(dāng)項目中有多模塊時,我的處理方式。

當(dāng)按照這種方式來實現(xiàn)時,對于了解一個 Angular,就有一定的規(guī)律可循了:

  1. 先找根視圖組件,然后確認根視圖組件中的 router-outlet 標(biāo)簽的區(qū)域,因為這個區(qū)域展示的就是由根模塊路由導(dǎo)航到的新的組件內(nèi)容;
  2. 去根模塊的配置中找到根模塊的路由配置表,來查看第一個層級的路由分別對應(yīng)哪些模塊;
  3. 去這些相應(yīng)的模塊中,查看它們各自內(nèi)部的路由配置表,來確定各自模塊的默認視圖組件是哪個,下一個層級的各個路由所對應(yīng)的視圖組件;
  4. 這樣,一個頁面的組件層次結(jié)構(gòu)就能夠很快的理清。

大家好,我是 dasu,歡迎關(guān)注我的公眾號(dasuAndroidTv),公眾號中有我的聯(lián)系方式,歡迎有事沒事來嘮嗑一下,如果你覺得本篇內(nèi)容有幫助到你,可以轉(zhuǎn)載但記得要關(guān)注,要標(biāo)明原文哦,謝謝支持~


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

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