react基礎(chǔ)學(xué)習(xí)和react服務(wù)端渲染框架next.js踩坑

react、next

說(shuō)明

React作為Facebook 內(nèi)部開發(fā) Instagram 的項(xiàng)目中,是一個(gè)用來(lái)構(gòu)建用戶界面的優(yōu)秀 JS 庫(kù),于 2013 年 5 月開源。作為前端的三大框架之一豪嚎,React的應(yīng)用可以說(shuō)是非常的廣泛。這里講一個(gè)react服務(wù)端渲染的框架-next.js踩坑過(guò)程谈火。

技術(shù)棧

react侈询、next.js、ant design堆巧、axios

大綱

按照以下思路來(lái)寫:

react妄荔、next

react基本語(yǔ)法

react基本語(yǔ)法參照react文檔,這里發(fā)放一個(gè)鏈接https://doc.react-china.org/谍肤。

以下是React重要的部分

  • JSX – 允許我們編寫類似HTML的語(yǔ)法啦租,轉(zhuǎn)換為JavaScript對(duì)象;
  • 虛擬DOM – 實(shí)際DOM的JavaScript表示荒揣;
  • React.Component – 創(chuàng)建新組件的方式篷角;
  • render(方法) – 渲染組件;
  • ReactDOM.render – 用于將模板轉(zhuǎn)為 HTML 語(yǔ)言系任,并插入指定的 DOM 節(jié)點(diǎn)恳蹲;
  • state – 組件的內(nèi)部數(shù)據(jù)存儲(chǔ)(對(duì)象)虐块,類型理解vue的data;
  • constructor(this.state) – 建立組件初始 state(狀態(tài)) 的方式嘉蕾;
  • setState – 一種輔助方法贺奠,用于更新組件的 state(狀態(tài)) 并重新渲染,類似微信小程序错忱;
  • props – 從父組件傳遞給子組件的數(shù)據(jù)儡率;
  • propTypes – 允許您控制傳遞給子組件的某些 props(屬性) 的存在或類型;
  • defaultProps – 允許您為組件設(shè)置默認(rèn) props(屬性) 以清;
  • className - 節(jié)點(diǎn)的class儿普,css標(biāo)記
  • style jsx樣式控制

jsx語(yǔ)法

直接寫在 JavaScript 語(yǔ)言之中,不加任何引號(hào)掷倔,它允許 HTML 與 JavaScript 的混寫眉孩。

//demo-1.js
import React from 'react';
class Demo1 extends React.Component{
  render(){
    const lists = ['我是誰(shuí)','我來(lái)自哪里','我要到哪兒去'];
    return(
      <div className="list">
        <ul>
          {
            lists.map((list,index)=>{
              return(
                <li key={index}>{list}</li>
              )
            })
          }  
        </ul>
      </div>
    )
  }
}

export default Demo1;

上面代碼體現(xiàn)了 JSX 的基本語(yǔ)法規(guī)則:遇到 HTML 標(biāo)簽(以 < 開頭),就用 HTML 規(guī)則解析勒葱;遇到代碼塊(以 { 開頭)浪汪,就用 JavaScript 規(guī)則解析,其中注意一點(diǎn)react沒有vue中v-for遍歷错森,需要自己寫遍歷吟宦。上面代碼的運(yùn)行結(jié)果如下:

頁(yè)面渲染效果

組件及組件傳值

//demo-2.js
import React from 'react';

class MyComponent extends React.Component{
  render(){
    return (
      <h1>{this.props.name}</h1>
    )
  }
}

class Demo2 extends React.Component{
  render(){
    const lists = ['我是誰(shuí)','我來(lái)自哪里','我要到哪兒去'];
    return(
      <div className="list">
        <ul>
          {
            lists.map((list,index)=>{
              return(
                <li key={index}>
                  <MyComponent name={list}></MyComponent>
                </li>
              )
            })
          }  
        </ul>
        
      </div>
    )
  }
}

export default Demo2;

React 允許將代碼封裝成組件(component)篮洁,然后像插入普通 HTML 標(biāo)簽一樣涩维,在網(wǎng)頁(yè)中插入這個(gè)組件。以上代碼中MyComponent即為組件袁波,需要注意的一點(diǎn)組件類的第一個(gè)字母必須大寫瓦阐,否則會(huì)報(bào)錯(cuò),組件類只能包含一個(gè)頂層標(biāo)簽篷牌,否則也會(huì)報(bào)錯(cuò)睡蟋。vue通過(guò)子組件中的props來(lái)傳遞數(shù)據(jù),而React則是用this.props.name來(lái)傳遞。下圖為渲染頁(yè)面效果:

渲染頁(yè)面效果

React之ref(獲取真實(shí)的DOM節(jié)點(diǎn))

  • 同vue的ref作用一樣枷颊,組件并不是真實(shí)的DOM節(jié)點(diǎn)戳杀,而是存在于內(nèi)存之中的一種數(shù)據(jù)結(jié)構(gòu),叫做虛擬 DOM夭苗。
  • 只有當(dāng)它插入文檔以后信卡,才會(huì)變成真實(shí)的 DOM 。根據(jù) React的設(shè)計(jì)题造,所有的DOM 變動(dòng)傍菇,都先在虛擬 DOM上發(fā)生,然后再將實(shí)際發(fā)生變動(dòng)的部分界赔,反映在真實(shí) DOM上丢习,這種算法叫做 DOM diff 牵触,它可以極大提高網(wǎng)頁(yè)的性能表現(xiàn)。
  • 有時(shí)需要從組件獲取真實(shí) DOM 的節(jié)點(diǎn)咐低,這時(shí)就要用到 ref 屬性揽思。
//dem0-3.
import React from 'react';

class Demo3 extends React.Component{
  handleClick(){
    this.refs.myTextInput.focus();
  }
  render(){
    return(
      <div>
        <input type="text" ref="myTextInput" />
        <br/>
        <input type="button" value="Focus the text input" onClick={this.handleClick.bind(this)} />
      </div>
    )
  }
}

export default Demo3;

在這里需要注意的是:

  • React的事件中如果不用剪頭函數(shù)见擦,那就要用bind來(lái)綁定this绰更,否則需要在constructor構(gòu)造函數(shù)里調(diào)用this.handleClick = this.handleClick.bind(this),這里建議用onClick={this.handleClick.bind(this)}锡宋。
  • 由于 this.refs.[refName] 屬性獲取的是真實(shí) DOM 儡湾,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個(gè)屬性执俩,否則會(huì)報(bào)錯(cuò)徐钠。上面代碼中,通過(guò)為組件指定 Click 事件的回調(diào)函數(shù)役首,確保了只有等到真實(shí) DOM 發(fā)生 Click 事件之后尝丐,才會(huì)讀取 this.refs.[refName] 屬性。
demo3

React之this.state以及點(diǎn)擊事件

React中的state就相當(dāng)于vue里的data數(shù)據(jù)存儲(chǔ),而小程序的this.setData就和React的this.setState類似衡奥。

//demo-4.js
import React from 'react';

class Demo4 extends React.Component{
  // constructor(props){
  //   super(props)
  //   this.state = {
  //     liked:false
  //   }
  // }
  state = {
    liked: false
  }
  handleClick(){
    this.setState({liked: !this.state.liked});
  }
  render(){
    let text = this.state.liked ? '喜歡' : '不喜歡';
    return(
      <div>
        <p onClick={this.handleClick.bind(this)}>
          你 {text} 這個(gè)點(diǎn)擊.
        </p>
      </div>
    )
  }
}

export default Demo4;

上面代碼是一個(gè) LikeButton 組件爹袁,它的 constructor 方法(或者直接state聲明)用于定義初始狀態(tài),也就是一個(gè)對(duì)象矮固,這個(gè)對(duì)象可以通過(guò) this.state 屬性讀取失息。當(dāng)用戶點(diǎn)擊組件,導(dǎo)致狀態(tài)變化档址,this.setState 方法就修改狀態(tài)值盹兢,每次修改以后,自動(dòng)調(diào)用 this.render 方法守伸,再次渲染組件绎秒。

由于 this.props 和 this.state 都用于描述組件的特性,可能會(huì)產(chǎn)生混淆尼摹。一個(gè)簡(jiǎn)單的區(qū)分方法是见芹,this.props 表示那些一旦定義,就不再改變的特性蠢涝,而 this.state 是會(huì)隨著用戶互動(dòng)而產(chǎn)生變化的特性玄呛。

demo4.gif

利用input的onChange事件實(shí)現(xiàn)簡(jiǎn)單的雙向綁定

vue里面v-model一鍵實(shí)現(xiàn)的事情React沒有,我們可以利用input組件的onChange事件來(lái)簡(jiǎn)單實(shí)現(xiàn)它惠赫,直接上代碼把鉴。

//Demo5.js
import React from 'react';

class Demo5 extends React.Component{
  // constructor(props){
  //   super(props)
  //   this.state = {
  //     text:''
  //   }
  // }
  state = {
    text: ''
  }
  handleChange(e){
    this.setState(
      {text: e.target.value}
    );
  }
  render(){
    return(
      <div>
        <p>
          你輸入了{(lán)this.state.text}
        </p>
        <input type="text" placeholder="請(qǐng)輸入..." onChange={this.handleChange.bind(this)}/>
      </div>
    )
  }
}

export default Demo5;
demo5.gif

組件的生命周期

組件的生命周期.png

一個(gè)React組件的生命周期分為三個(gè)部分:掛載期(Mounting)、存在更新期(Updating)和銷毀時(shí)(Unmounting)。

  • Mounting:已插入真實(shí) DOM

    當(dāng)一個(gè)組件實(shí)例被創(chuàng)建并且插入到DOM中庭砍,以下鉤子將被調(diào)用 constructor()
    繼承react的props场晶,和設(shè)置state的初始化。

constructor(props) {
  super(props); //不能缺少
  this.state = {
    color: props.initialColor
  };
}
  • Updating:當(dāng)組件的props和state發(fā)生改變時(shí)怠缸,重新渲染頁(yè)面是調(diào)用的诗轻。
  • Unmounting:組件從DOM中移動(dòng)時(shí)調(diào)用的。
React 為每個(gè)狀態(tài)都提供了兩種處理函數(shù)揭北,will 函數(shù)在進(jìn)入狀態(tài)之前調(diào)用扳炬,
did 函數(shù)在進(jìn)入狀態(tài)之后調(diào)用,三種狀態(tài)共計(jì)五種處理函數(shù)搔体。
  • componentWillMount()
  • componentDidMount()
  • componentWillUpdate(object nextProps, object nextState)
  • componentDidUpdate(object prevProps, object prevState)
  • componentWillUnmount()

事件

  • onClick-點(diǎn)擊事件
  • onSubmit-表單提交事件恨樟,可以配合antdesign的表單校驗(yàn)
  • onChange-input框數(shù)據(jù)變化,可實(shí)現(xiàn)數(shù)據(jù)的雙向綁定(react里沒有vue的v-modal)

style jsx

我們可以通過(guò)普通樣式(className)和行內(nèi)樣式(LineStyle)控制React組件的樣式:

  • 使用className設(shè)置樣式(與CSS的選擇器相同)
import React from 'react';
// import styles from '../../static/css/demo.css'

class Demo6 extends React.Component{
  // constructor(props){
  //   super(props)
  //   this.state = {
  //     text:''
  //   }
  // }
  state = {
    text: ''
  }
  handleChange(e){
    this.setState(
      {text: e.target.value}
    );
  }
  render(){
    return(
      <div>
        <p className="style">
          你輸入了{(lán)this.state.text}
        </p>
        <input className="input" type="text" placeholder="請(qǐng)輸入..." onChange={this.handleChange.bind(this)}/>
        <style jsx>
          {
            ` .style {
                background: #dcdcdc;
                font-size: 20px;
                height:40px;
                line-height:40px;
                padding:0 2%;
              }
              .input{
                width:96%;
                height:40px;
                padding:0 2%;
              }
            `
          }
        </style>
      </div>
    )
  }
}

export default Demo6;
demo6

為什么要用next

Next.js是一個(gè)基于React的一個(gè)服務(wù)端渲染簡(jiǎn)約框架疚俱。它使用React語(yǔ)法劝术,可以很好的實(shí)現(xiàn)代碼的模塊化,有利于代碼的開發(fā)和維護(hù)呆奕。

  • 默認(rèn)服務(wù)端渲染模式养晋,以文件系統(tǒng)為基礎(chǔ)的客戶端路由,類似nuxt.js梁钾;

  • 與nuxt.js相同绳泉,pages文件目錄即路由;

  • 以webpack的熱替換為基礎(chǔ)的開發(fā)環(huán)境(npm run dev)姆泻;

next創(chuàng)建的項(xiàng)目目錄結(jié)構(gòu)

next創(chuàng)建的項(xiàng)目目錄結(jié)構(gòu).png

next路由

  • 默認(rèn)從 pages 目錄下取頁(yè)面進(jìn)行渲染返回給前端展示零酪,路由可以使用Link(無(wú)刷新頁(yè)面)或者a標(biāo)簽(刷新頁(yè)面)
//pages/router.js
import Link from 'next/link';

<Link prefetch href='/about?id=11'>
    <a >Link</a>
</Link>

<a href="/about?id=11">Link</a>
  • 接收參數(shù):getInitialProps方法context參數(shù)或者{props.query.id},同時(shí)在getInitialProps 里面獲取數(shù)據(jù)麦射,服務(wù)端渲染會(huì)提前執(zhí)行這個(gè)方法獲取數(shù)據(jù)渲染到模板蛾娶,這里用到axios庫(kù)灯谣,前后端都可以使用
//pages/test.js http://localhost:3000/test
import React from 'react';
import MyHeader from '../components/MyHeader';
import axios from '../lib/axios';
import { bmobConfigDevdev, bmobConfig } from '../lib/config';
import urls from '../lib/urls';

import { Table, Form, Icon, Input, Button } from 'antd';
const FormItem = Form.Item;

const config1 = {
  headers: {
    'X-Bmob-Application-Id': bmobConfig.applicationId,
    'X-Bmob-REST-API-Key': bmobConfig.restApiKey,
    'Content-Type': 'application/json'
  }
};

const config2 = {
  headers: {
    'X-Bmob-Application-Id': bmobConfigDevdev.applicationId,
    'X-Bmob-REST-API-Key': bmobConfigDevdev.restApiKey,
    'Content-Type': 'application/json'
  }
};

const myStyle = {
  body: {
    width: '1200px',
    margin: '10px auto'
  }
}

const columns = [{
  title: 'id',
  dataIndex: 'objectId',
  key: 'objectId',
}, {
  title: '姓名',
  dataIndex: 'uname',
  key: 'uname',
}, {
  title: '電話',
  dataIndex: 'uphone',
  key: 'uphone',
}, {
  title: '地址',
  dataIndex: 'address',
  key: 'address',
}];

const dataSource = [{
  key: '1',
  name: '胡彥斌',
  age: 32,
  address: '西湖區(qū)湖底公園1號(hào)'
}, {
  key: '2',
  name: '胡彥祖',
  age: 42,
  address: '西湖區(qū)湖底公園1號(hào)'
}];

//封裝form組件
const MyForm = (props) => (
  <Form layout="inline" onSubmit={this.handleSubmit}>
    <FormItem>
      <Button
        type="primary"
        htmlType="submit"
      >
        增加數(shù)據(jù)
      </Button>
    </FormItem>
  </Form>
)

//聲明類
class addDeleteSelectUpdate extends React.Component {

  render() {
    return (
      <MyHeader title="用戶列表">
        <div style={myStyle.body}>
          <p className="about">傳遞的參數(shù)為:{this.props.query}</p>
          <p className="about">增加數(shù)據(jù)</p>
          <MyForm ></MyForm>
          <p className="about">獲取數(shù)據(jù){this.props.dataToString}</p>
          <Table dataSource={this.props.data} columns={columns} size="small" />
          <div className="">
            <p className="about">遍歷</p>
            <ul>
              {
                this.props.data.map(els => {
                  return (
                    <li key={els.objectId}>
                      {els.address}
                    </li>
                  )
                })
              }
            </ul>
          </div>
          <style jsx>
            {`
              .about {color:#666;padding:10px}
            `}
          </style>
        </div>
      </MyHeader>
    )
  }
}

/**
 * @description 獲取初始數(shù)據(jù)
 */
const isServer = typeof window === 'undefined'

addDeleteSelectUpdate.getInitialProps = async function (context) {
  console.log(context.query);
  const res = await axios.get(urls.userList, config1)
  console.log(res.data);
  var query = context.query;
  return {
    data: res.data.results,
    dataToString: JSON.stringify(res.data.results),
    query: JSON.stringify(context.query)
  }
}

export default addDeleteSelectUpdate;

數(shù)據(jù)請(qǐng)求-axios配置

Axios 是一個(gè)基于 promise 的 HTTP 庫(kù)潜秋,可以用在瀏覽器和 node.js 中。

axios具有以下幾個(gè)特點(diǎn):

  • 既可以在服務(wù)端使用又可以在瀏覽器端使用胎许;
  • 支持 Promise API(async await峻呛,解決地獄回調(diào));
  • 攔截請(qǐng)求和響應(yīng)(401跳轉(zhuǎn)登錄等操作)辜窑;
  • 轉(zhuǎn)換請(qǐng)求數(shù)據(jù)和響應(yīng)數(shù)據(jù)钩述;
  • 自動(dòng)轉(zhuǎn)換 JSON 數(shù)據(jù)。

以下為axios配置代碼:

//lib/axios.js
import axios from 'axios';
import NProgress from 'nprogress';

axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest';
axios.defaults.withCredentials = true;
axios.defaults.timeout = 5000;

//請(qǐng)求之前
axios.interceptors.request.use((config)=>{
  if(process.broswer) NProgress.start()//加一個(gè)loading
  return config;
});

//
axios.interceptors.response.use(
  response => {
    // console.log('-------axiosResponse---------')
    if(process.broswer) NProgress.done()
    return response;
  },
  error => {
    // console.log('-------axiosError---------:');
    // console.log(error.response.status==401)
    if(process.broswer) NProgress.done()
    if(error.response&&error.response.status==401){
      window.location.href="/login";//登錄失效跳轉(zhuǎn)
    }
    return Promise.reject(error);
  }
);

export default axios;

使用時(shí)在頁(yè)面引入axios配置文件axios.js穆碎,具體的axios配置可以參考link-axios文檔牙勘。

//pages/login.js
import axios from '../lib/axios';
...

axios.post(urls.login,qs.stringify(obj))
.then(res=>{
    console.log(res);
    Router.push('/contract/list');
})
.catch(error=>{
    console.log(error);
})
...

數(shù)據(jù)請(qǐng)求-開發(fā)環(huán)境代理

前后端分離以后,前端最常見的一個(gè)問(wèn)題就是跨域,之前的om項(xiàng)目基于nuxt可以配置proxy方面,在next.js里需要用到express和http-proxy-middleware在服務(wù)端(node)端做一層轉(zhuǎn)發(fā)放钦,代碼配置如下:

//server.js
var express =require('express');
var next = require('next');

const devProxy = {
  '/api': {
    target: 'http://39.107.58.75:9092/',// 目標(biāo)服務(wù)器 host
    pathRewrite: {'^/api': '/'}, // 重寫請(qǐng)求,比如我們?cè)丛L問(wèn)的是api/login恭金,那么請(qǐng)求會(huì)被解析為/www/login
    changeOrigin: true,// 默認(rèn)false操禀,是否需要改變?cè)贾鳈C(jī)頭為目標(biāo)URL
  },
  '/jt':{
    target: 'https://api.dededemo.com/plus/weapp.php?action=index&domain=http://23jt.net&skin=weapp&ver=3.0&page=1',// 目標(biāo)服務(wù)器 host
    // pathRewrite: {'^/api': '/'}, // 重寫請(qǐng)求,比如我們?cè)丛L問(wèn)的是api/login横腿,那么請(qǐng)求會(huì)被解析為/www/login
    changeOrigin: true,// 默認(rèn)false颓屑,是否需要改變?cè)贾鳈C(jī)頭為目標(biāo)URL
  }
}

const port = parseInt(process.env.PORT, 10) || 3000
const env = process.env.NODE_ENV
const dev = env !== 'production'
const app = next({
  dir: '.', // base directory where everything is, could move to src later
  dev
})

const handle = app.getRequestHandler()

let server
app
  .prepare()
  .then(() => {
    server = express()
      
    // Set up the proxy.
    if (dev && devProxy) {
      const proxyMiddleware = require('http-proxy-middleware')
      Object.keys(devProxy).forEach(function (context) {
        server.use(proxyMiddleware(context, devProxy[context]))
      })
    }

    // Default catch-all handler to allow Next.js to handle all other routes
    server.all('*', (req, res) => {
        req.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        req.headers['X-Requested-With'] = 'XMLHttpRequest';
        handle(req, res);
        // console.log(req.body);
      }
    )

    server.listen(port, err => {
      if (err) {
        throw err
      }
      console.log(`> Ready on port ${port} [${env}]`)
    })
  })
  .catch(err => {
    console.log('An error occurred, unable to start the server')
    console.log(err)
  })

配置完server.js后還需要在packge.json中配置啟動(dòng)腳本:

"devdev": "cross-env NODE_ENV=development PORT=9527 node server.js",

注意上線后需要在ngnix里配置反向代理,就不存在跨域的問(wèn)題耿焊。

在next.js里使用ant design

  • babel配置
//.babelrc
{
  "presets": [
    "next/babel"
  ],
  "plugins": [
    [
      "module-resolver", {
      "root": ["."],
      "alias": {
        "styles": "./styles"
      },
      "cwd": "babelrc"
    }],
    ["import", { "libraryName": "antd" }]
  ],
  "ignore": []
}
  • 引用ant design組件揪惦,需要用到ant design什么組件按照自己需要引用即可,各個(gè)組件使用方法參考ant design的link-官方文檔
import {Form, Icon,Input, Button, Checkbox, message} from 'antd'; 

部署一個(gè)next.js項(xiàng)目

Next.js 項(xiàng)目的部署罗侯,需要一個(gè) Node.js的服務(wù)器丹擎。
在開發(fā)環(huán)境服務(wù)器的入口文件就使用上文中提到的 server.js,在 server.js 里添加了針對(duì)部署環(huán)境的選擇歇父,代碼如下

const dev = process.env.NODE_ENV !== 'production'

為了區(qū)分部署環(huán)境蒂培,我們需要在 package.json 中修改 script 屬性如下:

"scripts": {
    "dev": "next",
    "devdev": "cross-env NODE_ENV=development PORT=9527 node server.js",
    "build": "next build",
    "start": "next start",
    "generate": "next build && next export",
    "export-h":"next export -h"
  },

其中,build 命令是用于打包項(xiàng)目榜苫,start 命令是用于生產(chǎn)環(huán)境部署护戳,devdev 命令是用于本地開發(fā),PORT為啟動(dòng)端口垂睬。

注意的幾個(gè)點(diǎn)

  • 增加第三方npm包必須加上--save關(guān)鍵字媳荒,會(huì)pakage.json文件里加入依賴包;
//如增加js-md5庫(kù)
$ npm install js-md5 --save
  • 組件名稱必須以大寫字母開頭驹饺,如MyHeader钳枕;
  • React的事件中如果不用剪頭函數(shù),那就要用bind來(lái)綁定this赏壹,否則需要在constructor構(gòu)造函數(shù)里調(diào)用this.handleClick = this.handleClick.bind(this)鱼炒,這里建議用onClick={this.handleClick.bind(this)}。

總結(jié)

只要熟悉React開發(fā)蝌借,上手一個(gè)Next項(xiàng)目很容易昔瞧,Next 讓前端項(xiàng)目開發(fā)效率更高。

參考資料

更多

更多前端技術(shù)請(qǐng)?jiān)L問(wèn)我的博客:https://hurely.github.io

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末菩佑,一起剝皮案震驚了整個(gè)濱河市自晰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌稍坯,老刑警劉巖酬荞,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡混巧,警方通過(guò)查閱死者的電腦和手機(jī)糟把,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牲剃,“玉大人遣疯,你說(shuō)我怎么就攤上這事≡涓担” “怎么了缠犀?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)聪舒。 經(jīng)常有香客問(wèn)我辨液,道長(zhǎng),這世上最難降的妖魔是什么箱残? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任滔迈,我火速辦了婚禮,結(jié)果婚禮上被辑,老公的妹妹穿的比我還像新娘燎悍。我一直安慰自己,他們只是感情好盼理,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布谈山。 她就那樣靜靜地躺著,像睡著了一般宏怔。 火紅的嫁衣襯著肌膚如雪奏路。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天臊诊,我揣著相機(jī)與錄音鸽粉,去河邊找鬼。 笑死抓艳,一個(gè)胖子當(dāng)著我的面吹牛触机,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播壶硅,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼威兜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了庐椒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蚂踊,失蹤者是張志新(化名)和其女友劉穎约谈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棱诱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年泼橘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片迈勋。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡炬灭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出靡菇,到底是詐尸還是另有隱情重归,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布厦凤,位于F島的核電站鼻吮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏较鼓。R本人自食惡果不足惜椎木,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望博烂。 院中可真熱鬧香椎,春花似錦、人聲如沸禽篱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)谆级。三九已至烤礁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肥照,已是汗流浹背脚仔。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留舆绎,地道東北人鲤脏。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吕朵,于是被迫代替她去往敵國(guó)和親猎醇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353