12.《Angular生命周期》

一苏遥、生命周期鉤子

每個(gè)組件都有一個(gè)被 Angular 管理的生命周期供填。

Angular 創(chuàng)建它,渲染它婿着,創(chuàng)建并渲染它的子組件颤绕,在它被綁定的屬性發(fā)生變化>時(shí)檢查它幸海,并在它從 DOM 中被移除前銷毀它。

Angular 提供了生命周期鉤子奥务,把這些關(guān)鍵生命時(shí)刻暴露出來(lái),賦予你在它們發(fā)生時(shí)采取行動(dòng)的能力袜硫。

除了那些組件內(nèi)容和視圖相關(guān)的鉤子外,指令有相同生命周期鉤子氯葬。

二、組件生命周期鉤子概覽

指令和組件的實(shí)例有一個(gè)生命周期:新建婉陷、更新和銷毀帚称。 通過(guò)實(shí)現(xiàn)一個(gè)或多個(gè) Angular core 庫(kù)里定義的生命周期鉤子接口,開(kāi)發(fā)者可以介入該生命周期中的這些關(guān)鍵時(shí)刻秽澳。

每個(gè)接口都有唯一的一個(gè)鉤子方法闯睹,它們的名字是由接口名再加上 ng 前綴構(gòu)成的。比如担神,OnInit接口的鉤子方法叫做 ngOnInit楼吃, Angular 在創(chuàng)建組件后立刻調(diào)用它,

沒(méi)有指令或者組件會(huì)實(shí)現(xiàn)所有這些接口妄讯,并且有些鉤子只對(duì)組件有意義孩锡。只有在指令/組件中定義過(guò)的那些鉤子方法才會(huì)被 Angular 調(diào)用。

三亥贸、生命周期的順序

1.組件生命周期概覽

組件生命周期.png
  • 紅色的被調(diào)用一次躬窜,綠色的會(huì)被調(diào)用多次。

  • 這里分為了三個(gè)階段炕置,組件初始化階段荣挨,變化檢測(cè)組件銷毀朴摊。

  • 會(huì)在組件初始化后看到組件默垄,在變化檢測(cè)階段讓屬性值和頁(yè)面展示保持一致。

  • 變化檢測(cè)中的四個(gè)方法和組件初始化中的四個(gè)方法是一樣的仍劈。

一共只有9個(gè)方法厕倍。

當(dāng) Angular 使用構(gòu)造函數(shù)新建一個(gè)組件或指令后,就會(huì)按下面的順序在特定時(shí)刻調(diào)用這些生命周期鉤子方法:

鉤子 用途及時(shí)機(jī)
ngOnChanges() 當(dāng) Angular(重新)設(shè)置數(shù)據(jù)綁定輸入屬性時(shí)響應(yīng)贩疙。 該方法接受當(dāng)前和上一屬性值的 SimpleChanges 對(duì)象當(dāng)被綁定的輸入屬性的值發(fā)生變化時(shí)調(diào)用讹弯,首次調(diào)用一定會(huì)發(fā)生在 ngOnInit() 之前。
ngOnInit() 在 Angular 第一次顯示數(shù)據(jù)綁定和設(shè)置指令/組件的輸入屬性之后这溅,初始化指令/組件组民。在第一輪 ngOnChanges() 完成之后調(diào)用,只調(diào)用一次悲靴。
ngDoCheck() 檢測(cè)臭胜,并在發(fā)生 Angular 無(wú)法或不愿意自己檢測(cè)的變化時(shí)作出反應(yīng)。在每個(gè) Angular 變更檢測(cè)周期中調(diào)用,ngOnChanges()ngOnInit() 之后耸三。
ngAfterContentInit() 當(dāng)把內(nèi)容投影進(jìn)組件之后調(diào)用乱陡。第一次 ngDoCheck() 之后調(diào)用,只調(diào)用一次仪壮。
ngAfterContentChecked() 每次完成被投影組件內(nèi)容的變更檢測(cè)之后調(diào)用憨颠。ngAfterContentInit() 和每次 ngDoCheck() 之后調(diào)用
ngAfterViewInit() 初始化完組件視圖及其子視圖之后調(diào)用。第一次 ngAfterContentChecked() 之后調(diào)用积锅,只調(diào)用一次爽彤。
ngAfterViewChecked() 每次做完組件視圖和子視圖的變更檢測(cè)之后調(diào)用。ngAfterViewInit() 和每次 ngAfterContentChecked() 之后調(diào)用缚陷。
ngOnDestroy() 當(dāng) Angular 每次銷毀指令/組件之前調(diào)用并清掃适篙。 在這兒反訂閱可觀察對(duì)象和分離事件處理器,以防內(nèi)存泄漏箫爷。在 Angular 銷毀指令/組件之前調(diào)用嚷节。

2.代碼示例

新建hooks組件

ng g hooks
//app.component.html
<app-hooks [name]="title"></app-hooks>
//app.component.ts
import {Component} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title: string = 'XiaoMing';
}
//hooks.component.html
<p>
  {{name}}
</p>
//hooks.component.ts
///<reference path="../../../node_modules/@angular/core/src/metadata/lifecycle_hooks.d.ts"/>
import {
  AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, DoCheck, Input, OnChanges, OnDestroy,
  OnInit, SimpleChanges
} from '@angular/core';

let logIndex: number = 1;

@Component({
  selector: 'app-hooks',
  templateUrl: './hooks.component.html',
  styleUrls: ['./hooks.component.css']
})
export class HooksComponent implements OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy {

  @Input()
  name: string;

  logMsg(msg: string) {
    console.log(`#${logIndex++} ${msg}`);
  }

  constructor() {
    this.logMsg('name屬性在construstor里的值是' + name);
  }

  ngOnChanges(changes: SimpleChanges): void {
    const newName = changes['name'].currentValue;
    this.logMsg('name屬性在ngOnChanges里的值是' + newName);
  }

  ngOnInit(): void {
    this.logMsg('ngOnInit');
  }

  ngDoCheck(): void {
    this.logMsg('ngDoCheck');
  }

  ngAfterContentInit(): void {
    this.logMsg('ngAfterContentInit');
  }

  ngAfterContentChecked(): void {
    this.logMsg('ngAfterContentChecked');
  }

  ngAfterViewInit(): void {
    this.logMsg('ngAfterViewInit');
  }

  ngAfterViewChecked(): void {
    this.logMsg('ngAfterViewChecked');
  }

  ngOnDestroy(): void {
    this.logMsg('ngOnDestroy');
  }
}

調(diào)用順序如圖所示


調(diào)用結(jié)果.png

首先會(huì)調(diào)用構(gòu)造函數(shù)

ngOnChanges:當(dāng)一個(gè)父組件修改或初始化一個(gè)子組件的`輸入屬性`的時(shí)候被調(diào)用
ngOnInit:初始化(如果初始化的邏輯需要依賴輸入屬性,那就一定要寫(xiě)在ngOnInit中蝶缀,而不要寫(xiě)在構(gòu)造函數(shù)中)
ngDoCheck:用來(lái)檢測(cè)
ngAfterContentInit:
ngAfterContentChecked:
ngAfterViewInit
ngAfterViewChecked
ngDoCheck
ngAfterContentChecked
ngAfterViewChecked

四丹喻、具體鉤子

4.1 ngOnchanges

當(dāng)父組件初始化修改子組件的輸入?yún)?shù)時(shí)會(huì)被調(diào)用。

可變對(duì)象翁都,不可變對(duì)象

  • 字符串是不可變的(改變值只是修改了內(nèi)存中的指向)

  • 對(duì)象的值是可變的

代碼示例
新建child組件

ng g component child
//child.component.html
<div style="background: deepskyblue;">
  <h2>我是子組件</h2>
  <div>問(wèn)候語(yǔ):{{greeting}}</div>
  <div>姓名:{{user.name}}</div>
  <div>消息:<input [(ngModel)]="message"></div>
</div>
//child.component.ts
import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges {
  @Input()
  greeting: string;
  @Input()
  user: { name: string };

  message: string = '初始化消息';

  constructor() {
  }

  ngOnInit() {
  }

  ngOnChanges(changes: SimpleChanges): void {
    console.log(JSON.stringify(changes, null, 4));
  }
}
//app.component.html
<div style="background: deeppink">
  <h1>
    我是主組件
  </h1>
  問(wèn)候語(yǔ):<input type="text" [(ngModel)]="greeting">
  姓名:<input type="text" [(ngModel)]="user.name">
  <app-child [greeting]="greeting" [user]="user"></app-child>
</div>

//app.component.ts
import {Component} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  greeting: string = 'Hi';
  user: { name: string } = {name: 'XiaoMing'};
}

運(yùn)行結(jié)果:

結(jié)果1.png

改變父組件‘問(wèn)候語(yǔ)’的值為'Hi!'
結(jié)果2.png

但當(dāng)我們改變父組件中'姓名'的值為'XiaoMing11111'時(shí)碍论,控制臺(tái)不會(huì)打印出新東西。
結(jié)果3.png

因?yàn)間reeting是字符串是不可變對(duì)象(每次值改變的時(shí)候都會(huì)創(chuàng)建一個(gè)新的字符串柄慰,然后把引用指向新的字符串)鳍悠,而user是可變對(duì)象,修改姓名的值的時(shí)候并沒(méi)有改變user對(duì)象的引用坐搔。那么怎么監(jiān)控可變對(duì)象呢藏研,用doCheck

當(dāng)我改變頁(yè)面中子組件的消息時(shí),也不會(huì)打印出新東西概行,因?yàn)樽咏M件中的message屬性沒(méi)有被@Input()標(biāo)記不是輸入屬性蠢挡。


結(jié)果4.png

4.2 變更檢測(cè)機(jī)制和DoCheck鉤子

查看package.json文件中的dependencies的zone.js

就是zone.js來(lái)實(shí)現(xiàn)變更檢測(cè)機(jī)制的,主要作用是保證屬性的變化和頁(yè)面的變化是一致的凳忙,瀏覽器中發(fā)生的任何異步事件都會(huì)觸發(fā)變更檢測(cè)业踏,比如點(diǎn)擊按鈕,輸入數(shù)據(jù)...

變更檢測(cè)機(jī)制1.png
  • 默認(rèn)的是Default策略涧卵,當(dāng)父組件變化時(shí)會(huì)檢測(cè)整個(gè)組件樹(shù)

  • 如果在子組件中設(shè)置了OnPush勤家,當(dāng)父組件變化時(shí)就只會(huì)檢測(cè)父組件

變更檢測(cè)機(jī)制2.png

當(dāng)孫子組件1發(fā)生變化后柳恐,紅色的部分都會(huì)被檢測(cè)一遍伐脖,也就是調(diào)DoCheck方法热幔。并且是從父組件開(kāi)始檢查。

書(shū)接上文讼庇,我們?cè)赾hild組件中添加Docheck鉤子

//child.component.ts
import {Component, DoCheck, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit, OnChanges, DoCheck {
  @Input()
  greeting: string;
  @Input()
  user: { name: string };

  message: string = '初始化消息';
  OldUserName: string;
  changeDetected: boolean = false;
  noChangeCount: number = 0;

  constructor() {
  }

  ngOnInit() {
  }

  ngOnChanges(changes: SimpleChanges): void {
    console.log(JSON.stringify(changes, null, 4));
  }

  ngDoCheck(): void {
    if (this.OldUserName !== this.user.name) {
      this.changeDetected = true;
      console.log('DoCheck:user.name從' + this.OldUserName + '變?yōu)? + this.user.name);
      this.OldUserName = this.user.name;
    }
    if (this.changeDetected) {
      this.noChangeCount = 0;
    } else {
      this.noChangeCount += 1;
      console.log('DoCheck:user.name沒(méi)變化時(shí)ngDoCheck方法已經(jīng)被調(diào)用' + this.noChangeCount + '次');
    }
    this.changeDetected = false;
  }
}

DoCheck運(yùn)行效果:

DoCheck運(yùn)行效果1.png

  • 頁(yè)面初始化時(shí)docheck調(diào)用一次
DoCheck運(yùn)行效果2.png
  • 當(dāng)我在問(wèn)候語(yǔ)的輸入框和姓名的輸入框中來(lái)回切換點(diǎn)擊的時(shí)候绎巨,就會(huì)觸發(fā)docheck方法。當(dāng)我改變姓名的值的時(shí)候也會(huì)觸發(fā)巫俺。之后我再點(diǎn)擊輸入框的時(shí)候认烁,調(diào)用次數(shù)重置為1。這就是上一段代碼要實(shí)現(xiàn)的效果介汹。
DoCheck運(yùn)行效果3.png
  • 雖然當(dāng)我修改姓名的時(shí)候這個(gè)鉤子會(huì)被調(diào)用,但是我們必須要小心ngdocheck這個(gè)鉤子會(huì)非常頻繁的被調(diào)用舶沛,每一次變化都會(huì)被調(diào)用嘹承,在這個(gè)例子中,我還沒(méi)做任何操作呢如庭,只是在頁(yè)面隨便點(diǎn)點(diǎn)就會(huì)被調(diào)用好幾次叹卷,只有很少的調(diào)用次數(shù)是修改數(shù)據(jù)的時(shí)候觸發(fā)的。

  • 所以對(duì)ngDoCheck這個(gè)方法的實(shí)現(xiàn)一定要非常高效坪它,非常輕量級(jí)骤竹,不然會(huì)引起性能問(wèn)題。不光是這個(gè)方法往毡,變更檢測(cè)中的那些帶Check的方法都應(yīng)該這樣

4.3 view鉤子

如何在父組件調(diào)用子組件中的方法

新建一個(gè)子組件

ng g component child2
//child2.component.ts
import {Component, OnInit} from '@angular/core';

@Component({
  selector: 'app-child2',
  templateUrl: './child2.component.html',
  styleUrls: ['./child2.component.css']
})
export class Child2Component implements OnInit {

  constructor() {
  }

  ngOnInit() {
  }

  greeting(name: string) {
    console.log('Hello' + name);
  }
}
//app.component.html
<h1>主組件</h1>
<div>
  <app-child2 #view1></app-child2>
  <app-child2 #view1></app-child2>
  <button (click)="view1.greeting('William')">點(diǎn)擊按鈕</button>
</div>

//app.component.ts
import {Component, ViewChild} from '@angular/core';
import {Child2Component} from './child2/child2.component';

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

  @ViewChild('view1')
  view1: Child2Component;//獲得子組件之后就可以調(diào)用子組件中的方法了

  constructor() {}

  ngOnInit(): void {
    this.view1.greeting('XiaoMing');//調(diào)用方法
  }

}


運(yùn)行效果:

效果1.png

  • 會(huì)在控制臺(tái)打印出HelloXiaoMing

  • 然后我點(diǎn)擊按鈕蒙揣,會(huì)打印出HelloWilliam

這樣就實(shí)現(xiàn)了在父組件中調(diào)用子組件方法。

現(xiàn)在學(xué)習(xí)那兩個(gè)鉤子AfterViewInit开瞭,AfterViewChecked

//修改child2.component.ts
import {AfterViewChecked, AfterViewInit, Component, OnInit} from '@angular/core';

@Component({
  selector: 'app-child2',
  templateUrl: './child2.component.html',
  styleUrls: ['./child2.component.css']
})
export class Child2Component implements OnInit, AfterViewInit, AfterViewChecked {

  constructor() {
  }

  ngOnInit() {
  }

  ngAfterViewInit(): void {
    console.log('子組件的視圖初始化完畢');
  }

  ngAfterViewChecked(): void {
    console.log('子組件的視圖變更檢測(cè)完畢');
  }
  
  greeting(name: string) {
    console.log('Hello' + name);
  }
}
//修改app.component.ts
import {AfterViewChecked, AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
import {Child2Component} from './child2/child2.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewInit, AfterViewChecked {

  @ViewChild('view1')
  view1: Child2Component;//獲得子組件之后就可以調(diào)用子組件中的方法了

  constructor() {

  }

  ngOnInit(): void {
    setInterval(() => {
      this.view1.greeting('XiaoMing');
    }, 5000);

  }

  //在組件模板的內(nèi)容都已經(jīng)呈現(xiàn)給用戶看之后懒震,會(huì)調(diào)用這兩個(gè)方法
  ngAfterViewInit(): void {
    console.log('父組件的視圖初始化完畢');
  }

  ngAfterViewChecked(): void {
    console.log('父組件的視圖變更檢測(cè)完畢');
  }

}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果1.png

  • 初始化ngAfterViewInit的方法會(huì)在變更檢測(cè)ngAfterViewChecked方法之前調(diào)用。這兩個(gè)方法都是在視圖組裝完畢之后 被調(diào)用的嗤详。
  • 初始化方法只會(huì)被調(diào)用一次个扰。
  • 如果有子組件,需要等所有子組件視圖組裝完畢之后才會(huì)觸發(fā)父組件的ngAfterViewInit葱色、ngAfterViewChecked(這里處理了兩個(gè)子組件所以子組件調(diào)用了兩次)递宅。
  • 不要在這兩個(gè)方法中去改變視圖中綁定的東西,如果想改變也要寫(xiě)在一個(gè)setTimeout里邊苍狰。
  • 如果想實(shí)現(xiàn)ngAfterViewChecked這個(gè)鉤子刻蟹,方法一定要非常高效,非常輕量級(jí)穴翩,不然會(huì)引起性能問(wèn)題氨菇。
//修改app.component.html
<h1>主組件</h1>
<div>
  <app-child2 #view1></app-child2>
  <app-child2 #view1></app-child2>
  <button (click)="view1.greeting('William')">點(diǎn)擊按鈕</button>
  {{message}}
</div>

//修改app.component.ts
  message:string;

  ngAfterViewInit(): void {
    console.log("父組件的視圖初始化完畢");
    this.message="Hello";
  }

運(yùn)行結(jié)果:

結(jié)果2.png

啟動(dòng)項(xiàng)目,這時(shí)候會(huì)報(bào)一個(gè)錯(cuò)

因?yàn)锳ngular規(guī)定禁止在一個(gè)視圖在組裝好之后再去更新這個(gè)視圖响牛。

ngAfterViewInit玷禽、ngAfterViewChecked這2個(gè)鉤子恰是在視圖組裝好之后被觸發(fā)的赫段。

//解決辦法
ngAfterViewInit(): void {
   console.log('父組件的視圖初始化完畢');
   setTimeout(() => {
     this.message = 'Hello';
   }, 0);
 }

讓其在JavaScript的另一個(gè)運(yùn)行周期中去運(yùn)行。

4.4 ngContent指令

投影矢赁,在某些情況下糯笙,需要動(dòng)態(tài)改變模板的內(nèi)容,可以用路由撩银,但路由是一個(gè)相對(duì)比較麻煩的東西给涕,而我要實(shí)現(xiàn)的功能沒(méi)有那么復(fù)雜,额获,沒(méi)有什么業(yè)務(wù)邏輯够庙,也不需要重用。

這個(gè)時(shí)候可以用投影抄邀≡耪#可以用ngContent將父組件中任意片段投影到子組件中。

代碼示例:

//新建組件child3
ng g component child3
//child3.component.html
<div class="wrapper">
  <h2>我是子組件</h2>
  <div>這個(gè)div定義在子組件中</div>
  <ng-content></ng-content>
</div>

///child3.component.css
.wrapper{
  background:deepskyblue;
}
//app.component.html
<div class="wrapper">
  <h2>我是父組件</h2>
  <div>這個(gè)div定義在父組件中</div>
  <app-child3>
    <div>這個(gè)div是父組件投影到子組件的</div>
  </app-child3>
</div>

//app.component.css
.wrapper{
  background:#ff6700;
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果1.png

一個(gè)組件可以在其模板中聲明多個(gè)ng-content標(biāo)簽

假設(shè)子組件的部分是由三部分組成的境肾,頁(yè)頭剔难,頁(yè)腳和內(nèi)容區(qū)。頁(yè)頭和頁(yè)腳由父組件投影進(jìn)來(lái)奥喻,內(nèi)容區(qū)自己定義

//修改child3.component.html
<div class="wrapper">
  <h2>我是子組件</h2>
  <ng-content select=".header"></ng-content>
  <div>這個(gè)div定義在子組件中</div>
  <ng-content select=".footer"></ng-content>
</div>
//修改app.component.html
<div class="wrapper">
  <h2>我是父組件</h2>
  <div>這個(gè)div定義在父組件中</div>
  <app-child3>
    <div class="header">這是頁(yè)頭.這個(gè)div是父組件投影到子組件的,title是{{title}}</div>
    <div class="footer">這是頁(yè)腳.這個(gè)div是父組件投影到子組件的</div>
  </app-child3>
</div>

//app.component.ts
export class AppComponent {
  title = 'XiaoMing';
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果2.png

使用的{{title}}只能綁定父組件中的屬性偶宫。

Angular還可以用屬性綁定的形式很方便的插入一段HTML。

//修改app.component.html
<div class="wrapper">
  <h2>我是父組件</h2>
  <div>這個(gè)div定義在父組件中</div>
  <app-child3>
    <div class="header">這是頁(yè)頭.這個(gè)div是父組件投影到子組件的,title是{{title}}</div>
    <div class="footer">這是頁(yè)腳.這個(gè)div是父組件投影到子組件的</div>
  </app-child3>
</div>
<div [innerHTML]="htmlContent"></div>

//修改app.component.ts
export class AppComponent {
  title = 'XiaoMing';
  htmlContent = '<p>this are some strings.</p>';
}
運(yùn)行結(jié)果3.png
  • innerHTML這種方式只能在瀏覽器中使用环鲤,而ngContent是跨平臺(tái)的纯趋,可以在app應(yīng)用中使用

  • ngContent可以設(shè)置多個(gè)投影點(diǎn)。

  • 動(dòng)態(tài)生成一段HTML楔绞,應(yīng)該優(yōu)先考慮ngContent這種方式结闸。

4.5 ngAfterContentInit和ngAfterContentChecked

//修改app.component.ts
import {AfterContentChecked, AfterContentInit, AfterViewInit, Component} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterContentInit, AfterContentChecked, AfterViewInit {

  title = 'XiaoMing';
  htmlContent = '<p>this are some strings.</p>';

  ngAfterContentInit(): void {
    console.log('父組件投影內(nèi)容初始化完畢');
  }

  ngAfterContentChecked(): void {
    console.log('父組件投影內(nèi)容變更檢測(cè)完畢');
  }

  ngAfterViewInit(): void {
    console.log('父組件視圖內(nèi)容初始化完畢');
  }
}
//修改child3.component.ts
import {AfterContentChecked, AfterContentInit, Component, OnInit} from '@angular/core';

@Component({
  selector: 'app-child3',
  templateUrl: './child3.component.html',
  styleUrls: ['./child3.component.css']
})
export class Child3Component implements OnInit, AfterContentInit, AfterContentChecked {

  constructor() {
  }

  ngOnInit() {
  }

  ngAfterContentChecked(): void {
    console.log('子組件投影內(nèi)容變更檢測(cè)完畢');
  }

  ngAfterContentInit(): void {
    console.log('子組件投影內(nèi)容初始化完畢');
  }
}

運(yùn)行結(jié)果:

運(yùn)行結(jié)果.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市酒朵,隨后出現(xiàn)的幾起案子桦锄,更是在濱河造成了極大的恐慌,老刑警劉巖蔫耽,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件结耀,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡匙铡,警方通過(guò)查閱死者的電腦和手機(jī)图甜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鳖眼,“玉大人黑毅,你說(shuō)我怎么就攤上這事∏栈洌” “怎么了矿瘦?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵枕面,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我缚去,道長(zhǎng)潮秘,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任易结,我火速辦了婚禮枕荞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搞动。我一直安慰自己躏精,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布鹦肿。 她就那樣靜靜地躺著玉控,像睡著了一般。 火紅的嫁衣襯著肌膚如雪狮惜。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天碌识,我揣著相機(jī)與錄音碾篡,去河邊找鬼。 笑死筏餐,一個(gè)胖子當(dāng)著我的面吹牛开泽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播魁瞪,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼穆律,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了导俘?” 一聲冷哼從身側(cè)響起峦耘,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旅薄,沒(méi)想到半個(gè)月后辅髓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡少梁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年洛口,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凯沪。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡第焰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出妨马,到底是詐尸還是另有隱情挺举,我是刑警寧澤杀赢,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站豹悬,受9級(jí)特大地震影響葵陵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瞻佛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一脱篙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伤柄,春花似錦绊困、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至笔喉,卻和暖如春取视,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背常挚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工作谭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奄毡。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓折欠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親吼过。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锐秦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360