React-Native操作随笔(一)

开发平台:macOS

搭建开发环境

  • 必需软件

Homebrew, Mac系统的包管理器,用于安装NodeJS和一些其他必需的工具软件。

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Node.js,一种javascript的运行环境,能够使得javascript脱离浏览器运行。
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
Node.js 的包管理器 npm(Node Package Manager),是全球最大的开源库生态系统。

$ brew install node

Yarn,Facebook提供的替代npm的工具,可以加速node模块的下载。
$ brew install yarn$ npm install -g yarn

react-native-cli,React Native轻量级的命令行工具,用于执行创建、初始化、更新项目、运行打包服务(packager)等任务。
$ npm install -g react-native-cli

Xcode7.0 或更高版本

  • 推荐安装

Watchman是由Facebook提供的监视文件系统变更的工具。安装此工具可以提高开发时的性能(packager可以快速捕捉文件的变化从而实现实时刷新)。译注:此工具官方虽然是推荐安装,但在实践中,我们认为此工具是必须安装,否则可能无法正常开发。
brew install watchman

Flow是一个静态的JS类型检查工具。译注:你在很多示例中看到的奇奇怪怪的冒号问号,以及方法参数中像类型一样的写法,都是属于这个flow工具的语法。这一语法并不属于ES标准,只是Facebook自家的代码规范。所以新手可以直接跳过(即不需要安装这一工具,也不建议去费力学习flow相关语法)。
brew install flow

Nuclide是由Facebook提供的基于atom的集成开发环境,可用于编写、运行调试React Native应用。
但是推荐使用WebStormSublime TextVisual Studio Code来编写React Native应用。所有这些开发工具都是跨平台的。其中webstorm是收费的(勤劳的人自然免费了),体量较大,功能较多,基本无需配置,必然是首选。其他工具免费,相对轻量,但或多或少需要下载插件和配置。

快速创建

react-native init AwesomeProject
cd AwesomeProject
react-native run-ios

可以使用--version参数(注意是两个杠)创建指定版本的项目。例如$ react-native init MyApp --version 0.44.3。注意版本号必须精确到两个小数点。
可以使用--simulator参数指定模拟器。例如$ react-native run-ios --simulator "iPhone X"

查看使用帮助:

$ react-native --help
Scanning folders for symlinks in /Users/mxr/Desktop/XDS/RN/AwesomeProject/node_modules (12ms)

  Usage: react-native [options] [command]

  Options:

    -V, --version                      output the version number
    -h, --help                         output usage information

  Commands:

    start [options]                    starts the webserver
    run-ios [options]                  builds your app and starts it on iOS simulator
    run-android [options]              builds your app and starts it on a connected Android emulator or device
    new-library [options]              generates a native library bridge
    bundle [options]                   builds the javascript bundle for offline use
    unbundle [options]                 builds javascript as "unbundle" for offline use
    eject [options]                    Re-create the iOS and Android folders and native code
    link [options] [packageName]       links all native dependencies (updates native build files)
    unlink [options] <packageName>     unlink native dependency
    install [options] <packageName>    install and link native dependencies
    uninstall [options] <packageName>  uninstall and unlink native dependencies
    upgrade [options]                  upgrade your app's template files to the latest version; run this after updating the react-native version in your package.json and running npm install
    log-android [options]              starts adb logcat
    log-ios [options]                  starts iOS device syslog tail
    dependencies [options]             lists dependencies
    info [options]                     Get relevant version info about OS, toolchain and libraries
$ react-native run-ios --help
Scanning folders for symlinks in /Users/mxr/Desktop/XDS/RN/AwesomeProject/node_modules (12ms)

  react-native run-ios [options]
  builds your app and starts it on iOS simulator

  Options:

    --simulator [string]      Explicitly set simulator to use (default: iPhone 6)
    --configuration [string]  Explicitly set the scheme configuration to use
    --scheme [string]         Explicitly set Xcode scheme to use
    --project-path [string]   Path relative to project root where the Xcode project (.xcodeproj) lives. The default is 'ios'. (default: ios)
    --device [string]         Explicitly set device to use by name.  The value is not required if you have a single device connected.
    --udid [string]           Explicitly set device to use by udid
    --no-packager             Do not launch packager while building
    --verbose                 Do not use xcpretty even if installed
    --port [number]            (default: 8081)
    --config [string]         Path to the CLI configuration file
    -h, --help                output usage information

  Example usage:

    Run on a different simulator, e.g. iPhone 5: 
    react-native run-ios --simulator "iPhone 5"

    Pass a non-standard location of iOS directory: 
    react-native run-ios --project-path "./app/ios"

    Run on a connected device, e.g. Max's iPhone: 
    react-native run-ios --device "Max's iPhone"

    Run on the AppleTV simulator: 
    react-native run-ios --simulator "Apple TV"  --scheme "helloworld-tvOS"
$ react-native run-android --help
Scanning folders for symlinks in /Users/mxr/Desktop/XDS/RN/AwesomeProject/node_modules (12ms)

  react-native run-android [options]
  builds your app and starts it on a connected Android emulator or device

  Options:

    --install-debug           
    --root [string]           Override the root directory for the android build (which contains the android directory) (default: )
    --flavor [string]         --flavor has been deprecated. Use --variant instead
    --variant [string]        
    --appFolder [string]      Specify a different application folder name for the android source. (default: app)
    --appId [string]          Specify an applicationId to launch after build. (default: )
    --appIdSuffix [string]    Specify an applicationIdSuffix to launch after build. (default: )
    --main-activity [string]  Name of the activity to start (default: MainActivity)
    --deviceId [string]       builds your app and starts it on a specific device/simulator with the given device id (listed by running "adb devices" on the command line).
    --no-packager             Do not launch packager while building
    --port [number]            (default: 8081)
    --config [string]         Path to the CLI configuration file
    -h, --help                output usage information
Simulator Screen Shot - iPhone X - 2018-04-19 at 14.43.16.png

集成到现有的原生应用

  • 设置项目目录结构

首先创建一个空目录用于存放React Native项目
创建一个/ios子目录,把你现有的iOS项目拷贝到/ios子目录中
创建一个/android子目录,把你现有的Android项目拷贝到/android子目录中

|-- AwesomeProject // 根目录
    |-- android // 安卓项目
    |-- ios // iOS项目
    |-- package.json // JavaScript依赖包配置文件
    |-- index.android.js // React Native应用在iOS上的入口文件
    |-- index.ios.js // React Native应用在Android上的入口文件
  • 配置package.json
{
  "name": "MyReactNativeApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "^16.3.1",
    "react-native": "^0.55.3"
  }
}

示例中的version字段没有太大意义(除非你要把你的项目发布到npm仓库)。
scripts中是用于启动packager服务的命令($ npm start命令则是启动开发服务器,其实$ react-native start也是一样的)。
dependencies中的react和react-native的版本取决于你的具体需求。一般来说我们推荐使用最新版本。你可以使用npm info reactnpm info react-native来查看当前的最新版本。

另外,react-native对react的版本有严格要求,高于或低于某个范围都不可以。
本文无法在这里列出所有react native和对应的react版本要求,只能提醒读者先尝试执行npm install,然后注意观察安装过程中的报错信息,例如require react@某.某.某版本, but none was installed,然后根据这样的提示,执行npm i -S react@某.某.某版本

如果你使用多个第三方依赖,可能这些第三方各自要求的react版本有所冲突,此时应优先满足react-native所需要的react版本。其他第三方能用则用,不能用则只能考虑选择其他库。

  • 安装 React & React Native & 第三方依赖

请打开一个终端/命令提示行,进入到项目目录中(即包含有package.json文件的目录),然后运行下列命令来安装:
$ npm install$ yarn add react-native
终端可能会打印类似如下的语句
react-native@0.54.4 requires a peer of react@^16.3.0-alpha.1 but none was installed.
只需要安装上述所需的react模块即可:
$ yarn add react@version_printed_above
这些模块会被安装到项目根目录下的node_modules/目录中(所有通过npm install命令安装的模块都会放在这个目录中。这个目录我们原则上不复制、不移动、不修改、不上传,随用随装)。通常我们需要将node_modules/添加到.gitignore忽略文件中。

使用 CocoaPods 导入 React Native

  • 安装CocoaPods

CocoaPods是针对iOS和Mac开发的包管理工具。我们用它来把React Native框架的代码下载下来并添加到你当前的项目中。 我们建议使用Homebrew来安装CocoaPods。
$ brew install cocoapods
从技术上来讲,我们完全可以跳过CocoaPods,但是这样一来我们就需要手工来完成很多配置项。CocoaPods可以帮我们完成这些繁琐的工作。

  • 配置CocoaPods的依赖

React Native框架整体是作为node模块安装到项目中的。下一步我们需要在CocoaPods的Podfile中指定我们所需要使用的组件。

在你开始把React Native集成到你的应用中之前,首先要决定具体整合的是React Native框架中的哪些部分。而这就是subspec要做的工作。在创建Podfile文件的时候,需要指定具体安装哪些React Native的依赖库。所指定的每一个库就称为一个subspec

可用的subspec都列在node_modules/react-native/React.podspec中,基本都是按其功能命名的。一般来说你首先需要添加Core,这一subspec包含了必须的AppRegistryStyleSheetView以及其他的一些React Native核心库。如果你想使用React Native的Text库(即<Text>组件),那就需要添加RCTTextsubspec。同理,Image需要加入RCTImage,等等。

我们需要在Podfile文件中指定所需的subspec。创建Podfile的最简单的方式就是在/ios子目录中使用CocoaPods的init命令:
$ pod init
Podfile会创建在执行命令的目录中。你需要调整其内容以满足你的集成需求。调整后的Podfile的内容看起来类似下面这样:

# Uncomment the next line to define a global platform for your project
  platform :ios, '8.0'

# The target name is most likely the name of your project.
target 'NumberTileGame' do
  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
  # use_frameworks!

  # Pods for NumberTileGame
  # Your 'node_modules' directory is probably in the root of your project,
  # but if not, adjust the `:path` accordingly
  pod 'React', :path => '../node_modules/react-native', :subspecs => [
    'Core',
    'CxxBridge', # Include this for RN >= 0.47
    'DevSupport', # Include this to enable In-App Devmenu if RN >= 0.43
    'RCTText',
    'RCTNetwork',
    'RCTWebSocket', # Needed for debugging
    'RCTAnimation', # Needed for FlatList and animations running on native UI thread
    # Add any other subspecs you want to use in your project
  ]
  # Explicitly include Yoga if you are using RN >= 0.42.0
  pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  # Third party deps podspec link
   pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
   pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
   pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

  target 'NumberTileGameTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

创建好了Podfile后,就可以开始安装React Native的pod包了。
$ pod install

常见问题&解决方案

问题一

[!] Unable to satisfy the following requirements:

- `React/Core (from `../node_modules/react-native`)` required by `Podfile`

Specs satisfying the `React/Core (from `../node_modules/react-native`)` dependency were found, but they required a higher minimum deployment target.

在Podfile中添加指定最低为8.0的开发版本:platform :ios, '8.0'

问题二

[!] Unable to find a specification for `boost-for-react-native` depended upon by `Folly`

执行$ pod update更新pods库即可。

  • pod install & pod update & pod repo update 加速技巧

使用$ pod repo查看本地的master库

$ pod repo

aliyun
- Type: git (master)
- URL:  https://github.com/aliyun/aliyun-specs.git
- Path: /Users/MountainX/.cocoapods/repos/aliyun

lunboPodWSpec
- Type: git (master)
- URL:  https://github.com/DevaLee/lunboPodWSpec.git
- Path: /Users/MountainX/.cocoapods/repos/lunboPodWSpec

Specs
- Type: git (master)
- URL:  https://github.com/CocoaPods/Specs.git
- Path: /Users/MountainX/.cocoapods/repos/Specs

3 repos

使用$ pod repo remove NAME来移除不要的master库

$ pod repo remove master
$ pod repo add master https://gitcafe.com/akuandev/Specs.git //添加pod的repo源
$ pod repo update

加速方法:进入到repos目录下,通过git clone直接添加到master库,命令行如下:

$ cd ~/.cocoapods/repos 
$ pod repo remove master
$ git clone https://github.com/CocoaPods/Specs.git master

首先要把本地老的master分支给移除掉,然后使用git clone从github镜像源上clone一份且设置本地master库。这样本地的repo就是最新的了。

$ git clone https://github.com/CocoaPods/Specs.git master

Cloning into 'master'...
remote: Counting objects: 2067512, done.
remote: Compressing objects: 100% (177/177), done.
remote: Total 2067512 (delta 78), reused 35 (delta 35), pack-reused 2067295
Receiving objects: 100% (2067512/2067512), 529.53 MiB | 95.00 KiB/s, done.
Resolving deltas: 100% (1164658/1164658), done.
Checking out files: 100% (230184/230184), done.

此时再进入到当前工程目录下,执行下面的命令行
$ pod install --no-repo-update --verbose
$ pod update --no-repo-update --verbose

其中--verbose的作用就是打印出执行过程中详细的信息,--no-repo-update的作用就是禁止更新repo,这样就避免执行了git fetch,从而加快速度。

这样就解决了工程依赖的第三方库版本过低需要更新的问题。

但是我们在clone github镜像源的时候,发现速度还是比较慢的,这是因为国内访问github的速度不给力,没办法的事情,这个时候可以考虑挂一个VPN或者使用国内一些网站提供的镜像源。
目前搜集到的可选源有:
https://gitcafe.com/akuandev/Specs.git
http://git.oschina.net/akuandev/Specs.git
https://git.coding.net/hging/Specs.git
其实就是常见的git托管站

比如换成coding提供的一个镜像源,命令行如下:

$ cd ~/.cocoapods/repos 
$ pod repo remove master
$ git clone https://git.coding.net/hging/Specs.git master

这样在clone的时候会发现速度很快哈。
另外,在自己工程中的Podfile文件加入下面一行描述:

source 'https://git.coding.net/hging/Specs.git'

如果不加这一句话,它默认还是从github镜像源地址去下载的,这个不要给忘记了。

注意

  • master repo里面存放的是所有第三方库的地址列表,下载第三方库对应的源码还是要到指定的源码存放地址(podspecs中有指定)去下载。更换repo源只是加快了repo的下载速度,并不会加快第三方库源码的下载速度,两者是没有任何关系的。
  • 在工程中尽量避免直接使用pod update、pod install,在后面添加--no-repo-update后使用。
  • 工程中依赖第三方库版本过低,可以先到repos目录下,使用git clone更新master repo,然后在工程中使用pod update --no-repo-update命令。

上述方案一定程度上加快了CocoaPods的执行速度,但是仍然避免不了要更新全部repo的情况,而实际情况是我们项目当中用到的第三方库大部分只需要十几个,大量的时间被浪费在我们不需要的库上面了。因为CocoaPods是使用中心化的方式来进行管理的,所以当第三方库多起来的时候,就会出现刚才的情况,这个时候可以选择使用Carthage来管理第三方库,它比CocoaPods最大的优势就在于去中心化的方式来管理,不过Carthage的缺点是里面的库还不是很丰富,不过随着时间的推移就不是问题了。

问题三

如果集成到原有项目中报错:'folly/folly-config.h' file not found
则需要更新yarn后重新安装,如果还是无法解决,那就需要回退到稳定版本了。

  • 更新 Yarn

warning Your current version of Yarn is out of date. The latest version is "1.6.0" while you're on "0.24.5".
info To upgrade, run the following command:

$ npm upgrade --global yarn

sudo npm upgrade --global yarn不能更新yarn?

$ yarn --version
yarn install v0.24.5
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 1.01s.

卸了重新安装即可:
npm uninstall -g yarn && npm install -g yarn

问题四

运行.xcworkspace项目后报错:'React/RCTBundleURLProvider.h’ file not found

解决:Delete node modules, then run npm
install (or better yet yarn) and after everything has finished downloading, run react-native
upgrade which should give you the option to replace old files with the template ones, by doing so you re-link your native dependencies in react-native which should fix your problem. Of course don't forget to clean your project in Xcode

翻译:
删除node modules文件夹(一般在根目录)$ sudo rm -r -f node_modules/,然后运行 $ npm install(也是在根目录),install 结束后再运行 $ react-native upgrade

代码集成示例

现在我们已经准备好了所有依赖,可以开始着手修改原生代码来把React Native真正集成到应用中了。在我们的2048示例中,首先尝试添加一个显示有"High Score"(得分排行榜)的React Native页面。

  1. 创建一个index.ios.js文件

index.ios.js是React Native应用在iOS上的入口文件。而且它是不可或缺的!它可以是个很简单的文件,简单到可以只包含一行require/import导入语句。

# 在项目根目录执行以下命令创建文件:
$ touch index.ios.js
  1. 添加你自己的React Native代码

为了简单示范,把全部的代码都写到了index.ios.js里(当然实际开发中并不推荐这样做)。

# 进入命令模式
vim index.ios.js
# 在命令模式下按下 'i' 进入输入模式
/*  
在输入模式中,可以使用以下按键:
ENTER(回车键)                          换行
BACK SPACE / Delete (退格键)           删除光标前一个字符
Fn + BACK SPACE / Delete               删除光标后的一个字符
方向键                                 在文本中移动光标
HOME/END                               移动光标到行首/行尾
Page Up/Page Down                      上/下翻页
ESC                                    退出输入模式,切换到命令模式
*/
/*
在苹果Mac电脑的键盘上没有Home, End, Page UP, Page DOWN这些键,可以通过用Fn键来组合得到同样的功能:
Home = Fn + 左方向
End = Fn + 右方向
Page UP = Fn + 上方向
Page DOWN = Fn + 下方向
向前 Delete = Fn + delete键。
*/
# 在命令模式下按下英文冒号 ':' 就进入了底线命令模式
/*
底线命令模式可以输入单个或多个字符的命令,可用的命令非常多。
在底线命令模式中,基本的命令如下
    :w      将编辑的数据写入硬盘档案中
    :w!     强制将编辑的数据写入硬盘档案中
    :q      离开
    :q!     为强制离开不储存档案
    :wq     储存后离开
    :wq!    强制储存后离开
    :set nu       显示行号,设定之后,会在每一行的前缀显示该行的行号
    :set nonu     取消行号
    按ESC键可随时退出底线命令模式
*/

编辑index.ios.js如下

//index.ios.js
'use strict';

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

class RNHighScores extends React.Component {
  render() {
    var contents = this.props["scores"].map(
      score => <Text key={score.name}>{score.name}:{score.value}{"\n"}</Text>
    );
    return (
      <View style={styles.container}>
        <Text style={styles.highScoresTitle}>
          2048 High Scores!
        </Text>
        <Text style={styles.scores}>    
          {contents}
        </Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF',
  },
  highScoresTitle: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  scores: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

// MyReactNativeApp整体js模块的名称
AppRegistry.registerComponent('MyReactNativeApp', () => RNHighScores);
  1. 原生接入RN模块

现在我们已经在index.ios.js中创建了React Native组件,下一步就是把这个组件添加给一个新的或已有的ViewController。

首先导入RCTRootView的头文件。

#import <React/RCTRootView.h>

原生项目中添加跳转React-Native的按钮并定义点击事件如下

- (IBAction)highScoreButtonPressed:(id)sender {
    NSLog(@"High Score Button Pressed");
    NSURL *jsCodeLocation = [NSURL
                             URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"];
    RCTRootView *rootView =
      [[RCTRootView alloc] initWithBundleURL : jsCodeLocation
                           moduleName        : @"MyReactNativeApp"
                           initialProperties :
                             @{
                               @"scores" : @[
                                 @{
                                   @"name" : @"Alex",
                                   @"value": @"42"
                                  },
                                 @{
                                   @"name" : @"Joel",
                                   @"value": @"10"
                                 }
                               ]
                             }
                           launchOptions    : nil];
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view = rootView;
    [self presentViewController:vc animated:YES completion:nil];
}
  1. Info.plist中添加App Transport Security例外
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>
  1. 启动开发服务器
# 在项目根目录执行:
$ npm start
//或者
$ react-native start
  1. 运行应用

如果你使用的是Xcode,那么照常编译和运行应用即可。
如果你不想使用Xcode(但是你仍然必须安装Xcode),则可以在命令行中使用以下命令来运行应用:

# 在项目的根目录中执行:
$ react-native run-ios
  1. 运行结果
    Simulator Screen Shot - iPhone X - 2018-04-19 at 15.35.49.png

    可以直接编辑index.ios.js,保存后在模拟器上Cmd + R(真机可以摇一摇)即可看到及时更新
    Simulator Screen Shot - iPhone X - 2018-04-19 at 15.44.42.png

Demo下载

RN_AwesomeProject
RN_NumberTileGame

参考:
React Native - English
React Native - 中文
Unable to find a specification for 'boost-for-react-native' depended upon by 'Folly'
解决CocoaPods慢的小技巧
解决CocoaPods各种慢的方案(gem换源+pod repo换源)
Mac终端 vi/vim 的简单使用

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

推荐阅读更多精彩内容