脚本宝典收集整理的这篇文章主要介绍了

React-Native 与 React-Web 的融合

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。
<p><code></p> <h2 id="articleHeader0">关于</h2> <p>对于react-native在实际中的应用, facebook官方的说法是react-native是为多平台提供共同的开发方式,而不是说一份代码,多处使用。 然后一份代码能够多处使用还是很有意义的,我所了解到的已经在尝试做这件事情的:</p> <ol> <li><a rel="nofollow" href="https://medium.com/@jviereck/modularise-css-the-react-way-1e817b317b04" target="_blank">modularise-css-the-react-way</a></li> <li><a rel="nofollow" href="https://github.com/js-next/react-style" target="_blank">react-style</a></li> <li> <a rel="nofollow" href="https://github.com/raphamorim/native-css" target="_blank">native-css</a> </li> </ol> <p>现阶段大家都是在摸索中,且react-native 还不够成熟,为此我也想通过一个实际的例子提前探究一下共享代码的可行性。</p> <p>下面是我以SampleApp做的一个简单demo, 先奉献上截图:</p> <p><strong>web 版本:</strong></p> <p><span class="img-wrap"><img data-src="http://gtms02.alicdn.com/tps/i2/TB1KhiiHFXXXXbBXpXXhV2lQVXX-512-743.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" style="cursor: pointer;"></span></p> <p><strong>react-native版本:</strong></p> <p><span class="img-wrap"><img data-src="http://gtms04.alicdn.com/tps/i4/TB1Fxx6HFXXXXXdXVXX66HwTVXX-487-801.png" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="" style="cursor: pointer;"></span></p> <h2 id="articleHeader1">初步想法</h2> <h3 id="articleHeader2">组件</h3> <p>react-native基本上是View套上Text这样来布局,为了做web和native的兼容,我们得提供继承版本的View ,针对不同的平台返回不同做兼容,我们将提供:</p> <ol> <li>Share.View -&gt; View (reac-native = View , web = <a href="http://www.js-code.com/tag/div" title="div" target="_blank">div</a>)</li> <li>Share.P + Share.Span -&gt; Text (Text在react-native中分为块级别和<a href="http://www.js-code.com/tag/in" title="in" target="_blank">in</a>l<a href="http://www.js-code.com/tag/in" title="in" target="_blank">in</a>e级别所以得用两个元素来区分)</li> </ol> <h3 id="articleHeader3">样式</h3> <p>我们知道react-native的样式是css很小的一个子集,大概支持50种属性,为了做到web和native使用同样地样式,那么我的想法是:</p> <ol> <li>使用css文件来编写样式,通过编译的方式生产不同平台需要的样式</li> <li>对于web,使用auto-prefixel处理,生产web兼容的css代码</li> <li>对于react-native,生成对应的styles.js</li> <li>css的写法用OO<a href="http://www.js-code.com/tag/css" title="CSS" target="_blank">CSS</a>的方式</li> </ol> <p>这样做的另外一个原因是,因为css是全集,react-native是子集,全集到子集可以通过删减来处理,但是如果想通过子集到全集就会很麻烦(react-style就是通过react-native来生成css)。 且这样做还有很多好处,例如我们可以支持react-native里边不支持的css写法,例如<code>padd<a href="http://www.js-code.com/tag/in" title="浏览关于“in”的文章" target="_blank" class="tag_link">in</a>g: a b c d;</code> 这种写法很容易得到兼容。</p> <blockquote> <p>其实这里,无论react-native还是react-web都支持<code>style={}</code>这样的写法. 上面例子中的web截图其实是没有引用css的,但inline样式对于web来说并不是优选。</p> </blockquote> <h2 id="articleHeader4">实现思路</h2> <p>首先大概整理一下我们需要解决的问题:</p> <ol> <li>如何区分web和native</li> <li>js如何对应不同的平台来编译,因为react-native使用的是自己的依赖管理<a href="http://www.js-code.com/tag/package" title="package" target="_blank">package</a>r</li> <li>css如何编译为js</li> <li>代码结构应该是怎样的</li> </ol> <h3 id="articleHeader5">问题一 : 如何区分web和native</h3> <p>react-native 里边会有win<a href="http://www.js-code.com/tag/do" title="do" target="_blank">do</a>w变量吗?我试了一下,是有的,那<a href="http://www.js-code.com/tag/window" title="window" target="_blank">window</a>变量里边不可能有<a href="http://www.js-code.com/tag/location" title="location" target="_blank">location</a>,<a href="http://www.js-code.com/tag/document" title="document" target="_blank">document</a>之类的吧, 借着这种想法,可用如下方法来区分native和web</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var isNative = !window.location; " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> <span class="hljs-keyword"><a href="http://www.js-code.com/tag/var" title="浏览关于“var”的文章" target="_blank" class="tag_link">var</a></span> isNative = !<span class="hljs-built_in"><a href="http://www.js-code.com/tag/window" title="浏览关于“window”的文章" target="_blank" class="tag_link">window</a></span>.<a href="http://www.js-code.com/tag/location" title="浏览关于“location”的文章" target="_blank" class="tag_link">location</a>; </code></pre> <h3 id="articleHeader6">问题二:如何对应不同平台打包</h3> <p>对于react-native,是通过<a href="http://www.js-code.com/tag/package" title="package" target="_blank">package</a>r来打包的,具体的实现和逻辑可以随时查看<a href="http://www.js-code.com/tag/package" title="浏览关于“package”的文章" target="_blank" class="tag_link">package</a>r的readme文档。 那我们怎么将适用于native的代码打包成web的代码,首先想到的是<code>browser<a href="http://www.js-code.com/tag/if" title="if" target="_blank">if</a>y</code>, <code>webpack</code>。 都是遵循commonJs规范,个人更喜欢前者, 用它来应该足以满足需求。</p> <h3 id="articleHeader7">问题三: css如何编译为js</h3> <p>前面提到了<code>native-css</code> , 可以用它来帮助我们完成打包。</p> <h3 id="articleHeader8">问题四:代码结构应该是怎样的</h3> <p>web和native的代码都写在同一个地方,如何做区分呢? 这个问题当然最好就是不做区分,或者就像女生的衣服,期望是越少越好,但永远不可能木有(猥琐了:-】)。</p> <p>我设想中的一个最简模型的目录结构,web和<a href="http://www.js-code.com/tag/ios" title="ios" target="_blank">ios</a>有不同的入口,web和<a href="http://www.js-code.com/tag/ios" title="ios" target="_blank">ios</a>有单独的目录, 组件共享, 如下:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="├── compo.js // 我们会使用到得公共组件 ├── styles.css // compo的样式文件 ├── index.web.js // web 入口 ├── index.ios.js // ios 入口 ├── shared.js // 做兼容的共享变量文件 ├── ios // ios 目录 └── web // web 目录 ├── index.html // web 页面 ├── index.web.js // 打包过后的js └── react.js // react.js依赖 " title="" data-original-title="复制"></span> </div> </p></div> <pre class="hljs objectivec"><code>├── compo.js <span class="hljs-comment">// 我们会使用到得公共组件</span> ├── styles.css <span class="hljs-comment">// compo的样式文件</span> ├── index.web.js <span class="hljs-comment">// web 入口</span> ├── index.<a href="http://www.js-code.com/tag/ios" title="浏览关于“ios”的文章" target="_blank" class="tag_link">ios</a>.js <span class="hljs-comment">// ios 入口</span> ├── shared.js <span class="hljs-comment">// 做兼容的共享变量文件</span> ├── ios <span class="hljs-comment">// ios 目录</span> └── web <span class="hljs-comment">// web 目录</span> ├── index.html <span class="hljs-comment">// web 页面</span> ├── index.web.js <span class="hljs-comment">// 打包过后的js</span> └── react.js <span class="hljs-comment">// react.js依赖</span> </code></pre> <p>好像很复杂的样子, 其实相对于原本的SampleApp,只是多了<code>index.web.js</code> , <code>web目录</code>, <code>shared</code>三者。 然后style通过style.css来描述。</p> <h2 id="articleHeader9">具体实现</h2> <p>我们已经整理了具体的实现思路,下面是我就会直接吐出我的实现代码, 重点的地方都会在源码里边有注释</p> <h4>先看应用代码:</h4> <p><strong>ios入口:index.ios.js</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" /** * Sample React Native App * https://github.com/facebook/react-native */ 'use strict'; var React = require('react-native'); var Compo = require('./compo'); React.AppRegistry.registerComponent('ShareCodeProject', () => Compo);<br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> <span class="hljs-comment">/** * Sample <a href="http://www.js-code.com/tag/react" title="浏览关于“React”的文章" target="_blank" class="tag_link">React</a> Native App * https://github.com/facebook/react-native */</span> <span class="hljs-meta"> 'use strict'</span>; <span class="hljs-keyword">var</span> React = <span class="hljs-built_in">require</span>(<span class="hljs-string">'react-native'</span>); <span class="hljs-keyword">var</span> Compo = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./compo'</span>); React.AppRegis<a href="http://www.js-code.com/tag/try" title="浏览关于“try”的文章" target="_blank" class="tag_link">try</a>.registerComponent(<span class="hljs-string">'ShareCodeProject'</span>, () =&gt; Compo); </code></pre> <p><strong>web入口:index.web.js</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="<a href="http://www.js-code.com/tag/button" title="button" target="_blank">button</a>" <a href="http://www.js-code.com/tag/class" title="class" target="_blank">class</a>="copyCode code-tool" data-toggle="tooltip" data-placement="<a href="http://www.js-code.com/tag/top" title="top" target="_blank">top</a>" data-clipboard-<a href="http://www.js-code.com/tag/text" title="text" target="_blank">text</a>=" /**<br /> * <a href="http://www.js-code.com/tag/for" title="for" target="_blank">for</a> web<br /> */<br /> <a href="http://www.js-code.com/tag/var" title="var" target="_blank">var</a> Compo = require('./compo');<br /> <a href="http://www.js-code.com/tag/react" title="React" target="_blank">React</a>.render(<Compo ></span>, document.getElementById('App'));<br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> <span class="hljs-comment">/** * <a href="http://www.js-code.com/tag/for" title="浏览关于“for”的文章" target="_blank" class="tag_link">for</a> web */</span> <span class="hljs-keyword">var</span> Compo = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./compo'</span>); React.render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Compo</span> /&gt;</span>, <a href="http://www.js-code.com/tag/document" title="浏览关于“document”的文章" target="_blank" class="tag_link">document</a>.getElementById('App')); </span></code></pre> <p><strong>样例组件:compo.js</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="<a href="http://www.js-code.com/tag/button" title="button" target="_blank">button</a>" <a href="http://www.js-code.com/tag/class" title="class" target="_blank">class</a>="copyCode code-tool" data-toggle="tooltip" data-placement="<a href="http://www.js-code.com/tag/top" title="top" target="_blank">top</a>" data-clipboard-<a href="http://www.js-code.com/tag/text" title="text" target="_blank">text</a>=" // 依赖的公共库,通过它获取兼容的组件<br /> <a href="http://www.js-code.com/tag/var" title="var" target="_blank">var</a> Share = require('./shared');<br /> // styles是style.css build过后生成的style.js<br /> var styles = require('./styles');<br /> var <a href="http://www.js-code.com/tag/react" title="React" target="_blank">React</a> = Share.React;<br /> var {<br /> View,<br /> P,<br /> Span<br /> } = Share;</p> <p> var Compo = React.create<a href="http://www.js-code.com/tag/class" title="Class" target="_blank">Class</a>({<br /> render: <a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a>() {<br /> <a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> (<br /> <View style={styles.container}><br /> <P style={styles.welcome}><br /> Welcome to React Native!<br /> </P><br /> <P style={styles.instructions}><br /> To get started, edit index.ios.js<br /> </P><br /> <P style={styles.instructions}><br /> Press Cmd+R to reload,{'n'}<br /> Cmd+Control+Z <a href="http://www.js-code.com/tag/for" title="for" target="_blank">for</a> dev menu<br /> </P><br /> </View><br /> );<br /> }<br /> });</p> <p> module.exports = Compo;<br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> <span class="hljs-comment">// 依赖的公共库,通过它获取兼容的组件</span> <span class="hljs-keyword">var</span> Share = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./shared'</span>); <span class="hljs-comment">// styles是style.css build过后生成的style.js</span> <span class="hljs-keyword">var</span> styles = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./styles'</span>); <span class="hljs-keyword">var</span> React = Share.React; <span class="hljs-keyword">var</span> { View, P, Span } = Share; <span class="hljs-keyword">var</span> Compo = React.create<a href="http://www.js-code.com/tag/class" title="浏览关于“Class”的文章" target="_blank" class="tag_link">Class</a>({ <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-keyword"><a href="http://www.js-code.com/tag/function" title="浏览关于“function”的文章" target="_blank" class="tag_link">function</a></span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword"><a href="http://www.js-code.com/tag/return" title="浏览关于“return”的文章" target="_blank" class="tag_link">return</a></span> ( <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">View</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.container}</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">P</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.welcome}</span>&gt;</span> Welcome to React Native! <span class="hljs-tag">&lt;/<span class="hljs-name">P</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">P</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.instructions}</span>&gt;</span> To get started, edit index.ios.js <span class="hljs-tag">&lt;/<span class="hljs-name">P</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">P</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{styles.instructions}</span>&gt;</span> Press Cmd+R to reload,{'n'} Cmd+Control+Z for dev menu <span class="hljs-tag">&lt;/<span class="hljs-name">P</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">View</span>&gt;</span></span> ); } }); <span class="hljs-built_in">module</span>.<a href="http://www.js-code.com/tag/export" title="浏览关于“export”的文章" target="_blank" class="tag_link">export</a>s = Compo; </code></pre> <p><strong>组件样式: style.css</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" /** * 大家可能发现了css的写法还是小驼峰,是的不是横杠,暂时我们还是以这种方式处理 * native-css 目测不支持横杠,(自己重写native-css相对来说是比较容易的,完全可以做到css兼容到react-native的css子集) */ .container { flex: 1; justifyContent: center; alignItems: center; backgroundColor: #F5FCFF; } .welcome { fontSize: 20; textAlign: center; margin: 10; } .instructions { textAlign: center; color: #333333; marginBottom: 5; } " title="" data-original-title="复制"></span> </div> </p></div> <pre class="css hljs"><code class="css"> <span class="hljs-comment">/** * 大家可能发现了css的写法还是小驼峰,是的不是横杠,暂时我们还是以这种方式处理 * native-css 目测不支持横杠,(自己重写native-css相对来说是比较容易的,完全可以做到css兼容到react-native的css子集) */</span> <span class="hljs-selector-class">.container</span> { <span class="hljs-attribute"><a href="http://www.js-code.com/tag/flex" title="浏览关于“flex”的文章" target="_blank" class="tag_link">flex</a></span>: <span class="hljs-number">1</span>; <span class="hljs-attribute">just<a href="http://www.js-code.com/tag/if" title="浏览关于“if”的文章" target="_blank" class="tag_link">if</a>yContent</span>: center; <span class="hljs-attribute">alignItems</span>: center; <span class="hljs-attribute">backgroundColor</span>: <span class="hljs-number">#F5FCFF</span>; } <span class="hljs-selector-class">.welcome</span> { <span class="hljs-attribute">fontSize</span>: <span class="hljs-number">20</span>; <span class="hljs-attribute"><a href="http://www.js-code.com/tag/text" title="浏览关于“text”的文章" target="_blank" class="tag_link">text</a>Align</span>: center; <span class="hljs-attribute">margin</span>: <span class="hljs-number">10</span>; } <span class="hljs-selector-class">.instructions</span> { <span class="hljs-attribute">textAlign</span>: center; <span class="hljs-attribute">color</span>: <span class="hljs-number">#333333</span>; <span class="hljs-attribute">marginBottom</span>: <span class="hljs-number">5</span>; } </code></pre> <p><strong>index.html</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="<a href="http://www.js-code.com/tag/button" title="浏览关于“button”的文章" target="_blank" class="tag_link">button</a>" class="copyCode code-tool" data-toggle="tooltip" data-placement="<a href="http://www.js-code.com/tag/top" title="浏览关于“top”的文章" target="_blank" class="tag_link">top</a>" data-clipboard-text=" <!DOCTYPE html><br /> <html><br /> <head><br /> <title>Hello React!</title><br /> <script src=&quot;./react.js&quot;></script><br /> <!-- No need for JSXTransformer! --><br /> </head><br /> <body></p> <div id=&quot;App&quot;></div> <p> <script src=&quot;./index.web.js&quot;></script><br /> </body><br /> </html><br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html"> <span class="hljs-meta">&lt;!DOCTYPE html&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Hello React!<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./react.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-comment">&lt;!-- No need for <a href="http://www.js-code.com/tag/jsx" title="浏览关于“JSX”的文章" target="_blank" class="tag_link">JSX</a>Trans<a href="http://www.js-code.com/tag/form" title="浏览关于“form”的文章" target="_blank" class="tag_link">form</a>er! --&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name"><a href="http://www.js-code.com/tag/div" title="浏览关于“div”的文章" target="_blank" class="tag_link">div</a></span> <span class="hljs-attr">id</span>=<span class="hljs-string">"App"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./index.web.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span> </code></pre> <h4>Share部分的处理</h4> <p><strong>shared.js</strong></p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var Share = {}; var React = require('react-native'); var isNative = !win<a href="http://www.js-code.com/tag/do" title="do" target="_blank">do</a>w.<a href="http://www.js-code.com/tag/location" title="location" target="_blank">location</a>;<br /> /**<br /> * 判断是web的时候,重新赋值React<br /> */<br /> <a href="http://www.js-code.com/tag/if" title="if" target="_blank">if</a> (<a href="http://www.js-code.com/tag/window" title="window" target="_blank">window</a>.React) {<br /> React = win<a href="http://www.js-code.com/tag/do" title="浏览关于“do”的文章" target="_blank" class="tag_link">do</a>w.React;<br /> }<br /> Share.React = React;</p> <p> /**<br /> * 做底层的兼容, 当然这里只是做了一个最简demo,具体实现的时候可能会对props做各种兼容处理<br /> */<br /> if (!isNative) {</p> <p> Share.View = React.create<a href="http://www.js-code.com/tag/class" title="Class" target="_blank">Class</a>({<br /> render: <a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a>() {<br /> <a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> </p> <div {...this.props}></span><br /> }<br /> });</p> <p> Share.P = React.createClass({<br /> render: <a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a>() {<br /> <a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> </p> <p {...this.props}> <p> }<br /> });</p> <p> Share.Span = React.createClass({<br /> render: <a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a>() {<br /> <a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> <span {...this.props}></span><br /> }<br /> });<br /> } else {<br /> // alert('isNative')<br /> Share.View = React.View;<br /> Share.P = React.Text;<br /> Share.Span = React.Text;<br /> Share.Text = React.Text;<br /> }</p> <p> module.exports = Share;<br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> <span class="hljs-keyword">var</span> Share = {}; <span class="hljs-keyword">var</span> React = <span class="hljs-built_in">require</span>(<span class="hljs-string">'react-native'</span>); <span class="hljs-keyword">var</span> isNative = !<span class="hljs-built_in">window</span>.location; <span class="hljs-comment">/** * 判断是web的时候,重新赋值React */</span> <span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.React) { React = <span class="hljs-built_in">window</span>.React; } Share.React = React; <span class="hljs-comment">/** * 做底层的兼容, 当然这里只是做了一个最简demo,具体实现的时候可能会对props做各种兼容处理 */</span> <span class="hljs-keyword">if</span> (!isNative) { Share.View = React.createClass({ <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> &lt;div {...<a href="http://www.js-code.com/tag/this" title="浏览关于“this”的文章" target="_blank" class="tag_link">this</a>.props}/&gt; } }); Share.P = React.createClass({ render: function() { return &lt;p {...this.props}/&gt; } }); Share.Span = React.createClass({ render: function() { return &lt;span {...this.props}/&gt; } }); } <a href="http://www.js-code.com/tag/else" title="浏览关于“else”的文章" target="_blank" class="tag_link">else</a> { // <a href="http://www.js-code.com/tag/alert" title="浏览关于“alert”的文章" target="_blank" class="tag_link">alert</a>('isNative') Share.View = React.View; Share.P = React.Text; Share.Span = React.Text; Share.Text = React.Text; } module.exports = Share; </code></pre> <h4>build打包程序</h4> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var fs = require('fs'); var nativeCSS = require('native-css'), var cssObject = nativeCSS.convert('./styles.css'); toStyleJs(cssObject, './styles.js'); buildWebReact(); /** * native-css获取到得是一个对象,需要将cssObject转化为js代码 */ function toStyleJs(cssObject, name) { console.log('build styles.js n'); var tab = ' '; var str = ''; str += '/* build header */n'; str += 'var styles = {n'; for(var key in cssObject) { var rules = cssObject[key]; str += tab + key + ': {n'; for(var attr in rules) { var rule = rules[attr]; str += tab + tab + attr + ': ' + format(rule) + ',n' } str += tab + '},n' } str += '};n' str += 'module.exports = styles;n' fs.writeFile(name, str) function format(rule) { if (!isNaN(rule - 0)) { return rule; } return '&quot;' + rule + '&quot;'; } } /** * 构造web使用的react */ function buildWebReact() { console.log('build web bundle'); var browserify = require('browserify'); var b = browserify(); b.add('./index.web.js'); // 添加es6支持 b.transform('reactify', {'es6': true}); // ignore掉react-native b.ignore('react-native') var wstream = fs.createWriteStream('./web/index.web.js'); b.bundle().pipe(wstream); } " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> <span class="hljs-keyword">var</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>); <span class="hljs-keyword">var</span> native<a href="http://www.js-code.com/tag/css" title="浏览关于“CSS”的文章" target="_blank" class="tag_link">CSS</a> = <span class="hljs-built_in">require</span>(<span class="hljs-string">'native-css'</span>), <span class="hljs-keyword">var</span> css<a href="http://www.js-code.com/tag/Object" title="浏览关于“Object”的文章" target="_blank" class="tag_link">Object</a> = nativeCSS.convert(<span class="hljs-string">'./styles.css'</span>); toStyleJs(cssObject, <span class="hljs-string">'./styles.js'</span>); buildWebReact(); <span class="hljs-comment">/** * native-css获取到得是一个对象,需要将cssObject转化为js代码 */</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toStyleJs</span>(<span class="hljs-params">cssObject, <a href="http://www.js-code.com/tag/name" title="浏览关于“name”的文章" target="_blank" class="tag_link">name</a></span>) </span>{ <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'build styles.js n'</span>); <span class="hljs-keyword">var</span> tab = <span class="hljs-string">' '</span>; <span class="hljs-keyword">var</span> str = <span class="hljs-string">''</span>; str += <span class="hljs-string">'/* build header */n'</span>; str += <span class="hljs-string">'var styles = {n'</span>; <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> cssObject) { <span class="hljs-keyword">var</span> rules = cssObject[key]; str += tab + key + <span class="hljs-string">': {n'</span>; <span class="hljs-keyword">for</span>(<span class="hljs-keyword">var</span> attr <span class="hljs-keyword">in</span> rules) { <span class="hljs-keyword">var</span> rule = rules[attr]; str += tab + tab + attr + <span class="hljs-string">': '</span> + format(rule) + <span class="hljs-string">',n'</span> } str += tab + <span class="hljs-string">'},n'</span> } str += <span class="hljs-string">'};n'</span> str += <span class="hljs-string">'module.exports = styles;n'</span> fs.writeFile(name, str) <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">format</span>(<span class="hljs-params">rule</span>) </span>{ <span class="hljs-keyword">if</span> (!<span class="hljs-built_in"><a href="http://www.js-code.com/tag/isNaN" title="浏览关于“isNaN”的文章" target="_blank" class="tag_link">isNaN</a></span>(rule - <span class="hljs-number">0</span>)) { <span class="hljs-keyword">return</span> rule; } <span class="hljs-keyword">return</span> <span class="hljs-string">'"'</span> + rule + <span class="hljs-string">'"'</span>; } } <span class="hljs-comment">/** * 构造web使用的react */</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">buildWebReact</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'build web bundle'</span>); <span class="hljs-keyword">var</span> browserify = <span class="hljs-built_in">require</span>(<span class="hljs-string">'browserify'</span>); <span class="hljs-keyword">var</span> b = browserify(); b.add(<span class="hljs-string">'./index.web.js'</span>); <span class="hljs-comment">// 添加<a href="http://www.js-code.com/tag/es6" title="浏览关于“es6”的文章" target="_blank" class="tag_link">es6</a>支持</span> b.transform(<span class="hljs-string">'reactify'</span>, {<span class="hljs-string">'es6'</span>: <span class="hljs-literal"><a href="http://www.js-code.com/tag/true" title="浏览关于“true”的文章" target="_blank" class="tag_link">true</a></span>}); <span class="hljs-comment">// ignore掉react-native </span> b.ignore(<span class="hljs-string">'react-native'</span>) <span class="hljs-keyword">var</span> wstream = fs.createWriteStream(<span class="hljs-string">'./web/index.web.js'</span>); b.bundle().pipe(wstream); } </code></pre> <h2 id="articleHeader10">也尝试一下由react-native 到react-web的兼容方案</h2> <h3 id="articleHeader11">问题</h3> <ol> <li><a href="http://www.js-code.com/tag/flex" title="flex" target="_blank">flex</a>box的写法在react-native上面我们会发现, 不用在父元素上声明<code>display: <a href="http://www.js-code.com/tag/flex" title="flex" target="_blank">flex</a>;</code> 在web上必须要做这样的声明, 所以我们需要让设置了<code>flex:*</code>的元素的父元素<code>display: flex;</code> 。</li> <li>flexbox在<a href="http://www.js-code.com/tag/android" title="android" target="_blank">android</a>上是由很多bug的,所以必须要解决兼容性问题<code>webkit-box</code> </li> </ol> <h3 id="articleHeader12">解决方案</h3> <h3 id="articleHeader13">1. nested 的style写法</h3> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" styles = StyleSheet.create({ mod: { flexDirection: 'row', item: { flex: 1 } } }); " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> styles = StyleSheet.create({ <span class="hljs-attr">mod</span>: { <span class="hljs-attr">flexDirection</span>: <span class="hljs-string">'row'</span>, <span class="hljs-attr">item</span>: { <span class="hljs-attr">flex</span>: <span class="hljs-number">1</span> } } }); </code></pre> <p>这样的写法有些像less,我们可以知道元素的层级关系, 这样我可以遍历这个对象,查找子元素有设置flex的,父元素加上<code>display:flexbox</code>。</p> <h3 id="articleHeader14">2. 通过自定义元素</h3> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var GridSystem = require('GridSystem'); var { Row, Grid, Grid6, Grid4 } = GridSystem; <Row ...><br /> <Grid></Grid><br /> <Grid></Grid><br /> </Row><br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> <span class="hljs-keyword">var</span> GridSystem = <span class="hljs-built_in">require</span>(<span class="hljs-string">'GridSystem'</span>); <span class="hljs-keyword">var</span> { Row, Grid, Grid6, Grid4 } = GridSystem; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Row</span> <span class="hljs-attr">...</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">Grid</span>/&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">Grid</span>/&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">Row</span>&gt;</span></span> </code></pre> <p>通过标签的方式, 相当于给react-native或者react添加了一个网格系统,同时我们可以直接在Row上设置<code>display:flex</code>.</p> <h3 id="articleHeader15">3. 遍历查找</h3> <p>完全同react-native原生的写法,直接在web中兼容,遍历所有有flex样式的节点,直接做兼容。</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" componentDidMount: function() { var $node = this.getDOMNode(); var $parent = $node.parentNode; var $docfrag = document.createDocumentFragment(); $docfrag.appendChild($node); var treeWalker = document.createTreeWalker($node, NodeFilter.SHOW_ELEMENT, { acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; } }, false); while(treeWalker.nextNode()) { var node = treeWalker.currentNode; if (node.style.flex) { flexChild(node); flexParent(node.parentNode); } }; $parent.appendChild($docfrag); } function flexChild(node) { if (node.__flexchild__) { return; } node.__flexchild__ = true; var flexGrow = node.style.flexGrow; addStyle(node, ` -webkit-box-flex: ${flexGrow}; -webkit-flex: ${flexGrow}; -ms-flex: ${flexGrow}; flex: ${flexGrow}; `); node.classList.add('mui-flex-cell'); } function flexParent(node) { if (node.__flexparentd__) { return; } node.__flexparentd__ = true; node.classList.add('mui-flex'); } " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"> componentDidMount: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> $<a href="http://www.js-code.com/tag/node" title="浏览关于“node”的文章" target="_blank" class="tag_link">node</a> = <span class="hljs-keyword">this</span>.get<a href="http://www.js-code.com/tag/dom" title="浏览关于“DOM”的文章" target="_blank" class="tag_link">DOM</a>Node(); <span class="hljs-keyword">var</span> $<a href="http://www.js-code.com/tag/parent" title="浏览关于“parent”的文章" target="_blank" class="tag_link">parent</a> = $node.parentNode; <span class="hljs-keyword">var</span> $docfrag = <span class="hljs-built_in">document</span>.createDocumentFragment(); $docfrag.appendChild($node); <span class="hljs-keyword">var</span> treeWalker = <span class="hljs-built_in">document</span>.createTreeWalker($node, NodeFilter.SHOW_ELEMENT, { <span class="hljs-attr">acceptNode</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">node</span>) </span>{ <span class="hljs-keyword">return</span> NodeFilter.FILTER_ACCEPT; } }, <span class="hljs-literal"><a href="http://www.js-code.com/tag/false" title="浏览关于“false”的文章" target="_blank" class="tag_link">false</a></span>); <span class="hljs-keyword"><a href="http://www.js-code.com/tag/while" title="浏览关于“while”的文章" target="_blank" class="tag_link">while</a></span>(treeWalker.nextNode()) { <span class="hljs-keyword">var</span> node = treeWalker.currentNode; <span class="hljs-keyword">if</span> (node.style.flex) { flexChild(node); flexParent(node.parentNode); } }; $parent.appendChild($docfrag); } <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">flexChild</span>(<span class="hljs-params">node</span>) </span>{ <span class="hljs-keyword">if</span> (node.__flexchild__) { <span class="hljs-keyword">return</span>; } node.__flexchild__ = <span class="hljs-literal">true</span>; <span class="hljs-keyword">var</span> flexGrow = node.style.flexGrow; addStyle(node, <span class="hljs-string">` -webkit-box-flex: <span class="hljs-subst">${flexGrow}</span>; -webkit-flex: <span class="hljs-subst">${flexGrow}</span>; -ms-flex: <span class="hljs-subst">${flexGrow}</span>; flex: <span class="hljs-subst">${flexGrow}</span>; `</span>); node.classList.add(<span class="hljs-string">'mui-flex-cell'</span>); } <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">flexParent</span>(<span class="hljs-params">node</span>) </span>{ <span class="hljs-keyword">if</span> (node.__flexparentd__) { <span class="hljs-keyword">return</span>; } node.__flexparentd__ = <span class="hljs-literal">true</span>; node.classList.add(<span class="hljs-string">'mui-flex'</span>); } </code></pre> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" .mui-flex { display: -webkit-box!important; display: -webkit-flex!important; display: -ms-flexbox!important; display: flex!important; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; -webkit-box-orient: vertical; -webkit-box-direction: normal; -webkit-flex-direction: column; -ms-flex-direction: column; flex-direction: column; } .mui-flex-cell { -webkit-flex-basis: 0; -ms-flex-preferred-size: 0; flex-basis: 0; max-width: 100%; display: block; position: relative; } " title="" data-original-title="复制"></span> </div> </p></div> <pre class="css hljs"><code class="css"> <span class="hljs-selector-class">.mui-flex</span> { <span class="hljs-attribute">display</span>: -webkit-box<span class="hljs-meta">!important</span>; <span class="hljs-attribute">display</span>: -webkit-flex<span class="hljs-meta">!important</span>; <span class="hljs-attribute">display</span>: -ms-flexbox<span class="hljs-meta">!important</span>; <span class="hljs-attribute">display</span>: flex<span class="hljs-meta">!important</span>; <span class="hljs-attribute">-webkit-flex-wrap</span>: wrap; <span class="hljs-attribute">-ms-flex-wrap</span>: wrap; <span class="hljs-attribute">flex-wrap</span>: wrap; <span class="hljs-attribute">-webkit-box-orient</span>: vertical; <span class="hljs-attribute">-webkit-box-direction</span>: normal; <span class="hljs-attribute">-webkit-flex-direction</span>: column; <span class="hljs-attribute">-ms-flex-direction</span>: column; <span class="hljs-attribute">flex-direction</span>: column; } <span class="hljs-selector-class">.mui-flex-cell</span> { <span class="hljs-attribute">-webkit-flex-basis</span>: <span class="hljs-number">0</span>; <span class="hljs-attribute">-ms-flex-preferred-size</span>: <span class="hljs-number">0</span>; <span class="hljs-attribute">flex-basis</span>: <span class="hljs-number">0</span>; <span class="hljs-attribute">max-width</span>: <span class="hljs-number">100%</span>; <span class="hljs-attribute">display</span>: block; <span class="hljs-attribute">position</span>: relative; } </code></pre> <h2 id="articleHeader16">总结</h2> <p>这个demo很简单,实际应用中应该会有很多地方的坑, 比如:</p> <ol> <li>模块中依赖只有native才有的组件</li> <li>Native模块的事件处理和web大不相同 </li> <li>现实环境中的模块更多,更复杂,如何做模块的管理</li> </ol> <p>对于<code>write once, run anywhere</code> 这个观点. 相信不同的人会有不同的看法,但无论如何,如果兼容成本不大,这样的兼容技术方案对业务开发是有极大意义的。</p> <p>ps0: 这里仅仅做可行性方案的分析,不代表我认同或不认同这种方案。<br /> ps1: 大家如果有更好的方案,求教,求讨论。<br /> ps2: 据说微博关注@sysu_学家不会怀孕</p> <p></code></p>

总结

以上是脚本宝典为你收集整理的

React-Native 与 React-Web 的融合

全部内容,希望文章能够帮你解决

React-Native 与 React-Web 的融合

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过