阅读 2112

Taro爬坑血泪史

Taro爬坑血泪史

一、介绍

  • Taro 是一个开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发 微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ 小程序 / H5 等应用。现如今市面上端的形态多种多样,Web、React Native、微信小程序等各种端大行其道,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。
  • Taro 2.X 支持react
  • Taro 3.0 支持vue/vue3

二、安装

# 使用 npm 安装 CLI
$ npm install -g @tarojs/cli
# 使用命令创建模板项目
$ taro init myApp
# 安装依赖
$ npm install
复制代码

++注意:依赖版本保持一致++

三、编译以及打包

"scripts": {
    "build:weapp": "taro build --type weapp", //微信
    "build:swan": "taro build --type swan", // 百度
    "build:alipay": "taro build --type alipay", //阿里
    "build:tt": "taro build --type tt",  //字节
    "build:h5": "taro build --type h5",  //H5
    "build:qq": "taro build --type qq",  //qq
    "build:quickapp": "taro build --type quickapp",
    "dev:weapp": "npm run build:weapp -- --watch",
    "dev:nopre:weapp": "set NODE_ENV=devNoPre && npm run build:weapp -- --watch",
    "dev:swan": "npm run build:swan -- --watch",
    "dev:alipay": "npm run build:alipay -- --watch",
    "dev:tt": "npm run build:tt -- --watch",
    "dev:h5": "npm run build:h5 -- --watch",
    "dev:rn": "npm run build:rn -- --watch",
    "dev:qq": "npm run build:qq -- --watch",
    "dev:quickapp": "npm run build:quickapp -- --watch",
    "lint-staged": "lint-staged"
  },
复制代码

四、项目目录结构

├── dist                   编译结果目录
├── config                 配置目录
|   ├── dev.js             开发时配置
|   ├── index.js           默认配置
|   └── prod.js            打包时配置
├── src                    源码目录
|   ├── pages              页面文件目录
|   |   ├── index          index 页面目录
|   |   |   ├── index.js   index 页面逻辑
|   |   |   └── index.css  index 页面样式
|   ├── app.css            项目总通用样式
|   └── app.js             项目入口文件
└── package.json
复制代码

五、多端编译

let pages = []
if (process.env.TARO_ENV === 'weapp') {
  pages = [
    '/pages/index/index'
  ]
}
if (process.env.TARO_ENV === 'swan') {
  pages = [
    '/pages/indexswan/indexswan'
  ]
}
export default {
  pages
}
复制代码

六、单位转化

小程序、H5尺寸单位统一

  • 把rpx替换成px
  • run dev:h5后,会自动编译成rem单位(行内样式无法自动转换,一些Taro-ui框架内的scss无法自动转化,需要手动调整,原因未知)
/config/index.js
const config = {
  projectName: 'myProject',
  date: '2018-4-18',
  designWidth: 640,
  ....
}
复制代码

七、优化

1.分包

config:[
    pages:[],
    subpages:[]
]
复制代码

2.预渲染

  • 将页面初始化的状态直接渲染为无状态(dataless)的 wxml,在框架和业务逻辑运行之前执行渲染流程。经过 Prerender 的页面初始渲染速度通常会和原生小程序一致甚至更快。
const config = {
  ...
  mini: {
    prerender: {
      match: 'pages/shop/**', // 所有以 `pages/shop/` 开头的页面都参与 prerender
      include: ['pages/any/way/index'], // `pages/any/way/index` 也会参与 prerender
      exclude: ['pages/shop/index/index'] // `pages/shop/index/index` 不用参与 prerender
    }
  }
};

module.exports = config
复制代码

3.长列表渲染

  • 只渲染当前可视区域(visible viewport)的视图
<VirtualList
    height={500} /* 列表的高度 */
    width='100%' /* 列表的宽度 */
    itemData={data} /* 渲染列表的数据 */
    itemCount={dataLen} /*  渲染列表的长度 */
    itemSize={100} /* 列表单项的高度  */
>
    {Row} /* 列表单项组件,这里只能传入一个组件 */
</VirtualList>
复制代码

八、技术选型

React、Typescript、Mobx、Hooks

九、小程序

1.第三方H5网页跳转

  • 需要配置第三方https证书,且第三方服务器需要添加一个业务域名校验文件,并小程序后台配置业务域名,详情查看小程序后台开发配置

2.input卡顿问题

输入框快速输入,或者快速删除数据卡顿闪屏问题

  • 绑定旧值,监听onChange事件设置旧值的拷贝值,==避免组件依赖值更新==,即可解决方法
const [formData, setFormData] = useState(initState)
const [selfFormState, setSelfFormState] = useState(initState)
const handleChange = (type, value) => {
    const newState = {
      ...selfFormState,
      [type]: value,
    }
      setSelfFormState(newState)
      //小程序需要return value
      return value
}
复制代码
<AtInput
  name='name'
  title='名称'
  type='text'
  required
  disabled
  placeholder='请输入名称'
  value={formData.name}
  onChange={(val) => {
    handleChange('name', val)
  }}
/>
复制代码

3.textArea层级最高,涉及到弹窗覆盖问题

弹窗被textArea遮挡的奇怪现象

  • 控制textArea的显示隐藏
<View>
  <AtForm onSubmit={onSubmit}>
    <View>
      <View style={{ visibility: show ? 'hidden' : 'visible' }}>
        <AtTextarea
          count={false}
          value={formData.tel}
          onChange={(val) => {
            handleChange('tel', val)
          }}
          maxLength={1000}
          placeholder={'请输入联系电话'}
        />
      </View>
    </View>
  </AtForm>
  {show && (
    <View>
      弹窗内容
    </View>
  )}
</View> 
复制代码

4.小程序后退页面刷新问题

例如从详情页进入编辑页,编辑完成后返回的情况下,小程序是不会重新请求新的数据。如果继续前进,会涉及到页面栈最大层级问题

  • 小程序返回的页面会触发==useDidshow==
function Index () {
  useDidShow(() => {
    // 校验用户状态
  })

  return (
    <View>
      测试
    </View> 
  )
}
复制代码

5.弹窗打开时,固定背景隐藏背景滚动条

  • 弹窗打开时背景添加css,隐藏滚动条
.at-modal__content {
  overflow-y: hidden;
  ::-webkit-scrollbar{
    width: 0;
    height: 0;
    color: transparent;
  }
}
复制代码

6.用户数据获取

授权操作弹窗,首次拒绝后 不会再次弹出

  • 非必要情况下建议使用开放组件==openData==展示用户头像及昵称
<OpenData type='userAvatarUrl'/>
复制代码

十、H5

1.Taro.request()H5端不返回数据

  • 用axios重新封装
export function generateTaroReq (config) {
  return async (data?: AjaxData) => {
    const res = await Taro.request({
      ...config,
      data,      
    })
    const { data: resData } = res
    return resData.data
  }
}
复制代码
export function generateTaroReq(axiosConfig:axiosConfig,config?:any): Function{
  const dataName = axiosConfig.method&&axiosConfig.method.toLowerCase() == 'post' ? 'data' : 'params'
  return (data?: Object) =>{
    return axios({
      method:axiosConfig.method,
      url:'/xxxx/'+axiosConfig.url,
      [dataName]:{
        ...data
      }
    }).then(res => {
      return res.data
    })
  }
}

const reqBankInfo = generateTaroReq({
  url: 'xxxxx/api',
  method: 'POST'
})
reqBankInfo(_ajaxData)
复制代码

2.登录Taro.login()不可用

H5端无法调用

  • 替换成其他登录形式

3.position:fixed状态下ScrollView无法滚动

顶部tabs超出屏幕宽度时无法左右滑动

  • 如固定再头部的导航菜单左右滚动,则设置需要设置css属性(left和right)
.className{
    position:fixed;
    top:0;
    left:0;
    right:0;
}
复制代码

4.Taro.uploadFile()

  • H5端需要多加一个参数:fileName:'xxxx.png',不加接口会报错
const config = {
  url: '/xxxxx/uploadxImage',//上传接口
  filePath: path,
  name: 'file',
  fileName:'file.' + type,
  header: {
    Authorization: Taro.getStorageSync('token'),
  },
}
Taro.uploadFile(config)
复制代码

5.tabs切换报错

Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.

  • 原因是用了同一套数据,把list和showData分开就行
<AtTabs current={current} tabList={tabList} onClick={handleClick}>
    <AtTabsPane current={current} index={0}>
      <View key="0">
        {
        showData&&!loading?(
          view.map(item => {
            return <JinrongItem item={item}></JinrongItem>
          })):empty
        }
      </View>
    </AtTabsPane>
</AtTabs>
复制代码

== 改成 ==

<AtTabs current={current} tabList={tabList} onClick={handleClick}>
    <AtTabsPane current={current} index={0}>
      <View key="0">
        {showData&&!loading?(
          list.map((item, i) => {
            return <JirongItem value={item}></JirongItem>
          })):empty
        }
      </View>
    </AtTabsPane>
    <AtTabsPane current={current} index={1}>
      <View key="1">
        {showData2&&!loading?(
          list2.map((item, i) => {
            return <XuqiuLow xuqiukey={_keys[current]} key={item.id} isedit value={item}></XuqiuLow>
          })):empty
        }
      </View>
    </AtTabsPane>
</AtTabs>
复制代码

6.Taro.getCurrentPages()在H5和小程序中表现不同

  • H5中没有setData方法

7.Picker组件

onChange钩子,选择下标的取值方法

  • 小程序:const value = event.detail.value[0]
  • H5:const value = event.detail.value

8.Editor组件替换为zx-editor

9.Testarea组件绑定的value不能为null,否则会报length of null错误

<AtTextarea
    className="AtTextareaFix"
    count={false}
    value={textareaProps.value}
    onChange={textareaProps.onChange}
    maxLength={textareaProps.maxLength}
    placeholder={textareaProps.placeholder}
/>
复制代码

10.微信浏览器项目更新后拿不到最新的js文件

h5: {
    publicPath: '/',
    output: {
      filename: 'js/[name].[hash].js',
      chunkFilename: 'js/[name].[chunkhash].js'
    },
    miniCssExtractPluginOption: {
      filename: 'css/[name].[hash].css',
      chunkFilename: 'css/[name].[chunkhash].css',
    }
}
复制代码
文章分类
前端
文章标签