uniapp微信小程序转支付宝小程序的坑

1,512 阅读2分钟

因为一些客户需要支付宝小程序,上个月的的时候就在给我们的产品的基础版本做支付宝小程序转化,也就有了这篇文章。

u-icon的class属性无效

我们的产品中有使用uview组件库,有很多标题开头会带一个图标、或者一些下拉框的箭头之类的,u-icon在微信端可以使用class属性,去给他设置尺寸啊、间距之类的。类似于这样

<u-icon
  custom-prefix="iconfont"
  name="disease-info"
  color="$baseColor"
  class="u-m-r-15"
  size="32"
/>

但是在支付宝小程序完全失效了。是因为微信端会有个u-icon元素去继承class属性,然而支付宝并不会。

image.png

image.png

然而事实上组件本身提供color、costom-style、size等属性,非必要不推荐用class去改变样式

image无法使用相对路径

这就很直接,字面意思,支付宝端image无法使用相对路径。支付宝小程序官方文档是这么说的

小程序包内相关资源图片需要放在image文件夹下面,否则不会将相关图片打包进小程序包导致小程序运行时引入相对路径的图片失败。 优化建议:建议将图片存到网络服务器上,通过url地址访问图片。

但是原来的代码有太多文件了,我干脆全绝对路径

mescroll组件相关问题

这个就不那么简单了,首先mescroll确实很好用,简单,便捷,但是没法辩驳的是其让我在支付宝小程序里遇到的问题。官方的建议是

绝大部分情况应优先考虑使用 mescroll-body因为支持原生组件,且性能好 只有当需要局部区域滚动 (如嵌在弹窗,浮层,swiper中), 才考虑mescroll-uni

然而事实上mescroll-uni+swiper仍然会有问题

  • swiper中的transfrom会使fixed失效,此时用height固定高度;
  • swiper中无法触发mescroll-mixins.js的onPageScroll和onReachBottom方法,只能用mescroll-uni,不能用mescroll-body;

然而做了这一切,手机上一运行仍然是徒劳无功,放到手机上去调试就发现他不会下拉回调,也就没法下拉加载,具体原因还未知,以下是我的(伪)代码,我总感觉是我用得不对,望指点。

<template>
  <mescroll-uni
    :ref="'mescrollRef' + i"
    :height="height"
    @init="mescrollInit"
    :down="downOption"
    @down="downCallback"
    :up="upOption"
    @up="upCallback"
  >
    <list-item :list="patientList" />
  </mescroll-uni>
</template>

<script>
import MescrollMixin from 'mescroll-uni/mescroll-mixins.js'
import listItem from './components/list-item.vue'
export default {
  mixins: [MescrollMixin],
  components: {
    listItem
  },
  props: {
    tabParams: Object,
    i: Number, // 每个tab页的专属下标
    index: { // 当前tab的下标
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      downOption: {
        auto: false, // 不自动加载 (mixin已处理第一个tab触发downCallback)
        offset: 50,
        fps: 100,
        outOffsetRate: 0.1
      },
      upOption: {
        auto: false, // 不自动加载
        page: {
          num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
          size: 5 // 每页数据的数量
        },
        noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
        empty: {
          tip: ''
        }
      },
      patientList: []
    }
  },
  watch: {
    tabParams(val) {
			if (this.i === val) {
				this.mescroll.resetUpScroll()
      }
    },
    index(val) {
		if (this.i === val) {
        	this.mescroll && this.mescroll.triggerDownScroll()
      	}
    },
    isSignIn(val) {
		if (this.i === val) {
        	this.mescroll && this.mescroll.triggerDownScroll()
      	}
    }
  },
  mounted() {
    this.height = uni.getSystemInfoSync().windowHeight - uni.upx2px(200)
	this.mescroll.resetUpScroll();
  },
  computed: {
    ...mapState({
	  mode: state => state.mode,
      isSignIn: (state) => state.isSignIn,
    }),
  },
  methods: {
    downCallback() {
      this.mescroll.resetUpScroll(); // 重置列表为第一页
    },
    upCallback(page) {
      console.log('页数:', page.num)
      if (page.num == 1) this.patientList = [] // 如果是第一页需手动置空列表
        // api调用
    },
  },
};
</script>

<template>
  <view class="futherConsultation">
    <list-tabs
      ref="furtherConsultationTabs"
      v-model="tabIndex"
      :tabs="tabs"
      :tabParams="tabParams"
      @Submit="submit"
    />
    <swiper :style="{ height: height }" :current="tabIndex" @change="swiperChange">
      <swiper-item v-for="(tab,i) of tabs" :key="i">
        <list-swiper-item
          ref="mescrollItem"
          :i="i"
          :index="i"
          :tabParams="tabParams"
        />
      </swiper-item>
    </swiper>
  </view>
</template>

<script>
import listTabs from './components/list-tabs-tabs.vue'
import listSwiperItem from './list-swiper-item.vue'
import { formatDate, timeFormat } from '@/utils/time.js'

export default {
  components: {
    listTabs,
    listSwiperItem
  },
  data() {
    return {
      canReset: false,
      height: '400px',
      tabIndex: 1,
      tabParams: { // tab参数
        startTime: formatDate(timeFormat('start', 7)),
        endTime: formatDate(timeFormat('end'))
      }
    }
  },
  onLoad() {
    this.height = uni.getSystemInfoSync().windowHeight - uni.upx2px(80) + 'px'
    this.tabParams = {
      ...this.tabParams,
      userName: this.$Route.query.userName || ''
    }
  },
  onShow() {
    if (this.canReset) {
      let curMescroll = this.getMescroll(this.tabIndex)
      curMescroll && curMescroll.resetUpScroll()
      this.$refs.furtherConsultationTabs.getMultipleStateReqPendingNum()
    }
    this.canReset = true
  },
  methods: {
    ...mapMutations(['UPDATE_Mode']),
    swiperChange(e) {
      this.tabIndex = e.detail.current
    },
  }
}
</script>

最终选择的妥协就是不使用swiper,直接改变列表数据,然而不使用swiper,mescroll出现的问题也不仅仅只是在swiper用不了,他在正常环境下,mescroll-body始终没法使用,尽管我设置了高度,但是这个问题可能是来源于我的使用不当,不做细究。用mescroll-uni又会撑满整个页面的高度,需要用height、top等属性去做处理,总之就是要不是原来都用的这个,不如自己写一个,除非是我用错了。

软键盘相关问题

软键盘的问题主要出现再苹果机型上,安卓机上会偶发获取键盘高度不正确以至于页面被上挤后出现一条很宽的白条。

image.png

不过貌似只在头几次访问中回偶然的出现,并不常见。苹果机型就有很多显眼的问题,软件盘弹出,页面不上挤,遮住输入框、弹框又会上挤,挤过头,以至于弹窗里的输入框超出视口,还会有如果用input去模拟textarea,会出现输入框聚焦,光标位置偏移的问题,然而解决起来却很简单。

uniapp的文档中的textarea属性fixed、adjust-position在支付宝统统无效,但是又没有给出解决办法,查看支付宝官方文档才能找到enableNative属性,把它设置为false就能够解决了,但是文档中还说input也有,但是实测下来并没有效果,所以会有问题的通通用txtarea取代了。 另外还有微信小程序没有文字长度的脚注,支付宝有,要注意一下

image.png