# react native webpack **Repository Path**: xiamids/react-native-webpack ## Basic Information - **Project Name**: react native webpack - **Description**: react-native-webpack - **Primary Language**: Unknown - **License**: 0BSD - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-05-19 - **Last Updated**: 2022-05-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # @marslibs/yfereact-freetemplate-common ## 说明 店铺装修ISV模板通用方法 依赖包执行 初始化web-init 启动项目 web-start 就可以启动项目 ## 安装 `npm install @marslibs/yfereact-freetemplate-common` ## 使用 初始化 web-init 后入口文件会修改成默认的index.web.js 样例为:JDReactAPIDemos.web.js ### 基本功能楼层例子 基本功能楼层可以实现接收楼层数据源,以及根据内容自动生成楼层高度 ```jsx import React from 'react' import { View, Text } from 'react-native' // 调试预览时可暂时注释掉 import { Floor,Util,FloorManager,PageVisibleManager,ListScrollManager } from '@marslibs/yfereact-freetemplate-common' export default class Example extends React.Component { constructor(props) { super(props) // 调试预览时可暂时注释掉 this.state = { data: Util.getSafeFloorData(this.props.data) }; // 注册监听楼层刷新,调试预览时可暂时注释掉 FloorManager.addFloorDataUpdateListener(this, props.id); } render() { // 【发布打包时】生成bundle时需要使用Floor包裹的形式,调试预览时可暂时注释掉 // this.props.id 楼层的id 必传 // this.props.data 楼层的数据 必传 return ( Hello world ) // 【调试预览时】使用@areslabs生成H5预览,直接写自己的业务代码, return Hello world } /** * 监听楼层刷新后的回调方法 * * @param {Object} data 智铺接口返回的楼层数据 * @memberof Example */ onFloorDataUpdate(data) { this.setState({ data }) } } ``` ### 监听滚动功能的楼层例子 监听滚动功能是在基础功能的基础上,使用ListScrollManager监听了楼层滚动 ```jsx import React from 'react' import { View } from 'react-native' // 调试预览时可暂时注释掉 import { Floor,Util,FloorManager,PageVisibleManager,ListScrollManager } from '@marslibs/yfereact-freetemplate-common' export default class Example extends React.Component { constructor(props) { super(props) // 调试预览时可暂时注释掉 this.state = { data: Util.getSafeFloorData(this.props.data) }; // 注册监听楼层刷新,调试预览时可暂时注释掉 FloorManager.addFloorDataUpdateListener(this, props.id); } render() { // 【发布打包时】生成bundle时需要使用Floor包裹的形式,调试预览时可暂时注释掉 // this.addListener() // this.props.id 楼层的id 必传 // this.props.data 楼层的数据 必传 // return ( // // // ) // 【调试预览时】使用@areslabs生成H5预览,直接写自己的业务代码, return } /** * 监听楼层刷新后的回调方法 * * @param {Object} data 智铺接口返回的楼层数据 * @memberof Example */ onFloorDataUpdate(data) { this.setState({ data }) } /** * 监听楼层滚动回调方法 * * @param {number} firstRow * @param {number} lastRow * @param {boolean} visible * @param {number} firstShowRow * @param {number} offset * @memberof Example */ onListScroll(firstRow, lastRow, visible, firstShowRow, offset) { console.log(`firstRow:${firstRow}-lastRow=${lastRow}-visible${visible}-firstShowRow${firstShowRow}-offset${offset}`); } /** * 监听页面显示隐藏的回调方法 * * @param {string} pageId * @param {boolean} showStatus * @memberof Example */ onPageShowStatusChange(pageId, showStatus) { console.log(`pageId=${pageId}-showStatus=${showStatus}`); } // 调试预览时可暂时注释掉 addListener() { let { pageId, uid} = FloorManager.getFloorIdentiInfo(this, this.props.id); // 监听页面显示隐藏 PageVisibleManager.addPageShowStatusListener(this, pageId); // 监听楼层滚动 ListScrollManager.addScrollListener(this, pageId, uid); } componentWillUnmount(){ // PageVisibleManager和ListScrollManager注册监听后需在componentWillUnmount时移除,调试预览时需暂时注释掉 const { pageId } = FloorManager.getFloorIdentiInfo(this, this.props.id); PageVisibleManager.removePageShowStatusListener(pageId, this); ListScrollManager.removeScrollListener(this); } } ``` ## 一键加购(支持版本:V8.5.10及之后版本) ```jsx import { ModuleMessage } from '@marslibs/yfereact-freetemplate-common' ``` ModuleMessage.batchAddCart(skuList) skuList: 商品id集合, 数组类型,若skuList未传参或者传参为空,将弹出toast “请选择商品” ## 组件props ### Floor Floor用于作为根视图容器,必传props传数是id、data id 楼层的id 必传 data 楼层的数据 必传 mtaParam 额外的曝光埋点参数 选传, 字典格式,目前支持的key(skuList 和 configDataType), 若不传,将上报字符串‘none’ ```jsx mtaParam = { skuList: ['skuId1', 'skuId2', 'skuId3'], configDataType: 1 } ``` >注意: 楼层组件必须用Floor作为根视图包裹起来 ### CycleVideo CycleVideo循环播放视频组件,必传props传数id、source id 楼层的id 必传 source 视频参数{{url: "视频源链接",imgUrl: "背景占位图链接"}} 因为android的视频组件外层包括TouchableOpacity点击事件无响应,所以新增了onVideoClick方法,ios没有实现onVideoClick方法,所以同时包括TouchableOpacity并实现onVideoClick方法。 示例 ```jsx return { console.log("点击了视频"); }}> { console.log("点击了视频"); }} /> // 最外层是为了兼容iOS端934以下版本,不支持onVideoClick方法。 ``` ***注意:id url imgUrl 是必传参数*** ### JSPImageGif JSPImageGif用于展示Gif动图,会自动判断添加https协议头,并通过缓存帧控制,有效的减少Gif图内存,Gif动图统一用此组件。 ```jsx 示例1 // style宽高需要自己通过Util.getRpx换算 示例2 ``` // autoRpx 设置为true后,组件会对宽高进行Util.getRpx进行等比像素宽高处理 ### JSPImage JSPImage基于JDImage的封装,JDImage的属性都支持。JSPImage会自动判断添加https协议头,并对style的尺寸进行图片url裁剪和压缩格式处理,可有效减少图片内存及提升下载展示速度。 注意:图片组件统一都用此组件,同时件样式宽高必须设置,否则无法进行图片url裁剪和优化,如果没有设置宽高组件内部是渲染JDImage组件 ```jsx 示例1 // style宽高需要自己通过Util.getRpx换算 示例2 // autoRpx 设置为true后,组件会对宽高进行Util.getRpx进行等比像素宽高处理 ``` ## 组件API ### Util Util提供一些通用的工具方法 #### getSafeFloorData Object Util.getSafeFloorData(Object data) android返回的data是json格式字符串需要使用此方法获取安全的JSON对象的楼层数据 data 传入的楼层数据 返回值是JSON对象 ### getNodeTextData Object Util.getNodeTextData(Object data, string name); 获取对应组件的数据源 data 传入的楼层数据 name 组件对应的名称 返回值是JSON对象 ### getNodeText Object Util.getNodeText(Object data, string name); 获取对应组件的数据源 data 传入的楼层数据 name 组件对应的名称 返回值是JSON对象 ### getDataDefine Object Util.getDataDefine(Object data, string name); 获取对应组件的数据源 data 传入的楼层数据 name 组件对应的名称 返回值是JSON对象 ### getRpx number Util.getRpx(number size); 获取等比像素 size 原有像素值 返回值等比的rpx ### Tracker Tracker用于埋点数据上报 #### Tracker.clickWithParams(skuId,positionid,configDataType,configDataValue) 点击事件上报 skuId 商品id, 此字段可以在detail.configDataValue里面取,如果没有可传空字符串 positionid 楼层位置,此字段可以通过调用getFloorIdentiInfo方法返回的对象取position属性 configDataType 点击类型,此字段可以在detail里面取 configDataValue 点击值,此字段预留用,暂时传空字符串 #### Tracker.batchAddCartClick(skuList, positionid, configDataType) 一键加购点击事件上报 skuList 商品id集合,数组 positionid 楼层位置,此字段可以通过调用getFloorIdentiInfo方法返回的对象取position属性 configDataType 点击类型,此字段可以在detail里面取 ### FloorManager FloorManager用于注册管理楼层的数据 #### addFloorDataUpdateListener FloorManager.addFloorDataUpdateListener(Object object, string id) 注册楼层数据更新的监听 object 楼层组件this id 楼层的参数id #### onFloorDataUpdate onFloorDataUpdate(Object data) 楼层数据更新的回调函数 data 楼层的数据 #### getFloorIdentiInfo FloorManager.getFloorIdentiInfo(Object this, string id) object 楼层组件this id 楼层的参数id 返回楼层信息的对象包含:pageId、uid、position等 ### ListScrollManager ListScrollManager用于监听楼层滚动 #### addScrollListener ListScrollManager.addScrollListener(Object this, string pageId, string uid) 添加楼层滚动监听,添加后记得在componentWillUnmount时移除 this 楼层组件this pageId 页面的pageId id 楼层的参数id #### onListScroll onListScroll(number firstRow, number lastRow, boolean visible, boolean firstShowRow, number offset) 监听楼层滚动的回调方法 firstRow 第一个展示楼层位置 lastRow 最后一个展示楼层位置 visible 是否显示 firstShowRow 第一个可见楼层位置,如有悬浮时会部分遮住第一个楼层,导致可视楼层位置为2 offset 控制listView滚动偏移量,当有悬浮时,listview锚点时,需要向下偏移悬浮高度 >举例:手机屏幕高度是100px,有个原生有个ListView,总共有10个楼层,每个楼层高度都是50px。那么刚开始ListView显示出来还未往上滑动时,我们在第0个楼层监听到的onListScroll回调方法的firstRow:0,lastRow:1,visible:true,firstShowRow:0,offset:0; 当ListView往上滑动50px时,firstRow:1,lastRow:2,visible:false,firstShowRow:1,offset:0;当原生的ListView有偏移量40px时,offset为40; ### removeScrollListener ListScrollManager.removeScrollListener(Object this) 移除监听 this 楼层组件this ### PageVisibleManager PageVisibleManager用于监听页面显示或消失 #### addPageShowStatusListener PageVisibleManager.addPageShowStatusListener(Object this, string pageId) 添加监听页面显示或隐藏,添加后记得在componentWillUnmount时移除 this 楼层组件this pageId 页面的pageId ### removePageShowStatusListener PageVisibleManager.removePageShowStatusListener(string pageId, Object this) 移除监听 pageId 页面的pageId this 楼层组件this #### onPageShowStatusChange onPageShowStatusChange(string pageId, boolean showStatus) 监听页面显示或隐藏的回调方法 pageId 页面的pageId showStatus 页面的显示状态 ## 调试 本组件依赖原生API,目前暂时只能在APP环境内看到展示效果,目前与@areslabs配合的临时方案,使用@areslabs开发生成H5预览,开发阶段需将组件的相关代码暂时注释,等正式打包时再取消相关注释。 ## 常见问题 ### 参数传递问题 比如AppRegistry.registerComponent注册对应的根视图是Home,那么render方法中必须要将传递参数`render() {return ; }`,否则视图会无法正常显示出来。 ### 使用areslabs生成web预览时报loader错误 因为areslabs打包web时不支持本组件的转换,所以需要在预览的时候注释掉@marslibs相关依赖,具体参考文档上面的的例子 ### 布局flex:1相关的视图无法展示问题 店铺的RN楼层和正常的RN不同,店铺的根视图Floor的高度默认是0,所以在使用flex:1的时候需要注意,以下是几种示例情况: ```jsx return ( {/* Floor的高度是0,所以flex:1会跟着填满Floor高度也是0,视图红色视图无法显示 */} ) return ( {/* Floor的高度是0,所以flex:1会跟着填满Floor高度也是0,视图红色视图无法显示 */} {/* 根视图高度是0,父视图红色的高度是0,虽然绿色的子视图1000,但还是无法正常显示 */} ) return ( {/* Floor的高度是0,所以flex:1会跟着填满Floor高度也是0,视图红色视图无法显示 */} {/* 根视图高度是0,父视图红色的高度是0,虽然绿色的子视图1000,但还是无法正常显示 */} ) return ( {/* 根视图高度是0,父视图红色的高度暂无,但是绿色的子视图1000,直接将红色的父视图及跟视图高度撑起,可以正常展示 */} ) return ( {/* 根视图高度是0,父视图红色的高度暂无,但是绿色的子视图1000,直接将红色的父视图及跟视图高度撑起,可以正常展示 */} {/* 根视图高度是0,flex:1跟着撑满父视图的高度所以黄色的视图高度还是0,因此无法正常显示 */} ) ``` 因此flex:1的布局方式慎用,一定要确定父视图有固定高度的情况下才可用。 ### ios和android数据差异导致android无法显示或显示错误问题 原生在向RN传递数据的时候this.props.data在ios和android两个平台的数据类型是有差异的,ios直接是JSON对象,android是JSON格式的字符串,为了统一数据格式在获取楼层数据this.props.data时需要使用Util.getSafeFloorData(this.props.data)方法,这样统一返回一个JSON对象。不过个人更建议直接在根组件中处理下,比如你的根组件视图是Home,那么我们可以使用Util.getSafeProps(this.props)方法处理this.props.data成统一的JSON对象: ```jsx render() { let safeProps = Util.getSafeProps(this.props) return ; } ``` 这样加这一处代码就可以确保Home里面的children组件视图可以安全放心的使用this.props.data的楼层数据 ### 关于像素问题 理论上我们设备是以iphone6为标注宽度是375像素,但是因为楼层布局的时候左右各留了12像素,所以在使用布局宽高的时候需要进行换算,可参考以下代码 ```jsx var { Platform,PixelRatio } = require('react-native'); const isApp = (Platform.OS == 'android' || Platform.OS == 'ios') ? true : false function getRpx(size){ if (!isApp) { return size } const windowWidth = window.width; const floorWidth = windowWidth - 24; const scale = floorWidth / 375; const rpx = size * scale; return PixelRatio.roundToNearestPixel(rpx); } ``` 所有布局都通过getRpx方法转一次,所以如果使用areslabs提供的JDDevice.width方法获取的宽度是真实设备的宽度,而不是楼层的宽度。所以建议一般使用View的话就不用写宽度,默认就是铺满楼层的宽度,或者使用getRpx(375)就是楼层宽度。比如:一张图片是宽是750、高是400,说明此时宽度是标准375的两倍,那么高度也要除于2,那么此时代码布局宽高分别是应该是getRpx(375)、getRpx(200)。