react-router

react-router 学习笔记

学习地址

https://github.com/ReactTraining/react-router

准备前工作

  1. 创建一个react项目
 npm install -g create-react-app yarn
  create-react-app antd-demo
   cd antd-demo
  $ yarn start
  1. 下载添加路由
npm i -D react-router react-router-dom

基本功

  1. 添加导航
            <ul>
                <li>
                    <Link to="/">Home</Link>
                </li>
                <li>
                    <Link to="/topics">Topics</Link>
                </li>
            </ul>
  1. 添加导航对应的组件
            <Route exact path="/" component={Home} />
            <Route path="/topics" component={Topics} />
  1. 添加一级组件

// 设置Home组件
const Home = () => (
    <div>
        <h2>Home</h2>
    </div>
);
// 设置 Topics组件
const Topics = ({ match }) => (
    <div>
        <h2>Topics</h2>
        <ul>
            <li>
                <Link to={`${match.url}/rendering`}>Rendering with React</Link>
            </li>
            <li>
                <Link to={`${match.url}/props-v-state`}>Props v. State</Link>
            </li>
        </ul>
        // 设置一个组件,
        <Route path={`${match.url}/:topicId`} component={Topic} />
        // 设置默认组件
        <Route
            exact
            path={match.url}
            render={() => <h3>Please select a topic.</h3>}
        />
    </div>
);
  1. 添加一级组件内二级导航
 <ul>
            <li>
                <Link to={`${match.url}/rendering`}>Rendering with React</Link>
            </li>
            <li>
                <Link to={`${match.url}/props-v-state`}>Props v. State</Link>
            </li>
        </ul>
  1. 添加二级导航组件
 // 设置一个组件,
        <Route path={`${match.url}/:topicId`} component={Topic} />
  1. 添加二级导航默认组件
        // 设置默认组件
        <Route
            exact
            path={match.url}
            render={() => <h3>Please select a topic.</h3>}
        />
  1. 添加二级组件
// 设置二级组件
const Topic = ({ match }) => {
    console.log(match);
    return (
        <h3>{match.url}</h3>
    )
};
  1. 完整示范
  • src/views/basic/index.js
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

// 设置根路由
const BasicExample = () => (
    // 根路由标签
    <Router>
        <div>
            <ul>
                <li>
                    <Link to="/">Home</Link>
                </li>
                <li>
                    <Link to="/topics">Topics</Link>
                </li>
            </ul>

            <hr />
            {/*// 设置跳转的组件*/}
            <Route exact path="/" component={Home} />
            <Route path="/topics" component={Topics} />
        </div>
    </Router>
);
// 设置Home组件
const Home = () => (
    <div>
        <h2>Home</h2>
    </div>
);
// 设置 Topics组件
const Topics = ({ match }) => (
    <div>
        <h2>Topics</h2>
        <ul>
            <li>
                <Link to={`${match.url}/rendering`}>Rendering with React</Link>
            </li>
            <li>
                <Link to={`${match.url}/props-v-state`}>Props v. State</Link>
            </li>
        </ul>
        // 设置一个组件,
        <Route path={`${match.url}/:topicId`} component={Topic} />
        // 设置默认组件
        <Route
            exact
            path={match.url}
            render={() => <h3>Please select a topic.</h3>}
        />
    </div>
);
// 设置二级组件
const Topic = ({ match }) => {
    console.log(match);
    return (
        <h3>{match.url}</h3>
    )
};

export default BasicExample;
  • src/App.js
import React, { Component } from 'react';
import './App.css';
import BasicExample from './views/basic/index.js';
class App extends Component {
  render() {
    return (
      <div className="App">
          <BasicExample></BasicExample>
      </div>
    );
  }
}
export default App;
  1. redirect 与登录验证
  2. 导入包
import React from "react";
import {
    BrowserRouter as Router,
    Route,
    Link,
    Redirect,
    withRouter
} from "react-router-dom";
  1. 添加路由导航
 <ul>
                <li>
                    <Link to="/public">Public Page</Link>
                </li>
                <li>
                    <Link to="/protected">Protected Page</Link>
                </li>
                <li>
                    <Link to="/logout">logout Page</Link>
                </li>
            </ul>
  1. 添加路由组件
{/*// 定义导航对应组件*/}
            <Route path="/public" component={Public} />
            {/*// 未登录的*/}
            <Route path="/login" component={Login} />
            {/*// 登录后的*/}
            <PrivateRoute path="/logout" component={Logout} />
            <PrivateRoute path="/protected" component={Protected} />
  1. 定义路由组件
  • 验证组件
// 判断是否登录, 如果登录, 则显示传递进来的组件, 否则重定向到登录组件
const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route
        {...rest}
        render={props =>
            fakeAuth.isAuthenticated ? (
                <Component {...props} />
            ) : (
                <Redirect
                    to={{
                        pathname: "/login",
                        state: { from: props.location }
                    }}
                />
            )
        }
    />
);
  • Public组件
  • Protected 组件
const Public = () => <h3>Public</h3>;
const Protected = () => <h3>Protected</h3>;
  • 退出组件
class Logout extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            redirectToReferrer: fakeAuth.isAuthenticated
        }
    }
    // 退出
    logout = () => {
        fakeAuth.signout(() => {
            this.setState({ redirectToReferrer: false });
        });
    };
    render() {
        const { from } = this.props.location.state || { from: { pathname: "/" } };
        const { redirectToReferrer } = this.state;
        // 判断是否登录,
        if (!redirectToReferrer) {
            return (<Redirect
                to={{
                    pathname: "/login",
                    state: { from: this.props.location }
                }}
            />)
        }
        // 未登录则提示登录
        return (
            <div>
                <p>You must log in to view the page at {from.pathname}</p>
                <button onClick={this.logout}>Log out</button>
            </div>
        );
    }
}
  • 登录组件
class Login extends React.Component {
    constructor(props){
        super(props)
        this.state = {
            redirectToReferrer: fakeAuth.isAuthenticated
        }
    }
    // 登录, 通过验证,
    login = () => {
        fakeAuth.authenticate(() => {
            this.setState({ redirectToReferrer: true });
        });
    };

    render() {
        const { from } = this.props.location.state || { from: { pathname: "/" } };
        const { redirectToReferrer } = this.state;
        // 判断是否登录,
        if (redirectToReferrer) {
            return <Redirect to={from} />;
        }
        // 未登录则提示登录
        return (
            <div>
                <p>You must log in to view the page at {from.pathname}</p>
                <button onClick={this.login}>Log in</button>
            </div>
        );
    }
}

  1. 验证数据

// 验证函数, 登录登出
const fakeAuth = {
    isAuthenticated: false,
    authenticate(cb) {
        this.isAuthenticated = true;
        setTimeout(cb, 100); // fake async
    },
    signout(cb) {
        this.isAuthenticated = false;
        setTimeout(cb, 100);
    }
};

匹配当前路径

  1. 定义匹配Link组件
- children  返回当前路径, 会与当前route组件进行匹配, 如果匹配, 则返回当了路径match, 否则返回Null
/*
* 有时您需要渲染路径是否与位置匹配。在这些情况下,您可以使用儿童道具功能。它的工作方式与渲染完全相同,只是它会被调用,无论是否匹配。子渲染道具接收与组件和渲染方法相同的所有路径道具,除非路径无法匹配URL,否则匹配为空。这允许您根据路径是否匹配动态调整UI。如果路线匹配,我们在这里添加一个活动类
* */
const OldSchoolMenuLink = ({ label, to, activeOnlyWhenExact }) => (
    <Route
        path={to}
        exact={activeOnlyWhenExact}
        children={({ match }) => {
            return (
                <div className={match ? "active" : ""}>
                 {match ? "> " : ""}
                    <Link to={to}>{label}</Link>
                </div>
            )
        }}
    />
);
  1. 添加导航
<OldSchoolMenuLink activeOnlyWhenExact={true} to="/" label="Home" />
            <OldSchoolMenuLink to="/about" label="About" />
  1. 添加导航对应组件
<Route exact path="/" component={Home} />
            <Route path="/about" component={About} />
  1. 定义组件

const Home = () => (
    <div>
        <h2>Home</h2>
    </div>
);

const About = () => (
    <div>
        <h2>About</h2>
    </div>
);
  1. 完整代码
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import './index.css'
const CustomLinkExample = () => (
    <Router>
        <div>
            <OldSchoolMenuLink activeOnlyWhenExact={true} to="/" label="Home" />
            <OldSchoolMenuLink to="/about" label="About" />
            <hr />
            <Route exact path="/" component={Home} />
            <Route path="/about" component={About} />
        </div>
    </Router>
);

/*
* 有时您需要渲染路径是否与位置匹配。在这些情况下,您可以使用儿童道具功能。它的工作方式与渲染完全相同,只是它会被调用,无论是否匹配。子渲染道具接收与组件和渲染方法相同的所有路径道具,除非路径无法匹配URL,否则匹配为空。这允许您根据路径是否匹配动态调整UI。如果路线匹配,我们在这里添加一个活动类
* */
const OldSchoolMenuLink = ({ label, to, activeOnlyWhenExact }) => (
    <Route
        path={to}
        exact={activeOnlyWhenExact}
        children={({ match }) => {
            console.log(match)
            return (
                <div className={match ? "active" : ""}>
                 {match ? "> " : ""}
                    <Link to={to}>{label}</Link>
                </div>
            )
        }}
    />
);

const Home = () => (
    <div>
        <h2>Home</h2>
    </div>
);

const About = () => (
    <div>
        <h2>About</h2>
    </div>
);

export default CustomLinkExample;

路由配置基础

  1. 引入对应的库
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
  1. 添加路由配置
const routes = [
    {
        path: "/sandwiches",
        component: Sandwiches
    },
    {
        path: "/tacos",
        component: Tacos,
        routes: [
            {
                path: "/tacos/bus",
                component: Bus,
                routes: [
                    {
                        path: "/tacos/bus/bus2",
                        component: Bus2
                    },
                    {
                        path: "/tacos/bus/bus3",
                        component: Bus3
                    }
                    ]
            },
            {
                path: "/tacos/cart",
                component: Cart
            }
        ]
    }
];

  1. 添加一级导航
<ul>
                <li>
                    <Link to="/tacos">Tacos</Link>
                </li>
                <li>
                    <Link to="/sandwiches">Sandwiches</Link>
                </li>
            </ul>
  1. 定义一个渲染当前路由配置的组件

传入一个route, 根据route配置绑定给Route, 并使用render渲染该组件, 其中 route.component 是 route配置中的component, 是Route.render渲染时返回的渲染标签

const RouteWithSubRoutes = route => (
    <Route
        path={route.path}
        render={props =>(
                // pass the sub-routes down to keep nesting
                <route.component {...props} routes={route.routes} />
            )
        }
    />
);
  1. 定义一个循环渲染当前路由数组的组件
  • 该组件值渲染当前数组的一级数组
const renderRoutes = (routes) => {return (routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />))};
  1. 渲染路由
{renderRoutes(routes)}
  1. 定义一级组件
  • Sandwiches组件
const Sandwiches = () => <h2>Sandwiches</h2>;
  • Tacos组件
const Tacos = ({ routes }) => (
    <div>
        <h2>Tacos</h2>
    </div>
);
  1. 准备渲染二级组件, 在路由配置对象内, 只有tacos组件才有子组件, 因此修改tacos组件
  • 这里添加了 二级导航, 和渲染二级导航对应的组件
  • 这里的routes 是render={props =>(<route.component {...props} routes={route.routes} />) 这里的 routes={route.routes}
  • renderRoutes组件是上面定义的组件, 他会帮我们循环routes数组, 然后渲染出当前数组的一维数组的组件
const Tacos = ({ routes }) => (
    <div>
        <h2>Tacos</h2>
        <ul>
            <li>
                <Link to="/tacos/bus">Bus</Link>
            </li>
            <li>
                <Link to="/tacos/cart">Cart</Link>
            </li>
        </ul>
        {renderRoutes(routes)}
    </div>
);
  1. 定义二级组件
  • Bus
const Bus = () => <h3>Bus</h3>;
  • Cart
const Cart = () => <h3>Cart</h3>;

10 二级组件定义好, 从路由配置上, 可以看出, 还有三级组件, 因此修改二级组件, 而在这里, 只有Bus组件才有三级组件, 因此只需要修改Bus组件就好

  • Bus
    跟前面的 Tacos 组件一样, 这里添加了三级导航, 并渲染了三级组件
const Bus = ({routes}) => {
    return (
        <div>
            <h3>Bus constructor
                <ul>
                    <li> <Link to="/tacos/bus/bus2">/tacos/bus/bus2</Link> </li>
                    <li> <Link to="/tacos/bus/bus3">/tacos/bus/bus3</Link> </li>
                </ul>
            </h3>
            {renderRoutes(routes)}
        </div>
    )
};
  1. 定义三级组件
const Bus2 = () => <h3>Bus2</h3>;
const Bus3= () => <h3>Bus3</h3>;
  1. 完整代码
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
// first our route components
const Sandwiches = () => <h2>Sandwiches</h2>;

const Tacos = ({ routes }) => (
    <div>
        <h2>Tacos</h2>
        <ul>
            <li>
                <Link to="/tacos/bus">Bus</Link>
            </li>
            <li>
                <Link to="/tacos/cart">Cart</Link>
            </li>
        </ul>
        {renderRoutes(routes)}
    </div>
);

const renderRoutes = (routes) => {return (routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />))};

const Bus = ({routes}) => {
    console.log(routes)
    return (
        <div>
            <h3>Bus constructor
                <ul>
                    <li> <Link to="/tacos/bus/bus2">/tacos/bus/bus2</Link> </li>
                    <li> <Link to="/tacos/bus/bus3">/tacos/bus/bus3</Link> </li>
                </ul>
            </h3>
            {renderRoutes(routes)}
        </div>
    )
};
const Bus2 = () => <h3>Bus2</h3>;
const Bus3= () => <h3>Bus3</h3>;
const Cart = () => <h3>Cart</h3>;

////////////////////////////////////////////////////////////
// then our route config
const routes = [
    {
        path: "/sandwiches",
        component: Sandwiches
    },
    {
        path: "/tacos",
        component: Tacos,
        routes: [
            {
                path: "/tacos/bus",
                component: Bus,
                routes: [
                    {
                        path: "/tacos/bus/bus2",
                        component: Bus2
                    },
                    {
                        path: "/tacos/bus/bus3",
                        component: Bus3
                    }
                    ]
            },
            {
                path: "/tacos/cart",
                component: Cart
            }
        ]
    }
];

// wrap <Route> and use this everywhere instead, then when
// sub routes are added to any route it'll work
const RouteWithSubRoutes = route => (
    <Route
        path={route.path}
        render={props =>{
            console.log(props)
            console.log(route)
            return (
                // pass the sub-routes down to keep nesting
                <route.component {...props} routes={route.routes} />
            )
        }}
    />
);

const RouteConfigExample = () => (
    <Router>
        <div>
            <ul>
                <li>
                    <Link to="/tacos">Tacos</Link>
                </li>
                <li>
                    <Link to="/sandwiches">Sandwiches</Link>
                </li>
            </ul>

            {renderRoutes(routes)}
        </div>
    </Router>
);

export default RouteConfigExample;

升级路由配置

  1. 定义一个路由配置
const routes = [
    {
        path: "/login",
        name: 'Login',
        component: Login
    },
    {
        path: "/tacos",
        name: 'Tacos',
        component: Tacos,
        routes: [
            {
                path: "/tacos/bus",
                name: "/tacos/bus",
                component: Bus,
                routes: [
                    {
                        path: "/tacos/bus/bus2",
                        name: "/tacos/bus/bus2",
                        component: Bus2
                    },
                    {
                        path: "/tacos/bus/bus3",
                        name: "/tacos/bus/bus3",
                        component: Bus3
                    }
                    ]
            },
            {
                path: "/tacos/cart",
                name: "/tacos/Cart",
                component: Cart
            }
        ]
    }
];
  1. 定义一级导航
 <ul>
                <li>
                    <Link to="/tacos">Tacos</Link>
                </li>
                <li>
                    <Link to="/login">login</Link>
                </li>
            </ul>
  1. 定义一级组件
 {routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />)}
  1. 封装渲染当前组件的组件
const RouteWithSubRoutes = route => (
    <Route
        path={route.path}
        render={props =>{
            return (
                <route.component {...props} routes={route.routes} />
            )
        }}
    />
);
  1. 定义一级组件
  • Login 组件
  • Tacos 组件
const Login = () => <h2>login</h2>;
const Tacos = ({ routes }) => (
    <div >
        <h2>Tacos</h2>
    </div>
);
  1. 根据路由配置, 因为要在 Tacos组件内, 渲染二级组件, 所以需要修改Tacos组件
const Tacos = ({ routes }) => (
    <div >
        <h2>Tacos</h2>
        <ul className="slider">
            {slideMenu(routes)}
        </ul>
        <div className="content">
            {renderRoutes(routes)}
        </div>
    </div>
);
  1. 循环渲染Link组件 slideMenu
  • OldSchoolMenuLink是封装的一层Link, 主要用来匹配当前组件并修改当前选中组件的样式
const slideMenu = (routes) => Array.isArray(routes) && routes.map(item => (
        <li key={item.path}>
            {/*<Link to={item.path}>{item.name}</Link>*/}
            <OldSchoolMenuLink to={item.path} label={item.name} exact={item.exact}></OldSchoolMenuLink>
            {Array.isArray(item.routes) && item.routes.length > 0 && (
                <ul>
                    {slideMenu(item.routes)}
                </ul>
            )}
        </li>
    )
);
  1. 渲染当前路由数组组件
const renderRoutes = (routes) => {return (routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />))};
  1. 定义二级组件
const Bus= () => <h3>Bus</h3>;
const Cart = () => <h3>Cart</h3>;
  1. 修改 Bus组件
  • renderRoutes 这里会渲染当前组件下面的子组件
const Bus = ({routes}) => {
    return (
        <div>
            <h3>Bus constructor
            </h3>
            {renderRoutes(routes)}
        </div>
    )
};
  1. 定义三级组件
const Bus3= () => <h3>Bus3</h3>;
const Cart = () => <h3>Cart</h3>;
  1. 完整代码
  • js
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import './index.css'

// Some folks find value in a centralized route config.
// A route config is just data. React is great at mapping
// data into components, and <Route> is a component.

////////////////////////////////////////////////////////////
// first our route components
const Login = () => <h2>login</h2>;

const Tacos = ({ routes }) => (
    <div >
        <h2>Tacos</h2>
        <ul className="slider">
            {slideMenu(routes)}
        </ul>
        <div className="content">
            {renderRoutes(routes)}
        </div>
    </div>
);

const slideMenu = (routes) => Array.isArray(routes) && routes.map(item => (
        <li key={item.path}>
            {/*<Link to={item.path}>{item.name}</Link>*/}
            <OldSchoolMenuLink to={item.path} label={item.name} exact={item.exact}></OldSchoolMenuLink>
            {Array.isArray(item.routes) && item.routes.length > 0 && (
                <ul>
                    {slideMenu(item.routes)}
                </ul>
            )}
        </li>
    )
);


const renderRoutes = (routes) => {return (routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />))};

const Bus = ({routes}) => {
    return (
        <div>
            <h3>Bus constructor
            </h3>
            {renderRoutes(routes)}
        </div>
    )
};
const Bus2 = () => <h3>Bus2</h3>;
const Bus3= () => <h3>Bus3</h3>;
const Cart = () => <h3>Cart</h3>;

////////////////////////////////////////////////////////////
// then our route config
const routes = [
    {
        path: "/login",
        name: 'Login',
        component: Login
    },
    {
        path: "/tacos",
        name: 'Tacos',
        component: Tacos,
        routes: [
            {
                path: "/tacos/bus",
                name: "/tacos/bus",
                component: Bus,
                routes: [
                    {
                        path: "/tacos/bus/bus2",
                        name: "/tacos/bus/bus2",
                        component: Bus2
                    },
                    {
                        path: "/tacos/bus/bus3",
                        name: "/tacos/bus/bus3",
                        component: Bus3
                    }
                    ]
            },
            {
                path: "/tacos/cart",
                name: "/tacos/Cart",
                component: Cart
            }
        ]
    }
];

const OldSchoolMenuLink = ({ label, to, exact }) => (
    <Route
        path={to}
        exact={exact}
        children={({ match }) => {
            return (
                <React.Fragment >
                    {match ? "> " : ""}
                    <Link to={to} className={match ? "active" : ""}>{label}</Link>
                </React.Fragment>
            )
        }}
    />
);


// wrap <Route> and use this everywhere instead, then when
// sub routes are added to any route it'll work
const RouteWithSubRoutes = route => (
    <Route
        path={route.path}
        render={props =>{
            console.log(props)
            console.log(route)
            return (
                // pass the sub-routes down to keep nesting
                <route.component {...props} routes={route.routes} />
            )
        }}
    />
);

const RouteConfigExample = () => (
    <Router>
        <div>
            <ul>
                <li>
                    <Link to="/tacos">Tacos</Link>
                </li>
                <li>
                    <Link to="/login">login</Link>
                </li>
            </ul>
            {routes.map((route, i) => <RouteWithSubRoutes key={i} {...route} />)}
        </div>
    </Router>
);

export default RouteConfigExample;

  • css
.slider{
    width: 200px;
    float: left;
}
.content {
    width: 100%;
    padding-left: 200px;
}

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

li {
    padding: 0;
    text-align: left;
}
ul>li>ul {
    padding-left: 20px;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容