Django結(jié)合Vue.js框架構(gòu)建前后端分離

Django結(jié)合Vue.js框架構(gòu)建前后端分離

一宴抚、先搞清楚什么是前后端分離

前后端分離能帶來哪些優(yōu)勢袄膏?(好處多多践图,這里僅提兩個點(diǎn))

  • 第一個,并行開發(fā)沉馆、獨(dú)立部署码党、實(shí)現(xiàn)前后端解,前后端的進(jìn)度互不影響斥黑,在過去揖盘,前后端不分離的情況下,項(xiàng)目代碼耦合嚴(yán)重相互影響心赶,且前后端人員工作量分布不均扣讼。

  • 第二個,術(shù)業(yè)有專攻(開發(fā)人員分離)缨叫,以前的JavaWeb項(xiàng)目大多數(shù)都是Java程序員又當(dāng)?shù)之?dāng)媽椭符,又搞前端,又搞后端耻姥。前后端分離之后销钝,前端工程師只管前端的事情,后端工程師只管后端的事情琐簇。

我們先看看一個 Web 系統(tǒng)蒸健,在前后端不分離時(shí)架構(gòu)設(shè)計(jì)是什么樣的。

用戶在瀏覽器上發(fā)送請求婉商,服務(wù)器端接收到請求似忧,根據(jù) Header 中的 token 進(jìn)行用戶鑒權(quán),從數(shù)據(jù)庫取出數(shù)據(jù)丈秩,處理后將結(jié)果數(shù)據(jù)填入 HTML 模板盯捌,返回給瀏覽器,瀏覽器將 HTML 展現(xiàn)給用戶蘑秽。

而采用前后端分離之后饺著,分離的是人員職責(zé),人員職責(zé)分離了肠牲,因此架構(gòu)也發(fā)生變化幼衰。

前后端分離后,前端人員和后端人員約定好接口缀雳,前端人員不用再關(guān)心業(yè)務(wù)處理是怎么回事渡嚣,他只需要把界面做好就可以了,后端人員也不用再關(guān)系前端界面是什么樣的,他只需要做好業(yè)務(wù)邏輯處理即可识椰。

小結(jié)一下扬绪,前后端分離是什么?

前后端分離是一種架構(gòu)模式裤唠,或者說是最佳實(shí)踐挤牛,它主張將前端開發(fā)人員和后端開發(fā)人員的工作進(jìn)行解耦,盡量減少他她們之間的交流成本种蘸,幫助他她們更能專注于自己擅長的工作墓赴。

PS: 本篇實(shí)戰(zhàn)示例,使用Vue.js作為前端框架航瞭,代替Django本身自帶的模板引擎诫硕,Django則作為服務(wù)端提供API接口,從而實(shí)現(xiàn)前后端分離刊侯。

二章办、環(huán)境準(zhǔn)備

本實(shí)戰(zhàn)示例,基礎(chǔ)環(huán)境對應(yīng)安裝版本如下:

  • Python 3.7.4
  • Mysql 5.7
  • Pycharm (建議專業(yè)版)
  • Node

三. 新建獨(dú)立的虛擬開發(fā)環(huán)境

1滨彻、創(chuàng)建一個用于Django項(xiàng)目開發(fā)的獨(dú)立虛擬環(huán)境藕届,切換到本地開發(fā)目錄,輸入如下命令:

python3 -m venv venv

2亭饵、創(chuàng)建完成后休偶,目錄結(jié)構(gòu)如下:

?  venv tree -L 2
.
├── bin
│   ├── activate
│   ├── activate.csh
│   ├── activate.fish
│   ├── easy_install
│   ├── easy_install-3.7
│   ├── pip
│   ├── pip3
│   ├── pip3.7
│   ├── python -> python3
│   └── python3 -> /usr/local/bin/python3
├── include
├── lib
│   └── python3.7
└── pyvenv.cfg

4 directories, 11 files

3、進(jìn)入到bin目錄辜羊,輸入命令source activate 命令踏兜,激活虛擬環(huán)境。

4八秃、虛擬環(huán)境激活后碱妆,如上圖所示。接下來昔驱,在虛擬環(huán)境安裝Django庫疹尾。

安裝Django (最新版本為3.0)

(venv) ?  pip install Django

Django 項(xiàng)目源碼

Django3.0 版本特性可查閱官網(wǎng)

5、安裝完成后舍悯,可檢查一下版本信息:

(venv) ?  python
Python 3.7.4 (default, Jul  9 2019, 18:15:00)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print(django.get_version())
3.0

可以發(fā)現(xiàn)航棱,在虛擬環(huán)境中已經(jīng)成功安裝好了Django 3.0睡雇。

四萌衬、創(chuàng)建Django后端項(xiàng)目

1、創(chuàng)建Django項(xiàng)目它抱,采用Pycharm或者命令行創(chuàng)建皆可秕豫。此處,以命令行方式作為演示,項(xiàng)目名為django_vue混移。

(venv) ? django-admin startproject django_vue

2. Django項(xiàng)目創(chuàng)建完成后祠墅,目錄結(jié)構(gòu)如下所示。


├── django_vue
│   ├── django_vue
│   │   ├── __init__.py
│   │   ├── asgi.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   └── manage.py

3歌径、執(zhí)行同步數(shù)據(jù)庫文件(Django默認(rèn)數(shù)據(jù)庫為db.sqlite3)毁嗦,執(zhí)行同步過程如下:


(venv) ?  python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

4、啟動Django Server 回铛,驗(yàn)證默認(rèn)配置是否正常狗准。

(venv) ?   python manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
December 15, 2019 - 08:36:28
Django version 3.0, using settings 'django_vue.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.

5、打開瀏覽器茵肃,訪問http://localhost:8000腔长,一切正常的話,可見到如下界面验残。

五捞附、將Django數(shù)據(jù)庫更換為Mysql

1、假設(shè)在前面您没,我們已經(jīng)安裝配置好了Mysql鸟召,輸入如下命令進(jìn)入到Mysql。

mysql -u root -p

2氨鹏、創(chuàng)建數(shù)據(jù)庫药版,數(shù)據(jù)庫取名為django_vue_db,并設(shè)置字符集為utf-8喻犁。

mysql> CREATE DATABASE django_vue_db CHARACTER SET utf8;
Query OK, 1 row affected (0.01 sec)

3槽片、安裝myslqclient庫

(venv) ?  pip install mysqlclient

4、配置settings.py文件肢础,配置Mysql數(shù)據(jù)庫引擎还栓。

?```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_vue_db',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
    }
}

5、執(zhí)行同步操作传轰,將數(shù)據(jù)遷移到Mysql剩盒。

python manage.py migrate

6、驗(yàn)證是否切庫成功慨蛙,進(jìn)入到Mysql客戶端辽聊,查看django初化表是否有生成。


mysql> use django_vue_db;
Database changed
mysql> show tables;
+----------------------------+
| Tables_in_django_vue_db    |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
10 rows in set (0.00 sec)

7期贫、運(yùn)行Django Server跟匆,重新訪問http://localhost:8000

python manage.py runserver 0.0.0.0:8000

如果能正常訪問通砍,過程沒有報(bào)錯玛臂,說明切換數(shù)據(jù)庫已經(jīng)成功了烤蜕。

六、創(chuàng)建Django實(shí)戰(zhàn)項(xiàng)目App

1迹冤、創(chuàng)建Django App讽营,進(jìn)入django_vue項(xiàng)目主目錄,輸入如下命令:

(venv) ?  python manage.py startapp api_test

2泡徙、App創(chuàng)建完成后橱鹏,目錄結(jié)構(gòu)如下所示:

├── api_test
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py

并把a(bǔ)pi_test加入到settings文件中的installed_apps列表里:


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api_test',
]

3、 在api_test目錄下的models.py里我們簡單寫一個model如下:

# -*- coding: utf-8 -*-
from django.db import models
class Book(models.Model):
    book_name = models.CharField(max_length=128)
    add_time = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.book_name

只有兩個字段堪藐,書名book_name和添加時(shí)間add_time蚀瘸。如果沒有指定主鍵的話Django會自動新增一個自增id作為主鍵。

4庶橱、在api_test目錄下的views里我們新增兩個接口贮勃,一個是show_books返回所有的書籍列表(通過JsonResponse返回能被前端識別的json格式數(shù)據(jù)),二是add_book接受一個get請求苏章,往數(shù)據(jù)庫里添加一條book數(shù)據(jù)寂嘉。

from django.shortcuts import render
from django.views.decorators.http import require_http_methods
from django.core import serializers
from django.http import JsonResponse
import json

from .models import Book

@require_http_methods(["GET"])
def add_book(request):
    response = {}
    try:
        book = Book(book_name=request.GET.get('book_name'))
        book.save()
        response['msg'] = 'success'
        response['error_num'] = 0
    except  Exception as e:
        response['msg'] = str(e)
        response['error_num'] = 1
    return JsonResponse(response)

@require_http_methods(["GET"])
def show_books(request):
    response = {}
    try:
        books = Book.objects.filter()
        response['list'] = json.loads(serializers.serialize("json", books))
        response['msg'] = 'success'
        response['error_num'] = 0
    except  Exception as e:
        response['msg'] = str(e)
        response['error_num'] = 1
    return JsonResponse(response)

可以看出,在ORM的幫忙下枫绅,我們的接口實(shí)際上不需要自己去組織SQL代碼泉孩。

5、在api_test目錄下并淋,新增一個urls.py文件寓搬,把我們新增的兩個接口添加到路由里:


from django.conf.urls import url, include
from .views import *

urlpatterns = [
    url(r'add_book$', add_book, ),
    url(r'show_books$', show_books, ),
]

6、我們還要把a(bǔ)pi_test下的urls添加到項(xiàng)目django_vue下的urls中县耽,才能完成路由:

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from django.contrib import admin
from django.views.generic import TemplateView
import api_test.urls

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include(api_test.urls)),
]

7句喷、在項(xiàng)目的根目錄,輸入命令:

python manage.py makemigrations api_test
python manage.py migrate

8兔毙、查詢數(shù)據(jù)庫唾琼,看到book表已經(jīng)自動創(chuàng)建了:

mysql> show tables;
+----------------------------+
| Tables_in_django_vue_db    |
+----------------------------+
| api_test_book              |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
11 rows in set (0.00 sec)
mysql> desc api_test_book;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(11)      | NO   | PRI | NULL    | auto_increment |
| book_name | varchar(128) | NO   |     | NULL    |                |
| add_time  | datetime(6)  | NO   |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql>

Django生成的表名將以app名加上model中的類名組合而成。

9澎剥、在項(xiàng)目的根目錄锡溯,輸入命令:

python manage.py runserver 0.0.0.0:8000

啟動服務(wù),通過httpie測試一下我們剛才寫的兩個接口哑姚。

10祭饭、通過調(diào)用接口向Django App中添加兩條書名記錄。

?  http http://127.0.0.1:8000/api/add_book\?book_name\=mikezhou_talk
HTTP/1.1 200 OK
Content-Length: 34
Content-Type: application/json
Date: Sun, 15 Dec 2019 09:11:12 GMT
Server: WSGIServer/0.2 CPython/3.7.4
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
    "error_num": 0,
    "msg": "success"
}


 ?  http http://127.0.0.1:8000/api/add_book\?book_name\=測試開發(fā)技術(shù)
HTTP/1.1 200 OK
Content-Length: 34
Content-Type: application/json
Date: Sun, 15 Dec 2019 09:11:44 GMT
Server: WSGIServer/0.2 CPython/3.7.4
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
    "error_num": 0,
    "msg": "success"
}

11叙量、通過調(diào)用接口倡蝙,顯示Django App中所有書名列表:

?  http http://127.0.0.1:8000/api/show_books
HTTP/1.1 200 OK
Content-Length: 305
Content-Type: application/json
Date: Sun, 15 Dec 2019 09:13:48 GMT
Server: WSGIServer/0.2 CPython/3.7.4
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
    "error_num": 0,
    "list": [
        {
            "fields": {
                "add_time": "2019-12-15T09:11:12.673Z",
                "book_name": "mikezhou_talk"
            },
            "model": "api_test.book",
            "pk": 1
        },
        {
            "fields": {
                "add_time": "2019-12-15T09:11:44.305Z",
                "book_name": "測試開發(fā)技術(shù)"
          },
            "model": "api_test.book",
            "pk": 2
        }
    ],
    "msg": "success"
}

七、新建Vue.js前端項(xiàng)目

1宛乃、有關(guān)Vue的模塊(包括vue)可以使用node自帶的npm包管理器安裝悠咱。推薦使用淘寶的 cnpm 命令行工具代替默認(rèn)的 npm。

npm install -g cnpm --registry=https://registry.npm.taobao.org

2征炼、先用cnpm安裝vue-cli腳手架工具(vue-cli是官方腳手架工具析既,能迅速幫你搭建起vue項(xiàng)目的框架):

cnpm install -g vue-cli

3、安裝好后谆奥,在django_vue項(xiàng)目根目錄下眼坏,新建一個前端工程目錄:

vue-init webpack frontend

在創(chuàng)建項(xiàng)目的過程中會彈出一些與項(xiàng)目相關(guān)的選項(xiàng)需要回答,按照真實(shí)情況進(jìn)行輸入即可酸些。

4宰译、安裝 vue 依賴模塊

cd frontend
cnpm install
cnpm install  vue-resource
cnpm install element-ui

5、現(xiàn)在我們可以看到整個文件目錄結(jié)構(gòu)是這樣的:

本文為了讀者方便查看魄懂,是直接將vue前端工程放在django項(xiàng)目目錄下沿侈,實(shí)際多人協(xié)作開發(fā)過程中,完全是可以放在不同代碼倉庫下面的市栗。

6缀拭、在frontend目錄src下包含入口文件main.js,入口組件App.vue等填帽。后綴為vue的文件是Vue.js框架定義的單文件組件蛛淋,其中標(biāo)簽中的內(nèi)容可以理解為是類html的頁面結(jié)構(gòu)內(nèi)容。

7篡腌、在src/component文件夾下新建一個名為Home.vue的組件褐荷,通過調(diào)用之前在Django上寫好的api,實(shí)現(xiàn)添加書籍和展示書籍信息的功能嘹悼。在樣式組件上我們使用了餓了么團(tuán)隊(duì)推出的element-ui叛甫,這是一套專門匹配Vue.js框架的功能樣式組件。由于組件的編碼涉及到了很多js杨伙、html合溺、css的知識,并不是本文的重點(diǎn)缀台,因此在此只貼出部分代碼:

Home.vue文件代碼:

<template>
<div class="home">
<el-row display="margin-top:10px">
<el-input v-model="input" placeholder="請輸入書名" style="display:inline-table; width: 30%; float:left"></el-input>
<el-button type="primary" @click="addBook()" style="float:left; margin: 2px;">新增</el-button>
</el-row>
<el-row>
<el-table :data="bookList" style="width: 100%" border>
<el-table-column prop="id" label="編號" min-width="100">
<template slot-scope="scope"> {{ scope.row.pk }} </template>
</el-table-column>
<el-table-column prop="book_name" label="書名" min-width="100">
<template slot-scope="scope"> {{ scope.row.fields.book_name }} </template>
</el-table-column>
<el-table-column prop="add_time" label="添加時(shí)間" min-width="100">
<template slot-scope="scope"> {{ scope.row.fields.add_time }} </template>
</el-table-column>
</el-table>
    </el-row>
  </div>
</template>

<script>
export default {
  name: 'home',
  data () {
    return {
      input: '',
      bookList: []
    }
  },
  mounted: function () {
    this.showBooks()
  },
  methods: {
    addBook () {
      this.$http.get('http://127.0.0.1:8000/api/add_book?book_name=' + this.input)
        .then((response) => {
          var res = JSON.parse(response.bodyText)
          if (res.error_num === 0) {
            this.showBooks()
          } else {
            this.$message.error('新增書籍失敗棠赛,請重試')
            console.log(res['msg'])
          }
        })
    },
    showBooks () {
      this.$http.get('http://127.0.0.1:8000/api/show_books')
        .then((response) => {
          var res = JSON.parse(response.bodyText)
          console.log(res)
          if (res.error_num === 0) {
            this.bookList = res['list']
          } else {
            this.$message.error('查詢書籍失敗')
            console.log(res['msg'])
          }
        })
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  h1, h2 {
    font-weight: normal;
  }

  ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

8、在src/router目錄的index.js中膛腐,我們把新建的Home組件睛约,配置到vue-router路由中:

import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/Home'
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    }
  ]
})

9、在src/main.js文件中哲身,導(dǎo)入element-ui辩涝、vue-resource庫。

import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import VueResource from 'vue-resource'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
Vue.use(VueResource)
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

10勘天、如果出現(xiàn)跨域問題怔揩,需要在Django層注入header捉邢,用Django的第三方包django-cors-headers來解決跨域問題:

pip install django-cors-headers

settings.py 修改:


MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ORIGIN_ALLOW_ALL = True

PS: 注意中間件的添加順序。

12商膊、在前端工程frontend目錄下伏伐,輸入npm run dev啟動node自帶的服務(wù)器,瀏覽器會自動打開晕拆, 我們能看到頁面:

13藐翎、嘗試新增書籍,如填入:“自動化測試實(shí)戰(zhàn)寶典”实幕,新增的書籍信息會實(shí)時(shí)反映到頁面的列表中吝镣,這得益于Vue.js的數(shù)據(jù)雙向綁定特性。

14昆庇、在前端工程frontend目錄下末贾,輸入npm run build,如果項(xiàng)目沒有錯誤的話整吆,就能夠看到所有的組件未舟、css、圖片等都被webpack自動打包到dist目錄下了:

八掂为、整合Django和Vue.js前端

目前我們已經(jīng)分別完成了Django后端和Vue.js前端工程的創(chuàng)建和編寫裕膀,但實(shí)際上它們是運(yùn)行在各自的服務(wù)器上,和我們的要求是不一致的勇哗。因此我們須要把Django的`TemplateView指向我們剛才生成的前端dist文件即可昼扛。

1、 找到project目錄的urls.py欲诺,使用通用視圖創(chuàng)建最簡單的模板控制器抄谐,訪問 『/』時(shí)直接返回 index.html:

urlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^api/', include(api_test.urls)),    url(r'^$', TemplateView.as_view(template_name="index.html")),]```

``2、上一步使用了Django的模板系統(tǒng)扰法,所以需要配置一下模板使Django知道從哪里找到index.html蛹含。在project目錄的settings.py下:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS':['frontend/dist'],
        'APP_DIRS':True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

3、 我們還需要配置一下靜態(tài)文件的搜索路徑塞颁。同樣是project目錄的settings.py下:

# Add for vuejs
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "frontend/dist/static"),
]

4浦箱、 配置完成,我們在project目錄下輸入命令python manage.py runserver祠锣,就能夠看到我們的前端頁面在瀏覽器上展現(xiàn):

注意此時(shí)服務(wù)的端口已經(jīng)是Django服務(wù)的8000而不是node服務(wù)的8080了酷窥,說明我們已經(jīng)成功通過Django集成了Vue前端工程。

該實(shí)戰(zhàn)示例為大家充分展示了現(xiàn)在主流的前后端分離方式伴网,由前端框架蓬推,如Vue.js來構(gòu)建實(shí)現(xiàn)前端界面,再通過后端框架澡腾,如Django來實(shí)現(xiàn)API數(shù)據(jù)提供沸伏,兩者通過接口進(jìn)行通訊糕珊、相輔相成、最終實(shí)現(xiàn)一個完整Web項(xiàng)目毅糟。

學(xué)習(xí)來源

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末红选,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子留特,更是在濱河造成了極大的恐慌纠脾,老刑警劉巖玛瘸,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜕青,死亡現(xiàn)場離奇詭異,居然都是意外死亡糊渊,警方通過查閱死者的電腦和手機(jī)右核,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渺绒,“玉大人贺喝,你說我怎么就攤上這事∽诩妫” “怎么了躏鱼?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長殷绍。 經(jīng)常有香客問我染苛,道長,這世上最難降的妖魔是什么主到? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任茶行,我火速辦了婚禮,結(jié)果婚禮上登钥,老公的妹妹穿的比我還像新娘畔师。我一直安慰自己,他們只是感情好牧牢,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布看锉。 她就那樣靜靜地躺著,像睡著了一般塔鳍。 火紅的嫁衣襯著肌膚如雪度陆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天献幔,我揣著相機(jī)與錄音懂傀,去河邊找鬼。 笑死蜡感,一個胖子當(dāng)著我的面吹牛蹬蚁,可吹牛的內(nèi)容都是我干的恃泪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼犀斋,長吁一口氣:“原來是場噩夢啊……” “哼贝乎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叽粹,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤览效,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后虫几,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锤灿,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年辆脸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了但校。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡啡氢,死狀恐怖状囱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情倘是,我是刑警寧澤亭枷,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站搀崭,受9級特大地震影響叨粘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜门坷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一宣鄙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧默蚌,春花似錦冻晤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锦茁,卻和暖如春攘轩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背码俩。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工度帮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓笨篷,卻偏偏與公主長得像瞳秽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子率翅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359

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