Taro开发过程遇到的问题汇总(更新日期2022-09-16)

十三、sentry监听小程序的报错信息(需后端搭建服务)

参考资料地址 https://lvan-zhang.blog.csdn.net/article/details/113448674
1、先安装sdk $ yarn add sentry-miniapp


//下面的代码放在Taro项目的app.js文件里
import * as Sentry from 'sentry-miniapp'
const version = Taro.getAccountInfoSync().miniProgram.version || 'alpha'
// 初始化 Sentry
Sentry.init({
  dsn: '后端配置的dsn',
  release: version
})


//用于传额外的信息,可以是当前用户姓名,id,手机号等信息,字段都是自定义的,随便写
Sentry.setUser({
   id: userInfo.userId,
   name: userInfo.name,
   phone: userInfo.phone
 })

十二、最近使用了taro-hooks开发项目,也换了UI框架,个人感觉还不错,使用上跟antd差不多,部分组件稍微有点区别

组件地址 https://antmjs.github.io/vantui/#/dialog

1、比如第十一条表单卡顿问题,form组件基本上解决了卡顿问题(只适合一个页面单个表单,并且提交的内容不是太多的情况)。

十一、表单卡顿问题

在这里插入图片描述
1、多层嵌套,触发原生组件渲染,不再是state更新组件的value值;(层级太深,不太好操作数据)
2、表单的卡顿主要的视觉效果是input的输入卡顿,其他的比如radio,select除了渲染值可能慢了点,其他的都不明显;
我主要讲解input的优化,解决卡顿问题。将input封装成一个组件,代码如下:

input组件
import React, { Component } from 'react'
import {Input} from "@tarojs/components";

class InputBox extends Component{
  state={
    value:this.props.value
  }
  shouldComponentUpdate(nextProps, nextState, nextContext) {
    //这个是触发input使用原生渲染的关键,必须添加,内容不需要添加任何东西
  }

  render() {
    let {name,placeholder,onValueChange} = this.props
    return <Input
      name={name}
      placeholder={placeholder}
      value={this.state.value}
      className='form_item'
       这个方法是父级传来的方法,用来存储input输入的值,表单提交的时候使用
      onInput={(e)=>onValueChange(e.target.value,name)} 
    />
  }
}
export {InputBox}

///父级页面
//引用input组件
import {InputBox} from "./components/Inputbox";

onValueChange (value,name) {
   let inputValueArr = {...this.state.inputValueArr};///浅拷贝数据,存储表单要提交的数据
   inputValueArr[name]=value;
   this.setState({
     inputValueArr
   })
}

//表单内使用方式
 <Form>
	<InputBox
        name='nickname'
        placeholder={'请输入姓名'}
        value={this.state.inputValueArr.nickname}
        onValueChange={this.onValueChange.bind(this)}
      />
 </Form>

以上代码在使用原生组件的情况下解决表单卡顿问题,其他的组件应该是同样的封装组件,然后父级引用使用(ps:理论上其他的比如说radio,select等,根据上面的代码修改下应该是不卡的,我只使用过input,哈哈,有问题可以私信我)

十、小程序下拉刷新功能

在需要分享的页面对应的config.js里添加 enablePullDownRefresh:true
onPullDownRefresh ()方法和componentDidMount()同级;

 onPullDownRefresh = () => {//添加监听下拉事件,刷新页面
    //这里调用方法获取最新数据
  };

九、分享小程序功能

onShareAppMessage() 方法和componentDidMount()同级;

onShareAppMessage() {分享功能
      return {
        title: "分享的标题",
        path: 'pages/index/index?id=' + id,  // 自定义的分享路径,点击分享的卡     片之后会跳转这里定义的路由
        imageUrl: '' // 图片路径,如果没有,那么展示的就是分享页面的预览图
      };
  }

八、echarts图表层级太高问题

![在这里插入图片描述](https://img-blog.csdnimg.cn/b78e042bfb1149e1b5f04abfa533d3f1.png)
在微信开放文档里已经描述了,view已经可以代替cover-view,不被echarts遮住了。但是我们在开发的过程中发现,开发工具中依然是echarts遮住其他组件的状态。<font color=#f73131>**这个其实是微信开发工具的显示bug**</font>,代码在实机上跑,会神奇的发现,echarts图表并没有遮住其他的组件。

一、图片上传

点击上传按钮时

  Taro.uploadFile({
    url: 'http://xxx/api/common_file/', //仅为示例,非真实的接口地址
    filePath: files[0].file.path,//Taro组件返回的图片信息
    header: {
      'Authorization':'JWT '+ token
    },
    name: 'file',//修改上传文件的名称
    formData: {
      'name': 'test'//上传文件的名称
    },
    success (res){
      console.log(result);
    },
    fail(){
      Taro.showToast({
        title: '上传失败,请联系管理员',
        icon:'none',
        duration: 2000
      })
    }
  })


/*组件onchange事件调用*/
 onChange (files,operationType,index) {图片上传
    let that=this;
    console.log(files);
    if(operationType==="remove"){///清除图片
       //移除事件后需操作的写在这边
    }else {//图片上传
      UploadFile(files,index,that)
    }
  }

二、多个input渲染后,修改其中一个,其他的也会跟着变化

input里的name名不能重复,Taro是根据name名修改对象input值的,所以将name名变不同了,相互之间就没有影响了

三、经常有同学想用微信的一些功能,但不知道在Taro中怎么调用。其实Taro都封装过了,参考地址如下,里面有常用的和不常用的功能

用的到的本地存储方法

//使用方法跟h5一样
//存储方法
Taro.setStorageSync({"key","value"})//
//读取方法
Taro.getStorageSync("key")   //值为value

经常用的到的跳转方法

//跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
Taro.switchTab({
  url: '/index'
})
//关闭所有页面,打开到应用内的某个页面
Taro.reLaunch({
  url: 'test?id=1'
})
//关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
Taro.redirectTo({
  url: 'test?id=1'
})
//保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 Taro.navigateBack 可以返回到原页面。小程序中页面栈最多十层。
Taro.navigateTo({
  url: 'test?id=1',
  events: {
    // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
    acceptDataFromOpenedPage: function(data) {
      console.log(data)
    },
    someEvent: function(data) {
      console.log(data)
    }
    ...
  },
  success: function (res) {
    // 通过eventChannel向被打开页面传送数据
    res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'test' })
  }
})
//关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层。
//如果跳转层级超出了应有的层级会报错的
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码
// 此处是A页面
Taro.navigateTo({
  url: 'B?id=1'
})
// 此处是B页面
Taro.navigateTo({
  url: 'C?id=1'
})
// 在C页面内 navigateBack,将返回A页面
Taro.navigateBack({
  delta: 2
})

更多功能查看官网地址示例
https://taro-docs.jd.com/taro/docs/apis/about/desc

四、接口请求全局添加拦截器

import Taro from "@tarojs/taro";
//配置的常量文件
import {BASE_URL} from '../lib/constant';

/**
 * http request 拦截器
 */
const interceptor = function (chain) {
  const requestParams = chain.requestParams;
  let { url } = requestParams;
  //console.log(requestParams)
  //完整的请求地址
  //console.log(requestParams);
  将请求地址修改为完整的请求地址
  requestParams.url=BASE_URL+url;
  //接口添加Authorization
  let gToken=Taro.getStorageSync('token');///获取本地存储的token
  //添加用户身份验证信息,Authorization
  requestParams.header={
    'Content-Type':"application/json"
    'Authorization':gToken?('JWT '+ gToken.split("&&")[0]):''
  };
  //小程序不支持patch接口,所以在接口里添加一个'patch/'标记为patch的接口
  if(url.match('patch')){
    requestParams.url=BASE_URL+url.replace('patch/','');//将接口里标记为patch方法的字符串去掉
    requestParams.header={
      'Content-Type':"application/json",
      'Authorization':gToken?('JWT '+ gToken.split("&&")[0]):'',
      //添加请求头,中间件将post方法设置为patch方法,解决小程序不支持patch方法的问题,需与后台商议,      让他做下处理
      'X-HTTP-Method-Override':'PATCH' 
    };
  }
  return chain.proceed(requestParams)
    .then(res => {
        return res
    }).catch((error) => {
        return error
    });
};
Taro.addInterceptor(interceptor);///为请求添加拦截器

let Axios={//为了从pc端copy方便,封装成了同样的对象,哈哈
  /**
   * 封装get方法
   * @param url  请求url
   * @param params  请求参数
   * @returns {Promise}
   */
  get(url, params = {}) {
    return new Promise((resolve, reject) => {
      Taro.request({url,
        data: params,
        method:'GET'
      }).then((response) => {
        //console.log(response);
        if(response.statusCode < 300){//请求成功
          //接口返回的信息
          resolve(response.data);
        }else 
          //错误信息未返回,如果有需要返回,可以添加,用于特殊处理
          //resolve(response);
          msag(response)
        }
      }).catch((error) => {
          reject(error);
        });
    });
  },
  /**
   * 封装post方法
   * @param url  请求url
   * @param data  请求参数
   * @returns {Promise}
   */
  post(url, data) {
    return new Promise((resolve, reject) => {
      Taro.request({url,
        data: data,
        method:'POST'
      }).then((response) => {
        if(response.statusCode < 300){//请求成功
          resolve(response.data);
        }else {
          //错误信息未返回,如果有需要返回,可以添加,用于特殊处理
          //resolve(response);
          msag(response)
        }
      }).catch((error) => {
          console.log(error);
          msag(error);
          reject(error);
        });
    });
  },
};
export default Axios

//失败提示
function msag(err) {
  // hideLoading ()
  if (err ) {
    switch (err.statusCode) {
      ///根据实际情况自己处理接口错误信息提示
      case 400:
        
        break;
      case 401:

        break;

      case 403:
       
        break;

      case 404:
      
        break;

      case 408:
      
        break;

      case 500:
        
        break;

      case 501:
      
        break;

      case 502:

        break;

      case 503:
      
        break;

      case 504:
       
        break;

      case 505:
       
        break;
      default:
    }
  }
}

五、echarts图表
先安装插件

 $ yarn add echarts-taro3-react

安装完成后,我们开始封装一些基础的图表
创建bar.jsx文件

import React, { Component } from 'react'
import { View } from '@tarojs/components'
import { EChart } from 'echarts-taro3-react'

class Bar extends Component {

  componentDidMount() {
    if(this.props.data.x.length>0){
      this.refresh(this.props.data)
    }
  }
  refresh(data) {
    let x=data.x;
    let y=data.y;
    const option = {
      color:'#1e91ff',
      xAxis: {
        type: "value",
      },
      grid:{
        left:'2%',
        right:'6%',
        bottom:'4%',
        top:'15%',
        containLabel:true
      },
      tooltip: {
        trigger: 'item',
        formatter: '{b} : {c} ' + '人',
        confine:true ///解决tooltip被遮挡问题
      },
      yAxis: {
        type: "category",
        data: y,
      },
      series: [
        {
          data: x,
          type: "bar",
          showBackground: true,
          // 实现数字展示在柱状图
          label: {
            show: true,
            position: 'inside',
            color:'white'
          },
          itemStyle: {
            //这里是重点
            color: function(params) {
              //注意,如果颜色太少的话,后面颜色不会自动循环,最好多定义几个颜色
              var colorList = ['#5470C6','#91CB74', '#FAC858', '#EE6666', '#73C0DE','#3CA272', '#FC8452','#9A60B4'];
              return colorList[params.dataIndex%7]
            }
          }
        },
      ],
    };

    this.pieChart.refresh(option);
  }

  refPieChart = (node) => (this.pieChart = node);

  render() {
    return (
      <View className='chart pie-chart'>
        {this.props.data.x.length===0?
          <View className='noDate'>暂无统计数据</View>: <EChart ref={this.refPieChart} canvasId={this.props.id} />
        }
      </View>
    )
  }
}

export default Bar

接下来使用刚封装好的组件

import React, { Component } from 'react'
import { View} from '@tarojs/components'
import './center_echarts.less'
import '../main.less'
import Bar from '../../components/echarts/bar/bar'
import Pie from '../../components/echarts/pie/pie'
import Axios from '../../api/request'
import Taro from "@tarojs/taro";
export default class Center_echarts extends Component {
  state={
    area:{
      x:[],
      y:[]
    },
    areaKey:0,
  };
  componentWillMount () { }
  componentDidMount () {
    let _this=this;
    Axios.get('/api/v1/report/?type=area').then((res)=>{//柱状图
      if(res){
        if(res.data){
          let result=res.data;
          let x=[];
          let y=[];
          result.map((item)=>{
            y.push(item.province__name?item.province__name:'未知');
            x.push(item.count);
            return item
          });
          let area={
            x,y
          };
          _this.setState({
            area:area,
            areaKey:area.x.length
          })
        }
      }
    });
  }

  componentWillUnmount () { }

  componentDidShow () { }

  componentDidHide () { }

  render () {
    return (
      <View className='center_echarts'>
        <View className='echarts_box'>
          <View className='title'>各省份人数</View>
          //key的作用是用来重新加载组件的,area数据变化后,图表并不会自动刷新
          <Bar id='bar' data={this.state.area} key={this.state.areaKey}  />
        </View>
      </View>
    )
  }
}

更多echarts组件参考Taro物料市场 echarts-taro3-react

提示:自定义echart.js,自行前往echart官网(注意:版本需要选择4.9.0,不要勾选压缩,可下载下来后自行压缩) 按需构建echart.js,然后替换掉echarts-taro3-react/lib/ec-canvas/echart.js,压缩下来大概在600kb左右,比原来体积小了一大半。

六、小程序分享功能

componentDidMount () {}

//位置与componentDidMount同一级 ,添加后右上角可以点击分享了
onShareAppMessage() {分享功能 ,不能改为箭头函数,会失效的,啥?我为啥会知道?
      return {
        title: "分享小程序",
        path: 'pages/index/index',  // 自定义的分享路径,点击分享的卡片之后会跳转这里定义的路由
        imageUrl: '' // 图片路径
      };
  }

页面里点击实现分享功能,能够触发分享功能

 <Button openType='share'>分享小程序</Button>

七、小程序登录授权手机号

//进入首页时,先调用wx.login方法获取code
Taro.login({
success:function(res){
     let code=res.code;
     //这边后台根据code去查询用户是否已经登录过, xxx是后台的接口
     Axios.post('/api/v1/xxx/', {code:res.code,type:small_progress_type}).then((res)=>{//接口获取openid
        if(res){
          //这边根据后台返回的数据做些判断,本地存储下用户是否已经授权注册过
        }
      });
  }
})



getPhoneNumber=(e)=>{///获取用户手机号
  console.log('获取手机号');
  if(e){///授权登录
    let iv=e.detail.iv;
    let encryptedData=e.detail.encryptedData;
    console.log(e);
    if(iv&&encryptedData){
      Taro.showLoading({
        title: '授权中...',
      });
      //后台根据iv&&encryptedData解密出手机号
      toGetPhoneNum(iv,encryptedData);
    }else {
      ///用户拒绝授权
      console.log('用户拒绝授权');
      callback();
    }
  }
};

 //用户未授权注册过,引导用户点击授权登录按钮,微信已经不让自动弹出获取手机号的界面了,只能用户点击了才能出现,嗯嗯,干的漂亮。
 <Button type='primary'  openType ="getPhoneNumber" onGetPhoneNumber ={(e)=>getPhoneNumber(e,'',id,name)}>授权登录</Button>
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值