React Navigation

官方网站

Learn once, navigate anywhere.

React Navigation的诞生,源于React Native社区对基于Javascript的可扩展且使用简单的导航解决方案的需求

只需安装react-navigation的npm package, 就可以开始使用React Navigation了

安装react-navigation

  1. 使用 NPM 安装
    npm install --save react-navigation
    或者使用yarn安装
    yarn add react-navigation

要开始使用React Navigation,您必须先创建一个navigator,React Navigation带有三种默认的navigator。

  • StackNavigator - 为应用程序提供了一种页面切换的方法,每次切换时,新的页面会放置在堆栈的顶部
  • TabNavigator - 用于设置具有多个Tab页的页面
  • DrawerNavigator - 用于设置抽屉导航的页面

StackNavigator

'use strict';
import React,{Component} from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button,
  PixelRatio,
} from 'react-native';
//1. 导入文件
import { StackNavigator } from 'react-navigation';

//2. 编写页面
const HomeScreen = ({navigation}) =>(
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>Home Screen</Text>
            //5. 从Home页面跳转到Details页面
            <Button 
                onPress={()=>navigation.navigate('Details')}
                title='Go to Details'
            ></Button>
        </View>
    );

const Details = ()=>(
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>Details Screen</Text>
        </View>
    );

//3.创建StackNavigator
const RootNavigator = StackNavigator({
    Home:{
        screen:HomeScreen,
        //4. 添加标题
        navigationOptions:{
            headerTitle:'home',
        },
    },
    Details:{
        screen:Details,
        navigationOptions:{
            headerTitle:'details',
        },
    }
});
export default RootNavigator;
效果图
image.png
image.png

TabNavigator

我们将在例子中使用react-native-vector-icons, 如果你的项目中没有安装,请自行安装。

react-native-vector-icons ICONS是矢量图,可以直接使用图片名, 就能加载图片的第三方,使用很方便, 你不需要在工程文件夹里塞各种图片, 节省很多空间,
图片库
图片库
icons 使用

代码
'use strict';
import React,{Component} from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button,
  PixelRatio,
} from 'react-native';
//1. 导入文件
import { createBottomTabNavigator } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';


//2.创建一些页面
const HomeScreen=()=>(
        <View style={{flex:1,alignItems:'center',justifyContent:'center'}}>
            <Text>HomeScreen</Text>
        </View>
    );

const ProfileScreen=()=>(
        <View style={{flex:1,alignItems:'center',justifyContent:'center'}}>
            <Text>ProfileScreen</Text>
        </View>
    );

//3. 添加TabNavigator中
const RootTabs = createBottomTabNavigator({
        Home:{
            screen:HomeScreen,
            navigationOptions:{
                //4. 创建标签
                tabBarLabel:'MyHome',
                //5 .添加图标
                tabBarIcon:({tintColor,focused})=>(
                        <Ionicons 
                            name={focused?'ios-home' : 'md-home'}
                            size={26}
                            style={focused?{ color: tintColor }:{color:'#f00'}}
                        >
                        </Ionicons>
                    ),
            },
        },
        Profile:{
            screen:ProfileScreen,
            navigationOptions:{
                tabBarLabel:'MyProfile',
                tabBarIcon:({tintColor,focused})=>(
                        <Ionicons
                            name={'ios-aperture'}
                            size={26}
                            style={{color:tintColor}}
                        >
                        </Ionicons>
                    ),
            }
        },
    });

//最后导出
export default RootTabs;
效果图
image.png
image.png
出现的几个问题
  1. 消除警告
"Method jumpToIndex is deprecated. Please upgrade your code to use jumpTo instead. Change your code from jumpToIndex(1) to `jumpTo('Parties')."

这个警告的意思是把TabNavigator替换成createBottomTabNavigator
问题解决

import { createBottomTabNavigator } from 'react-navigation';

const RootTabs = createBottomTabNavigator({...});

  1. react-native-vector-icons 使用问题
  • 安装时注意
    npm install react-native-vector-icons --save
    或者
    yarn add react-native-vector-icons

注意:目前npm5存在安装新库时会删除其他库的问题,可能后面会修复导致项目无法正常运行。请尽量使用yarn代替npm操作。

  • 执行以下命令链接原生库
    react-native link react-native-vector-icons

  • ios配置(ios需要单独导入字体文件,安卓link完就可以用了)
    ios必须要配置 如果不配置会报错Unrecognized font family ‘Ionicons’

  • 如果还是报错
    我的解决方法
    node_modules目录找到react-native-vector-icons目录,删除掉,使用yarn命令重新下载,link 命令,ios配置,关闭所有服务,使用xcode安装。问题解决。

DrawerNavigator

代码
'use strict';
import React,{Component} from 'react';
352152
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button,
  PixelRatio,
} from 'react-native';

import { DrawerNavigator } from 'react-navigation';

import Ionicons from 'react-native-vector-icons/Ionicons';


const HomeScreen=({navigation})=>(
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>HomeScreen</Text>
            <Button
                 onPress={()=>(navigation.toggleDrawer())} 
                 title="Open Drawer"
            ></Button>
        </View>
    );

const ProfileScreen=()=>(
        <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}><Text>ProfileScreen</Text></View>
    );

const RootDrawer =DrawerNavigator({
    Home:{
        screen:HomeScreen,
        navigationOptions:{
            drawerLabel:'MyHome',
            drawerIcon:({tintColor, focused })=>(
                <Ionicons                   
                      name={'ios-home'}
                      size={20}
                      style={{ color: tintColor }}
                ></Ionicons>
                ),
        },
    },
    Profile:{
        screen:ProfileScreen,
        navigationOptions:{
            drawerLabel:'MyProfile',
            drawerIcon:({tintColor})=>(
                <Ionicons 
                    name={'ios-person'}
                    size={20}
                    style={{color:tintColor}}
                ></Ionicons>
                ),
        },
    }
});

export default RootDrawer;
效果图

点击Button会打开侧拉菜单

image.png
image.png

嵌套导航

标题仅适用于StackNavigator。 本来想切换tab页面,标题也跟着切换,折腾了半天也没做出来。官方文档说的意思是标题仅适用于StackNavigator

这个例子意思是:StackNavigator导航里面嵌套TabNavigator导航。
把StackNavigator的主页面替换成了TabNavigator两个tab页面,在tab页面点击按钮跳转到StackNavigator导航页面并携带数据。

'use strict';
import React,{Component} from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button,
  PixelRatio,
} from 'react-native';

import { StackNavigator } from 'react-navigation';
import { createBottomTabNavigator } from "react-navigation";

/**
* Home页面
*/
class HomeScreen extends Component{
  static navigationOptions={
    title:'Welcome',
  };

  render(){
    const { navigate } = this.props.navigation;
    return(
        <View>
            <Text>Hello, Navigation!</Text>
            <Button 
                onPress={ ()=>{navigate('Chat',{user:'Lucy'})}}
                title='Chat with Lucy'
            ></Button>
         </View>
      );
  }
}

/**
*   聊天界面
*/
class ChatScreen extends Component{

    static navigationOptions=({navigation})=>({
        title:navigation.state.params.user,
    });
    

    render(){
        const userTitle=this.props.navigation.state.params.user;
        const {params} = this.props.navigation.state;
        return(
            <Text>{params.user}</Text>
            );
    }
}

class RecentChatsScreen extends Component{

    render(){
        return(
            <View>
                <Text>List of recent chats</Text>

                <Button
                    onPress={ () => {this.props.navigation.navigate('Chat',{user:'RecentChatsScreen'})}}
                    title='Chat with Lucy'
                ></Button>
            </View>     
            );
    }
}

class AllContactsScreen extends Component{
    render(){
        return(
            <View>
                <Text>List of all contacts</Text>

                <Button
                    onPress={ () => {this.props.navigation.navigate('Chat',{user:'AllContactsScreen'})}}
                    title='Chat with Lucy'
                ></Button>
            </View>     
            );
    }
}

/**
*   页面嵌套
*/
export const MainScreenNavigator=createBottomTabNavigator({
    Recent:{ 
        screen:RecentChatsScreen,   
        navigationOptions:{
            headerTitle:'My Chat',
        }   
    },
    All:{ 
        screen:AllContactsScreen,
        navigationOptions:{
            headerTitle:'My All',
        }
    },
});


export const SimpleApp=StackNavigator({
  HomeScreen:{
    screen:MainScreenNavigator,
    navigationOptions:{
        title:'My Chats',
        }
  },
  Chat:{
    screen:ChatScreen,
    Navigation:{
    }
  }
});



AppRegistry.registerComponent('MyApp', () => SimpleApp);

需要注意一点

点击按钮打开侧拉侧单下面这种做法是错误的。因为过时了。

<Button
      onPress={() => navigation.navigate('DrawerToggle')}
      title="Open Drawer"
    />

解决办法: 使用最新的API

 onPress={()=>(navigation.toggleDrawer())} 

标题仅适用于StackNavigator。

添加右侧的按钮

'use strict';
import React,{Component} from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button,
  PixelRatio,
  TextInput,
  //屏幕组件与标题的交互 记得导入
  ActivityIndicator,
} from 'react-native';

import { StackNavigator } from 'react-navigation';
import { createBottomTabNavigator } from "react-navigation";

/**
* Home页面
*/
class HomeScreen extends Component{
  static navigationOptions={
    title:'Welcome',
  };

  render(){
    const { navigate } = this.props.navigation;
    return(
        <View>
            <Text>Hello, Navigation!</Text>
            <Button 
                onPress={ ()=>{navigate('Chat',{user:'Lucy'})}}
                title='Chat with Lucy'
            ></Button>
         </View>
      );
  }
}

/**
*   聊天界面
*/
class ChatScreen extends Component{
    static navigationOptions=({navigation})=>{
        console.log(navigation);
        const {state,setParams} = navigation;
        const isInfo = state.params.mode === 'info';
        const {user} = state.params;
        //添加右侧的按钮
        //动态修改标题  和  button的title
        return{
            title: isInfo ? `${user}'s Contact Info` :  `Chat with ${state.params.user}`,
            headerRight:(
                <Button
                    title={isInfo ? 'Done' : `${user}'s info`}
                    onPress={()=>{setParams({mode:isInfo?'none' : 'info'})}}
                ></Button>
                ),
        };
    };
    

    render(){
        console.log(this);
        const userTitle=this.props.navigation.state.params.user;
        const {params} = this.props.navigation.state;
        return(
            <Text>{params.user}</Text>
            );
    }
}

class RecentChatsScreen extends Component{

    render(){
        return(
            <View>
                <Text>List of recent chats</Text>

                <Button
                    onPress={ () => {this.props.navigation.navigate('Chat',{user:'RecentChatsScreen'})}}
                    title='Chat with Lucy'
                ></Button>
            </View>     
            );
    }
}

class AllContactsScreen extends Component{
    render(){
        return(
            <View>
                <Text>List of all contacts</Text>

                <Button
                    onPress={ () => {this.props.navigation.navigate('Chat',{user:'AllContactsScreen'})}}
                    title='Chat with Lucy'
                ></Button>
            </View>     
            );
    }
}

/**
*   页面嵌套
*/
export const MainScreenNavigator=createBottomTabNavigator({
    Recent:{ 
        screen:RecentChatsScreen,   
        navigationOptions:{
            headerTitle:'My Chat',
        }   
    },
    All:{ 
        screen:AllContactsScreen,
        navigationOptions:{
            headerTitle:'My All',
        }
    },
});

/**
*   屏幕组件与标题的交互
*/
class EditInfoScreen extends Component{

    static navigationOptions= ({navigation}) =>{
        // 3 获取navigation state 中 params 属性 使用解构赋值 并设置默认值
        const {params={}} = navigation.state;
        console.log(params);
        console.log(params.handleSave);
        //设置标题右侧按钮 
        let headerRight=(
            <Button 
                title='Save'
                // handleSave 是函数_handlerSave  params.handleSave才会调用函数 
                onPress={params.handleSave? params.handleSave : ()=>null}
            ></Button>
            );
        console.log(params.isSaveing);
        if(params.isSaveing){
            headerRight = <ActivityIndicator/>;
        }
        return {headerRight};
    }

    //2. 编写state属性 存放数据
    state={
        nickName:'fengxing',
    }

    componentDidMount(){
        this.props.navigation.setParams({handleSave:this._handlerSave});
        console.log(this._handlerSave);
    }

    _handlerSave= ()=>{
        console.log('_handlerSave');
        this.props.navigation.setParams({isSaveing:true});

        //saveInfo().then(()=>{
        //  this.props.navigation.setParams({isSaveing:false});
        //});
    }


    render(){
        return(
            //1. 编写组件基本内容 
            <View>
                <TextInput 
                    style={{height: 400, borderColor: 'gray', borderWidth: 1,marginTop:30}}
                    placeholder={'Nickname'}
                    onChangeText={ (nickName) => this.setState({nickName}) }
                    multiline={true}
                    value={this.state.nickName}
                >
                </TextInput>

                <Button 
                    title='点击'
                    onPress = { ()=> this.props.navigation.setParams({isSaveing:false}) }
                    >
                </Button>
            </View>
            );
    }
}


/**
*   输出的视图
*/
export const SimpleApp=StackNavigator({
  HomeScreen:{
    screen:MainScreenNavigator,
    navigationOptions:{
        title:'My Chats',
        }
  },
  Chat:{
    screen:EditInfoScreen,
    Navigation:{
    }
  }
});


AppRegistry.registerComponent('MyApp', () => SimpleApp);

内置导航器

react-navigation包含以下功能来帮助你创建导航器:

  • StackNavigator - 一次只渲染一个页面,并提供页面之间跳转的方法。 当打开一个新的页面时,它被放置在堆栈的顶部
  • TabNavigator - 渲染一个选项卡,让用户可以在几个页面之间切换
  • DrawerNavigator - 提供一个从屏幕左侧滑入的抽屉

StackNavigator

API 定义

StackNavigator(RouteConfigs, StackNavigatorConfig)

RouteConfigs

路由配置对象是从路由名称到路由配置的映射,告诉导航器该路由应该呈现什么。

StackNavigator({

  // For each screen that you can navigate to, create a new entry like this:
  Profile: {

    // `ProfileScreen` is a React component that will be the main content of the screen.
    screen: ProfileScreen,
    // When `ProfileScreen` is loaded by the StackNavigator, it will be given a `navigation` prop.

    // Optional: When deep linking or using react-navigation in a web app, this path is used:
    path: 'people/:name',
    // The action and route params are extracted from the path.

    // Optional: Override the `navigationOptions` for the screen
    navigationOptions: ({navigation}) => ({
      title: `${navigation.state.params.name}'s Profile'`,
    }),
  },

  ...MyOtherRoutes,
});

StackNavigatorConfig

router的选项:

  • initialRouteName - 设置堆栈的默认页面。 必须匹配RouteConfigs中的一个key
  • initialRouteParams - 初始化路由的参数
  • navigationOptions - 用于页面的默认导航选项
  • paths - 用于覆盖RouteConfigs中设置的path的一个映射

视觉选项:

  • mode - 定义页面渲染和转换的风格:
    • card - 使用标准的iOS和Android页面转换风格,此项为缺省。
    • modal - 使页面从屏幕底部滑入,这是一种常见的iOS模式。 只适用于iOS,在Android上不起作用。
  • headerMode - 定义标题该如何渲染:
    • float - 渲染一个放在顶部的标题栏,并在页面改变时显示动画。 这是iOS上的常见模式。
    • screen - 每个页面上都有一个标题栏,标题栏与页面一起淡入淡出。 这是Android上的常见模式。
    • none - 没有标题栏
  • cardStyle - 使用这个属性覆盖或者扩展堆栈中单个Card的默认样式。
  • transitionConfig - 返回一个与默认页面的transitionConfig(参见类型定义)合并的对象的函数。 提供的函数将传递以下参数:
    • transitionProps - 新页面跳转的属性。
    • prevTransitionProps - 上一个页面跳转的属性
    • isModal - 指定页面是否为modal
  • onTransitionStart - card跳转动画开始时要调用的函数。
  • onTransitionEnd - card跳转动画结束时要调用的函数。

Screen Navigation Options

title

可当作headerTitle的备用的字符串。 此外,将用作tabBarLabel(如果嵌套在TabNavigator中)或drawerLabel(如果嵌套在DrawerNavigator中)的后备。

header

可以是React元素或给定了HeaderProps然后返回一个React元素的函数,显示为标题。 设置为null隐藏标题。

headerTitle

字符串、React元素或被当作标题的React组件。默认显示title属性的值。当使用一个组件时,它会收到allowFontScalingstylechildren属性。 标题字符串在children中进行传递。

headerTitleAllowFontScaling

标题栏中标题字体是否应该缩放取决于文本大小是否可以设置。 默认为true。

headerBackTitle

iOS上的返回按钮的文字使用的字符串,或者使用null来禁用。 默认为上一个页面的headerTitle

headerTruncatedBackTitle

headerBackTitle不适合在屏幕显示时(一般是因为文字太多),返回按钮使用的标题字符串。 默认是Back

headerRight

显示在标题栏右侧的React元素。

headerLeft

用于在标题栏左侧展示的React元素或组件。当一个组件被渲染时,它会接收到很多的属性(onPress, title, titleStyle 等等, - 请检查 Header.js 的完整列表)

headerStyle

标题栏的样式

headerTitleStyle

标题栏中标题的样式

headerBackTitleStyle

标题栏中返回按钮标题的样式

headerTintColor

标题栏的色调

headerPressColorAndroid

material design中的波纹颜色 (仅支持Android >= 5.0)

gesturesEnabled

是否可以使用手势来关闭此页面。 在iOS上默认为true,在Android上默认为false。

gestureResponseDistance

一个对象,用以覆盖从屏幕边缘开始触摸到手势被识别的距离。 它具有以下属性:

  • horizontal - 数值型 - 水平方向的距离,默认值25
  • vertical - 数值型 - 垂直方向的距离,默认值135.

字符串,用来设置关闭页面的手势方向,默认(default)是从做往右,inverted是从右往左

/**
*   输出的视图
*/
export const SimpleApp=StackNavigator({
  HomeScreen:{
    screen:MainScreenNavigator,
    navigationOptions:{
        title:'My Chats',
        }
  },
  Chat:{
    screen:EditInfoScreen,
    Navigation:{
    }
  }
},{
    //定义标题该如何渲染 none 没有标题 float 淡入淡出 screen
    headerMode: 'screen',
    //弹出方式
    mode:'modal',

    navigationOptions: {
        //是否可以使用手势来关闭此页面。 在iOS上默认为true,在Android上默认为false。
        gesturesEnabled: false,
   },
    
    //
    transitionConfig:() => ({
        transitionSpec:{
            duration:300,
            easing:Easing.out(Easing.poly(4)),
            timing: Animated.timing,
        }
    })
});

TabNavigator

API 定义

TabNavigator(RouteConfigs, TabNavigatorConfig)

TabNavigatorConfig

  • tabBarComponent - 用作渲染tab bar的组件,例如TabBarBottom(这是iOS上的默认设置),TabBarTop(这是Android上的默认设置)。
  • tabBarPosition - tab bar的位置, 可选值: 'top' or 'bottom'
  • swipeEnabled - 是否允许滑动切换tab页
  • animationEnabled - 是否在切换tab页时使用动画
  • configureTransition - 给定currentTransitionPropsnextTransitionProps的函数,其返回一个配置对象,该对象用于描述tab页之间的动画
  • initialLayout - 可以传递包含初始heightwidth的可选对象,用以防止react-native-tab-view渲染中一个帧的延迟
  • tabBarOptions - 配置tab bar ,详情见下文

传递到底层路由,用于修改导航逻辑的几个选项:

  • initialRouteName - 第一次加载tab bar时路由的routeName
  • order - 定义了tab bar顺序的一个routeNames数组
  • paths - 提供routeNamepath config的映射,它覆盖了routeConfigs中设置的path
  • backBehavior - 返回按钮是否会导致tab切换到初始tab页? 如果是,则设置为initialRoute,否则为none。 缺省为initialRoute

TabBarBottomtabBarOptions (TabBarBottom为iOS的默认tab bar)

  • activeTintColor - 当前选中的tab bar的文本颜色和图标颜色
  • activeBackgroundColor - 当前选中的tab bar的背景色
  • inactiveTintColor - 当前未选中的tab bar的文本颜色和图标颜色
  • inactiveBackgroundColor - 当前未选中的tab bar的背景色
  • showLabel - 是否显示tab bar的文本,默认是true
  • style - tab bar的样式
  • labelStyle - tab bar的文本样式
  • tabStyle - tab页的样式
  • allowFontScaling - 文本字体大小是否可以缩放取决于该设置,默认为true。
tabBarOptions: {
  activeTintColor: '#e91e63',
  labelStyle: {
    fontSize: 12,
  },
  style: {
    backgroundColor: 'blue',
  },
}

TabBarToptabBarOptions (TabBarTop为Android的默认tab bar)

  • activeTintColor - 当前选中的tab bar的文本颜色和图标颜色
  • inactiveTintColor - 当前未选中的tab bar的文本颜色和图标颜色
  • showIcon - 是否显示tab bar的图标,默认是false
  • showLabel - 是否显示tab bar的文本,默认是true
  • upperCaseLabel - 是否将文本转换为大小,默认是true
  • pressColor - material design中的波纹颜色(仅支持Android >= 5.0)
  • pressOpacity - 按下tab bar时的不透明度(仅支持iOS和Android < 5.0).
  • scrollEnabled - 是否允许滑动切换
  • tabStyle - tab页的样式
  • indicatorStyle - tab 页指示符的样式 (tab页下面的一条线).
  • labelStyle - tab bar的文本样式
  • iconStyle - tab bar的图标样式
  • style - tab bar的样式
  • allowFontScaling - 文本字体大小是否可以缩放取决于该设置,默认为true。

栗子:

tabBarOptions: {
  labelStyle: {
    fontSize: 12,
  },
  tabStyle: {
    width: 100,
  },
  style: {
    backgroundColor: 'blue',
  },
}

Screen Navigation Options

title

可以用作headerTitletabBarLabel后备的通用标题。(headerTitletabBarLabel未设置时,就会使用title的值替代)

tabBarVisible

tab bar是否可见,缺省是true

swipeEnabled

是否允许tab页之间滑动切换,如果未设置,则使用TabNavigatorConfigswipeEnabled选项

tabBarIcon

用于在tab bar中展示的React元素或一个传入{ focused: boolean, tintColor: string }返回React.Node的函数

tabBarLabel

用于在tab bar中展示的一个字符串或者一个传入{ focused: boolean, tintColor: string }返回React.Node的函数,如果未定义,则使用页面的title属性。如果像隐藏文本,请参阅上一小节中讲到的tabBarOptions.showLabel

tabBarOnPress

tab被点击时的回调函数;参数是一个对象,包含一下属性:

  • previousScene: { route, index } :正在离开的页面
  • scene: { route, index } 被点击的页面
  • jumpToIndex 执行跳转操作必须的参

DrawerNavigator

使用...navigate('DrawerOpen')和...navigate('DrawerClose')打开和关闭抽屉

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

推荐阅读更多精彩内容