display reactnative_reactnative display - CSDN
  • 1、有固定的宽高,则显示固定的宽高,这个宽高不是像素,而是代表独立的像素密度 2、flex:让组件根据可用空间动态的收缩和扩展 通常情况下我们可以使用flex:1,告诉某个组件来填充剩余的所有的空间,如果是多个...

    1、有固定的宽高,则显示固定的宽高,这个宽高不是像素,而是代表独立的像素密度

    2、flex:让组件根据可用空间动态的收缩和扩展

    通常情况下我们可以使用flex:1,告诉某个组件来填充剩余的所有的空间,如果是多个组件的话,则是所有的这些组件去平分父容器中的剩余的所有空间。。如果这些并列的子组件的flex值不一样,则谁的值更大,谁占据剩余空间的比例就更大。

    2、Flexbox

    一个组件可以使用Flexbox指定其子组件或元素之间的布局。Flexbox旨在为不同的屏幕上提供一致的布局。

    通常情况下,我们结合使用flexDirection、alignItems和 justifyContent三个样式属性就已经能够实现我们所需的布局。

    注意:Flexbox在React Native的工作原理和使用方式与css在web上的方式基本一样,当然也有一些例外:比如flexDirection的默认值是column而不是row,alignItems的默认值是stretch而不是flex-start,以及flex只能指定一个数字值。

    3、Flex Direction

    向一个组件的样式中添加Flex Direction可以决定一个布局的主轴。子元素应该沿着水平方向(row)排列,还是沿着竖直方向(column)排列呢?默认值是竖直(column)方向。

    4、Justify Content

    向组件的样式中添加Justify Content可以决定其子元素沿着主轴的排列方式。子元素应该分布在主轴的开始端,还是中间,最后,还是均匀分布?可用的选项有:flex-start、center、flex-end、space-around以及space-between。

    • flex-start:弹性盒子元素将与行起始位置对齐。该行的第一个子元素的主起始位置的边界将与该行的主起始位置的边界对齐,同时所有后续的伸缩盒项目与其前一个项目对齐。
    • flex-end:弹性盒子元素将与行结束位置对齐。该行的第一个子元素的主结束位置的边界将与该行的主结束位置的边界对齐,同时所有后续的伸缩盒项目与其前一个项目对齐。
    • center:弹性盒子元素将与行中间位置对齐。该行的子元素将相互对齐并在行中居中对齐,同时第一个元素与行的主起始位置的边距等同与最后一个元素与行的主结束位置的边距(如果剩余空间是负数,则保持两端相等长度的溢出)。
    • space-between:弹性盒子元素会均匀分布在行里。如果最左边的剩余空间是负数,或该行只有一个子元素,则该值等效于’flex-start’。在其它情况下,第一个元素的边界与行的主起始位置的边界对齐,同时最后一个元素的边界与行的主结束位置的边距对齐,而剩余的伸缩盒项目则平均分布,并确保两两之间的空白空间相等。
    • space-around:弹性盒子元素会均匀分布在行里,两端保留子元素与子元素之间间距大小的一半。如果最左边的剩余空间是负数,或该行只有一个伸缩盒项目,则该值等效于’center’。在其它情况下,伸缩盒项目则平均分布,并确保两两之间的空白空间相等,同时第一个元素前的空间以及最后一个元素后的空间为其他空白空间的一半。

    5、Align Items

    向组件的样式(style)中添加alignItems可以决定其子元素沿着次轴(就是与主轴垂直的轴,比如若主轴方向为row,则次轴方向为column)的排列方式。子元素是应该靠近次轴的开始端还是中间,还是末端,亦或是拉伸来填补呢?可用选项有:flex-start、center、flex-end以及stretch。

    • flex-start:弹性盒子元素的次轴起始位置的边界紧靠该行的次轴起始边界。
    • flex-end:弹性盒子元素的次轴起始位置的边界紧靠住该行的次轴结束边界。
    • center:弹性盒子元素在该行的次轴)上居中放置。(如果该行的尺寸小于弹性盒子元素的尺寸,则会向两个方向溢出相同的长度)。
    • stretch:如果指定次轴大小的属性值为’auto’,则其值会使项目的边距盒的尺寸尽可能接近所在行的尺寸,但同时会遵照’min/max-width/height’属性的限制。

    注意:要使stretch选项生效的话,子元素在次轴方向上不能有固定的尺寸。在下面的例子中:只有将子元素样式中的width: 50去掉之后,alignItems: ‘stretch’才能生效。

    6、flex-wrap

    默认情况下,item排列在一条线上,即主轴上,flex-wrap决定当排列不下时是否换行以及换行的方式,可能的值nowrap(默认)|wrap|wrap-reverse

        nowrap:自动缩小项目,不换行

        wrap:换行,且第一行在上方

        wrap-reverse:换行,第一行在下面

    7、align-self

    align-self会覆盖父级设置的alignItem属性在次轴上的对齐方式,它有六个可能的值。默认值为auto。

          auto:和父元素align-self的值一致

          flex-start:顶端对齐

          flex-end:底部对齐

          center:竖直方向上居中对齐

          baseline:item第一行文字的底部对齐

          stretch:当item未设置高度时,item将和容器等高对齐

    展开全文
  • React Native 三:样式

    万次阅读 2016-08-22 23:55:08
    一、声明和使用样式1.React Native里面的样式和使用如下面所示,StyleSheet.create这个构造函数不是必须的;index.android.js文件 import React, { … … } from 'react-native'; class AwesomeProject extends ...
    一、声明和使用样式
    1.React Native里面的样式和使用如下面所示,StyleSheet.create这个构造函数不是必须的;
    index.android.js文件
    import React, {
        … …
    } from 'react-native';
    class AwesomeProject extends Component {
      render() {
        return (
          <View>
                //所有核心组件都可以接受style属性
               <Text style={styles.base}>Declare Style</Text>
                //接受数组形式的多个style
               <Text style={[styles.base, styles.background]}>Declare Style</Text>
                //根据某些条件选择性的添加样式,否定型取值如false,undefined和null则会被忽略
                <View style={[styles.base, true && styles.active]}/>
                //可以在render方法中创建样式,多个值冲突的时候,右边的元素优先级最高
                <View style={[styles.background, styles.base, { width:80, height:80}]}/>
           </View>
        );
      }
    }
    //声明样式
    var styles = StyleSheet.create({
      base: {
        width: 100,
        height: 38,
      },
      background: {
        backgroundColor: '#cccccc',
      },
      active: {
        borderWidth: 2,
        borderColor: '#00ff00',
      },
    });
    AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

    二、Flexbox(弹性盒子模型)
    1.在布局上,React Native还实现了弹性盒子模型Flexbox。flexbox布局由伸缩容器和伸缩项目组成,任何一个元素都可以指定为flexbox布局;
         其中设为display:flex或display:inline-flex的元素称为伸缩容器;
         伸缩容器的子元素称为伸缩项目;
    2.和传统的布局不一样,它按照伸缩流的方向布局;
    3.默认情况下,伸缩容器由两根轴组成,即主轴(main axis)和交叉轴(cross axis);
         其中主轴的开始位置叫main start,结束位置叫main end;
         交叉轴的开始位置叫cross start,结束位置叫cross end;
         伸缩项目在主轴上占据的空间叫main size,在交叉轴上占据的空间叫cross size;
         根据设置的情况,主轴可以是水平轴,也可以是垂直轴;
         不管那个轴作为主轴,默认情况下伸缩项目总是沿着主轴,从主轴开始位置到主轴结束位置进行排列;
    4.伸缩容器属性
        下面我们一实际的Demo来演示下相关属性的作用;
     index.android.js文件:
         import React, {
             … …   
         } from 'react-native';
         class AwesomeProject extends Component {
             render() {
                  return (
                       <View style={styles.flexcontain}>
                           <View style={styles.flexitem}>
                             <Text>1</Text>
                           </View>
                           <View style={styles.flexitem}>
                             <Text>2</Text>
                           </View>
                           <View style={styles.flexitem}>
                             <Text>3</Text>
                           </View>
                           <View style={styles.flexitem}>
                             <Text>4</Text>
                           </View>
                           <View style={[styles.flexitem,styles.item5]}>
                             <Text>5</Text>
                           </View>
                    </View>
                  );
                }
         }
         var styles = StyleSheet.create({
              flexcontain: {
                   width:300,
                  height:300,
                  borderWidth:1,
                  borderColor:'blue',
                  flexDirection:'row',
                  top:100,
                  left:100,
             },
             flexitem: {
                  width:50,
                  height:50,
                  borderWidth:1,
                  borderColor:'white',
                  backgroundColor:'gray',
                  justifyContent:'center',
                  alignItems:'center',
           },
           item5: {
             alignSelf:'stretch',
           },
         });
         AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
         flexDirection:指定主轴的方向;
              row:水平方向;
              column:竖直方向;

         flexWrap:主轴线方向空间不足的情况下,是否换行以及应该如何换行;
              wrap:空间不足的情况下允许换行,若主轴方向为水平方向,则从上到下;若主轴方向是为竖直方向,从左到右;
              nowrap:即使空间不足,伸缩容器也不允许换行;


         justifyContent:伸缩项目沿主轴方向的对其方式;
              flex-start:伸缩项目沿主轴线的对其方式;
              flex-end:伸缩项目沿着主轴线的结束位置靠齐;
              center:伸缩项目向主轴中间位置靠齐;
              space-between:伸缩项目会平均地分配在主轴线里,第一伸缩项目在主轴线的开始位置,最后一个项目在主轴线的终点位置;
              space-around:伸缩项目会平均分布在主轴线里,两端保持一半的空间;



         alignItems:伸缩项目在伸缩容器的交叉轴上的对其方式;
              flex-start:伸缩项目向交叉轴的起始的位置对齐;
              flex-end:伸缩项目向交叉轴的结束位置对齐;
              center:伸缩项目向交叉轴的中间位置对齐;


         alignSelf:设置单独伸缩项目在交叉轴上的对齐方式;
              auto:伸缩项目按照自身设置的宽高显示;
              flex-start:伸缩项目向交叉轴开始位置靠齐;
              flex-end:伸缩项目向交叉轴的结束位置靠齐;
              center:伸缩项目向交叉轴的中心位置靠齐;


         borderBottomWidth/borderRightWidth/borderTopWidth/borderTopWidth:底部边框的宽度;

         margin/marginTop/marginBottom/marginLeft/marginRight:外边距;
         padding/paddingTop/paddingBottom/paddingLeft/paddingRight:内边距;
         left/top/right/bottom:左上角坐标;
         width/height:宽高;
    三、将样式作为参数传递
    1.为了能够在调用组件的地方对其子组件样式进行自定义,可以将样式作为参数进行传递;
    2.使用View.propTypes.style和Text.propTypes.style来确保传递的参数确实是style类型的;
    index.android.js文件:
    import React, {
      AppRegistry,
      … … 
    } from 'react-native';
    
    //创建List组件
    var List = React.createClass({
      //声明传递参数和参数类型
      propTypes: {
        style: View.propTypes.style,
        elementStyle: View.propTypes.style,
      },
      render() {
        var elements = ['element1','element2','element3'];
        return (
            //使用参数传递过来的样式设置子组件
            <View style={this.props.style}>
              //直接调用和使用参数传递的样式设置子组件
              {elements.map((element) =><View key={element} style={[styles.element, this.props.elementStyle]} />)}
            </View>
        );
      }
    });
    
    class AwesomeProject extends Component {
      render() {
        return (
          <View>
            <List style={styles.list} elementStyle={styles.listElement} />
          </View>
        );
      }
    }
    
    var styles = StyleSheet.create({
      //传递给子组件样式list
      list: {
        width:300,
        height:300,
        borderWidth:1,
        borderColor:'blue',
      },
      //传递给子组件样式listElement
      listElement: {
        width:50,
        height:50,
        backgroundColor:'gray',
      },
      //直接调用样式element
      element: {
        borderWidth:1,
        borderColor:'yellow',
      }
    });
    AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject

    提示1:
    如果RoadJS的时候,页面报错如下:
    Warning: Each child in an array or iterator should have a 
    unique "key" prop. Check the render method of List.
    处理1:在map函数中的<View>加上key={element}属性;



    展开全文
  • React Native 三端同构实战

    千次阅读 2018-11-14 10:43:41
    React Native 三端(Web、iOS、Android)同构是指在不改动原 React Native 的代码下,让其在浏览器中运行出和在 React Native 环境下一样的页面。对于使用 React Native 开发的页面,如果又单独为 Web 平台重复写一...

    WeiboGoogle+用电子邮件发送本页面

    Comments

     

    0

    React Native 三端(Web、iOS、Android)同构是指在不改动原 React Native 的代码下,让其在浏览器中运行出和在 React Native 环境下一样的页面。对于使用 React Native 开发的页面,如果又单独为 Web 平台重复写一份代码代价是极其大的,而 React Native 三端同构能以零花费快速做到一份代码三端复用。

    React Native 三端同构的应用场景包括:

    • 在 React Native 页面崩溃时用对应的 Web 页兜底,以保证用户可以正常使用页面。
    • 对于需要分享到社交网络如微信朋友圈、微博的页面,不可避免地需要 Web 网页。

    React Native 三端同构基础原理

    React Native 就像一套新的浏览器标准,它提供了大量内置的原生 UI 元素和系统 API,对应着浏览器中的 div、img 等标签以及 BOM API;但是 React Native 目前只专注于移动 App 平台,只适配了 iOS 和 Android 两大系统,而浏览器则是适配了各种操作系统。由于 React Native 需要适配的平台更少所以性能会比浏览器要好。

    React Native 是基于 React 实现的,编写 React Native 应用和编写 Web 应用一样需要编写大量 React 组件。我们编写的 React 组件经过 render 后会以虚拟 DOM 的形式存储在内存中,React 只负责 UI 层面的抽象和组件的状态管理,各平台都可用虚拟 DOM 去渲染出不同的结果,React 架构如图 1 所示:

    图 1. React 架构

    点击查看大图

    由此可见,虚拟 DOM 这层中间抽象在实现 React 渲染到多端时发挥了很大的作用。

    ReactNative 三端同构方案对比

    目前社区中已经有多个 React Native 三端同构方案,比较成熟的有 reactxp 和 react-native-web,下面分别介绍这两种方案并从多方面对比二者以帮助你做出合适的选择。

    认识 reactxp

    reactxp 是一个跨平台的开源 UI 库,由微软 Skype 团队维护,Skype 产品中就大量使用了它来实现写一份代码运行在多个平台上。目前 reactxp 支持以下平台:

    • iOS/Android:基于 React Native 渲染。
    • Web:基于 react-dom 渲染。
    • UWP:基于 react-native-windows 渲染。
    • 其他平台 (如 Mac、Windows10 以下系统、Linux 桌面):基于 Web 渲染的 Electron 

    reactxp 实现原理

    reactxp 充份发挥了 React 虚拟 DOM 的优势,它其实只是充当胶水的作用,把各个平台的渲染引擎整合起来,对外暴露平台一致的接口,reactxp 架构如图 2 所示:

    图 2. reactxp 架构

    reactxp 为各个平台都实现了一份代码,在构建的过程中构建工具会自动选择平台相关的代码进行打包输出。

    reactxp 的优缺点

    优点

    1. 写一份代码就可实现多端渲染,对于有多端需求的产品可以减少代码量和人力。
    2. 由微软 Skype 团队维护并且用于 Skype 产品中,有大公司投入资源支持。
    3. 基于 TypeScript 编写,对 IDE 友好。

    缺点

    1. 为了抹平多端平台差异导致灵活性降低,暴露的组件和 API 较 react-native 要少很多。
    2. 需要兼容 UWP 平台导致包袱更重,而目前会针对 Windows 桌面或手机开发应用的产品在渐渐减少,大多数产品不需要支持 Windows 平台。
    3. 需要多导入 reactxp 这个库,导致打包输出的 bundle 会变大;并且由于多了一层适配,运行时性能肯定不如直接使用 React Native。

    其中最为致命的缺点可能在于目前 reactxp 支持的组件和 API 相当匮乏,一些比较细的操作无法控制。如果你的项目中确实有超出 reactxp 的能力范围的需求,可以通过导入和使用 React Native 实现,但这会导致整个项目脱离 reactxp 体系而无法实现多端同构。reactxp 只保证在它的体型内实现多端同构,但在其体系内却有很多 API 不可用。

    reactxp 和 React Native 的异同点

    从使用层面来说它们最大的区别在于:用 reactxp 写的一份代码可以在多个平台运行,而 React Native 是学会它后可多个平台编写原生应用但还得为不同平台编写不同代码。

    这一点从 reactxp 和 React Native 暴露出的 API 就可以看出来:React Native 中有大量诸如 SegmentedControlIOS、PermissionsAndroid 这样针对特定平台的 API,而 reactxp 中所有的 API 在所有端中都可以正常调用。

    事实上 React Native 也在为多端接口统一做努力,React Native 中的大多数接口是可以在多端运行一致的,但为了保证灵活性 React Native 也提供了平台相关的接口。而 reactxp 抹平了多端接口的差异,但这也导致 reactxp 灵活性降低。

    二者的相同点是都采用了 React 框架编程的思想,由于 reactxp 是基于 React Native 封装的导致两者大多数 API 的使用方式都是一致的。

    认识 react-native-web

    react-native-web 是由 Twitter 工程师 Nicolas Gallagher 实现并维护的开源项目,目前已用在 Twitter、Flipkart、Uber 等项目中,它支持把 React Native 编写的项目转换成 Web 应用。

    为 React Native 项目接入 react-native-web 成本极低:react-native-web 对原项目没有侵入性,无需改动原来的代码,只需在项目中加入一些 webpack 构建配置即可构建出运行出和 React Native 应用一致效果的 Web 应用。

    react-native-web 实现原理

    react-native-web 实现了在不修改 React Native 代码的情况下渲染在浏览器里的功能,其实现原理如下:

    在用 webpack 构建用于运行在浏览器里的代码时,会把 React Native 的导入路径替换为 react-native-web 的导入路径,在 react-native-web 内部则会以和 React Native 目录结构一致的方式实现了一致的 React Native 组件。在 react-native-web 组件的内部,则把 React Native 的 API 映射成了浏览器支持的 API。react-native-web 架构如图 3 所示:

    图 3. react-native-web 架构

    react-native-web 和 reactxp 异同点

    react-native-web 和 reactxp 的目的都是为了实现多端同构,但 react-native-web 只专注于 Web 平台的适配,而 reactxp 则还需要适配 UWP 平台。

    在实现 Web 平台的适配过程中它们都采用了类似的原理:把对外暴露的 API 或组件映射到 Web 平台去。但在实现 Web 平台的样式适配时二者有细微区别:

    • reactxp 全部通过内联样式实现。
    • react-native-web 通过为每条不同的样式生产一个 className,对于重复出现的样式则通过复用 className 实现。

    对于这两种不同的实现方式,我更看好 react-native-web 的实现方式,原因有两个:

    1. 通过复用 className 节省网络传输字节,如果你需要做服务端渲染这个优势会凸显出来。
    2. 通过 className 的方式浏览器渲染性能更好,因为浏览器有做样式计算缓存优化,有人专门写了性能对比测试页面

    表 1 列出了 reactxp 和 react-native-web 在其他方面的对比:

    表 1. react-native-web 和 reactxp 的对比

    对比项 reactxp react-native-web 对比结果
    维护人 微软 Skype 团队和 GitHub 社区 来自 Twitter 的个人Necolas 和 GitHub 社区 reactxp 小胜
    服务端渲染支持 官方没有明确要支持 完全支持 react-native-web 胜
    Web 端包大小 435KB 354.4KB react-native-web 胜
    写代码效率 针对 reactxp 暴露的 API 去实现多端适配 需要自己去验证代码在多端的表现是否一致 reactxp 胜
    学习成本 除了需要学习 reactxp 外,不可避免的还需要学习 React Native 只需学习 React Native 即可 react-native-web 胜
    Github 数据 start=2017 年 4 月 star=6521 issues=23/739 commits=814 start=2017 年 7 月 star=10151 issues=45/1034 commits=1248 react-native-web 用户更多,代码变动频率更大。reactxp 问题响应速度更快。

    如何选择

    如果你开发的产品有适配 UWP 平台的需求就选择 reactxp,否则选择 react-native-web,因为 reactxp 相比于 react-native-web 除了多支持 Windows 平台外,并无其它明显优势。

    reactxp 接入

    由于 reactxp 所有暴露的 API 都支持在 Web 平台和 React Native 平台同时正常运行,因此为 reactxp 应用转 Web 的方法非常简单,只需为项目加入 webpack 构建和运行 Web 页面的 index.html 文件。

    reactxp 的 webpack 配置文件如清单 1 所示:

    清单 1. reactxp 的 webpack 配置文件 webpack.config.js

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    module.exports = {

      entry: "./src/index.tsx",

      mode: "development",

      output: {

        filename: "bundle.js",

        path: __dirname + "/dist"

      },

      resolve: {

        // 优先加载 web.js 后缀的文件

        extensions: [".web.js", ".ts", ".tsx", ".js"]

      },

     

      module: {

        rules: [

             // 转换 TypeScript 文件   

          { test: /\.tsx?$/, loader: "awesome-typescript-loader" }

        ]

      }

    };

    再写一个运行 Web 页面的 index.html 文件,内容如清单 2 所示:

    清单 2. reactxp 平台启动入口文件 index.html

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    <!doctype html>

    <html>

    <head>

      <meta charset='utf-8'>

      <style>

        html, body, .app-container {

          width: 100%;

          height: 100%;

          padding: 0;

          border: none;

          margin: 0;

        }

        *:focus {

            outline: 0;

        }

      </style>

    </head>

    <body>

      <div class="app-container"></div>

      <script src="dist/bundle.js"></script>

    </body>

    </html>

    完整的例子可以参考 reactxp 的官方例子

    react-native-web 接入

    为了给你现有的 ReactNative 接入 react-native-web,实现 ReactNative 三端同构的能力,你需要做以下事情:

    1. 安装新的依赖,按照依赖的命令如下:

      # 运行时依赖

      npm i react react-dom react-native-web react-art

      # 构建工具

      npm i -D webpack webpack-dev-server webpack-cli babel-loader babel-plugin-transform-runtime

    2. 为 Web 平台写一份 webpack 配置文件 webpack.config.js,内容如清单 3 所示:

      清单 3. webpack 配置文件 webpack.config.js

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      module.exports = {

        module: {

          rules: [

            {

              // 支持图片等静态文件的加载

              test: /\.(gif|jpe?g|png|svg)$/,

              use: {

                loader: 'file-loader'

              }

            },

            {

              // React Native 包中有很多 es6 语法的 js,需要用 babel 转换后才能在浏览器中运行

              test: /\.js$/,

              use: {

                loader: 'babel-loader',

                options: {

                  cacheDirectory: false,

                  presets: ['react-native'],

                  plugins: [

                    // 支持 async/await 语法

                    'transform-runtime'

                  ]

                }

              }

            }

          ]

        },

        resolve: {

          // 优先加载以 web.js 结尾的针对 web 平台的文件

          extensions: {

              '.web.js',

              '.js',

              '.json',

          },

          alias: {

             // 把 react-native 包映射成 react-native-web

            'react-native$': 'react-native-web'

          }

        }

      }

    3. 写一个针对 Web 平台启动入口文件 index.web.js,内容如清单 4 所示:

      清单 4. Web 平台启动入口文件 index.web.js

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      import { AppRegistry } from 'react-native';

       

      // 注册组件

      AppRegistry.registerComponent('App', () => App);

       

      // 启动 App 组件

      AppRegistry.runApplication('App', {

        // 启动时传给 App 组件的属性

        initialProps: {},

        // 渲染 App 的 DOM 容器

        rootTag: document.getElementById('react-app')

      });

    4. 写一个 index.html 文件,引入 webpack 构建出的 JavaScript,以在 Web 平台运行,内容如清单 5 所示:

    清单 5. Web 平台启动入口文件 index.html

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    <html>

    <head>

        <meta charset="UTF-8">

        <meta name="viewport"

              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.

    0, minimum-scale=1.0">

        <meta http-equiv="X-UA-Compatible" content="ie=edge">

        <!--以下是正常运行所需的必须样式-->

        <style>

            html,body,#react-root{

                height: 100%;

            }

            #react-root{

                display:flex;

            }

        </style>

    </head>

    <body>

    <div id="react-root"></div>

    <script src="main.js"></script>

    </body>

    </html>

    完成以上步骤后重新执行 webpack 构建,再在浏览器中打开 index.html 你就可以看到 React Native 转出的 Web 网页了。

    完整的例子可以参考 react-native-web 的官方例子

    适配自定义的 Native Modules

    React Native 开发的 App 中经常会出现 React Native 官方提供的 Native Modules

    够用的情况,这时你会在项目中开发自己的 Native Modules,然后在 JavaScript 中去调用自己的 Native Modules。这在 ReactNative 环境下运行没有问题,但转成 Web 后执行时会报错说 Native Modules 上找不到对应的模块,这时因为在浏览器环境下是不存在这些自定义的 Native Modules。为了让页面能正常在浏览器中运行,需要为 Web 平台也实现一份自定义的 Native Modules,实现方法可以在 Web 平台的执行入口的最开头注入以下 polyfill,内容如清单 6 所示:

    清单 6. NativeModules polyfill.js

    1

    2

    3

    4

    import { NativeModules } from 'react-native';

    import MyModule from './MyModule'; // 实现自定义 Native Modules 的地方

     

    NativeModules.MyModule = MyModule; // 挂载 MyModule

    这段代码的作用是把针对 Web 平台编写的自定义原生模块挂载到 Native Modules 对象上成为其属性,以让 JavaScript 代码在访问自定义 Native Modules 时访问到针对 Web 平台编写模块。

    编写特定平台的代码

    为了让 React Native 三端同构能正常的运行,在有些情况下你不得不编写平台特定的代码,因为有些代码只能在特定平台下才能运行,编写特定的 Web 平台代码有以下三种方法:

    1. ReactNative.Platform.OS:所有端的代码都在一个文件中,通过以下代码来写 Web 平台专属代码:

      import { Platform } from 'react-native';

       

      if(Platform.OS==='web'){

        // web 平台专属代码

      }

    2. process.env.platform:通过 webpack 注入的环境变量来区分:

      if (process.env.platform === 'web') {

        // web 平台专属代码

      }

      这段代码只会在 Web 平台下被打包进去,这和 ReactNative.Platform 的区别是:后者的代码会打包进所有的平台。

      要使用这种方法需要你在 webpack.config.js 文件中注入环境变量:

      plugins: [

          new webpack.DefinePlugin({

              'process.env': {

                  platform: JSON.stringify(platform),

                  __DEV__: mode === 'development'

          }),

      ]

    3. .web.js: 在 Web 模式下会优先加载 .web.js 文件,当 .web.js 文件不存在时才使用 .js 文件。

    总结

    React Native 三端同构在理论上虽然可行,并且有现成的方案,但实践是还是会遇到一些问题,例如:

    • 在 Web 平台运行出的样式和 React Native 平台不一致,针对这种情况一般是 react-native-web 库的适配问题,可以在 Github 上提 issue 或 Pull Request。
    • 有些 React Native 提供的 API 在 Web 平台不可能实现适配,例如调摄像头、振动等,对于这种问题可以在 Web 平台裁剪掉这些功能或使用其他交互方式替代。

    React Native 三端同构虽然无法实现 100% 和 React Native 环境运行一致,但能快速简单的转换大多数场景,以低成本的方式为你的项目带来收益。

    参考资源

    原文https://www.ibm.com/developerworks/cn/web/wa-universal-react-native/index.html?ca=drs-&utm_source=tuicool&utm_medium=referral

    展开全文
  • reactnative中flex布局

    2020-08-21 22:17:46
    在普通移动端网页中,加display:flex默认水平排布 在reactnative中,view(不写flex)默认是display:flex布局,但是却是竖直排布

    在普通移动端网页中,加display:flex默认水平排布

    在reactnative中,view(不写flex)默认是display:flex布局,但是却是竖直排布

    展开全文
  • React-Native flex 布局使用总结

    千次阅读 2018-06-26 09:17:25
    React-Native flex 布局使用总结 父视图属性(容器属性): flexDirection : 对子布局方向的设置 row : 从左到右依次排列 row-reverse :从右向左依次排列 column:(default) 从上到下排列 column-reverse :从下...
  • React Native(二):属性、状态

    千次阅读 2018-01-18 17:35:17
    欢迎一起来学习React Native,QQ群:672509442 属性 大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为props(属性)。 原生组件的prop 以常见的基础组件Image为例,在创建一个...
  • React Native通过一个基于Flexbox的布局引擎,在所有移动平台上实现了一致的跨平台样式和布局方案。主要属性 flex flexDirection alignSelf alignItems justifyContent flexWrap 属性讲解flex当一个元素定义了flex...
  • React Native学习心得

    千次阅读 2019-04-15 18:24:37
    结合网址进行学习:https://reactnative.cn/ 讨论社区:https://www.facebook.com/groups/react.native.community React Native - 调试技巧及调试菜单说明(模拟器调试、真机调试):...
  • 在去年也整理过 《移动端跨平台开发的深度解析》 的对比文章,时隔一年之后,本篇将重新由 环境搭建、实现原理、编程开发、插件开发、编译运行、性能稳定、发展未来 等七个方面,对当前的 React Native 和 ...
  • 在上篇中,笔者分享了部分安装并调试React Native应用过程里的一点经验,如果还没有看过的同学请点击《React Native基础&amp;入门教程:调试React Native应用的一小步》。在本篇里,让我们一起来了解一下,什么...
  • React Native转web方案:react-native-web

    千次阅读 2018-11-13 09:15:06
    React源码 React16源码之React Fiber架构 从源码看React异常处理 从源码看React.PureComponent ...web移动端布局的那些...React Native转web方案:react-native-web React Native Icon方案:react-native-svg ...
  • 需求背景 我们最近要做一个React Native的产品详情页,里面有一部分内容展示的是服务端下发的html标签(运营人员编写的,内容不固定,且很随意)。...第三方组件react-native-htmlview 要实现这个需求,我第一...
  • react native实现隐藏和显示

    千次阅读 2018-11-08 14:43:36
      1.目的:在APP开发中实现隐藏和显示功能。... 2.实现思路:通过对this.state显示初始状态的判断和三目比较来实现影藏和显示 3.代码实现 ...大家如果有其他的好方法可以贴出来一起交流学习(RN新手,欢迎大家指正!...
  • React Native组件只Image

    千次阅读 2016-12-10 13:16:13
    不管在Android还是在ios原生...静态图片资源从0.14版本开始,React Native提供了一个统一的方式来管理iOS和Android应用中的图片。要往App中添加一个静态图片,只需把图片文件放在代码文件夹中某处,然后像下面这样去引
  • 如果之前接触过一些web开发,上手ReactNative基本没什么难度,搞清楚一些用法上的区别就可以了。 正常的web开发,我们一般是在HTML里嵌入javascript代码,ReactNative则恰恰相反,它使用的是JSX,也就是在javascript...
  • elm-react-native https://github.com/stoneWeb/elm-react-native This is a high simulating eleme app (eleme website) , implemented by React Native . This app can run on iOS and Android, the
  • I have been working on a lot of mobile projects lately — including Cordova, PhoneGap, React Native, some Ionic and Swift — but I have to say, React Native is by far the best experience in mobile...
  • react native常用css

    2019-04-30 18:20:40
    布局属性:https://reactnative.cn/docs/layout-props/ 样式:https://reactnative.cn/docs/layout-props/ 图标列表 https://oblador.github.io/react-native-vector-icons/ npm install react-native-vector-...
  • React Native Elements is a styling library with pre-built components to replace the basic, limited React Native components. It’s similar to Bootstrap, giving you useable styles that are broad enough ...
  • React NativeReact速学教程

    千次阅读 2019-01-08 00:34:50
    本文出自《React Native学习笔记》系列文章。 React Native是基于React的,在开发React Native过程中少不了的需要用到React方面的知识。虽然官方也有相应的Document,但篇幅比较多,学起来比较枯燥。 通过《React ...
1 2 3 4 5 ... 20
收藏数 3,560
精华内容 1,424
热门标签
关键字:

display reactnative