uniapp做微信小程序总结

358 阅读4分钟
1、自定义title问题
<!-- 自定义header -->
      <view class="custom-header">
        <view :style="{height: iStatusBarHeight + 'px'}">
        <!-- 这里是状态栏 class="status_bar" navigationBarHeight -->
        </view>
        <view
          class="header-content"
          :style="{height: navigationBarHeight + 'px', 'line-height': navigationBarHeight + 'px'}"
        >
          <view class="custom-title">
            <!-- :style="{opacity: opacity}" -->
            <text class="title-text">
              title名称
            </text>
          </view>
        </view>
        <view
          class="return-img"
          :style="returnStyle"
          @click="returnPage"
        >
          <text class="iconfont icon-left" />
        </view>
      </view>
      <!-- 自定义header -->
const systemInfo = uni.getSystemInfoSync()
export function getMenuPosition() { // 微信小程序自定义导航 获取右上角胶囊位置
  let top = 4
  let right = 7
  let width = 87
  const height = 32
  if (systemInfo.platform === 'devtools' && systemInfo.system.indexOf('Android') === -1) {
    top = 6
    right = 10
  } else if (systemInfo.platform === 'devtools' && systemInfo.system.indexOf('Android') != -1) {
    top = 8
    right = 10
  } else if (systemInfo.system.indexOf('Android') != -1) {
    top = 8
    right = 10
    width = 95
  }
  return {
    top: systemInfo.statusBarHeight + top,
    left: systemInfo.windowWidth - width - right,
    width: width,
    height: height
  }
}
// 格式化style
export function formatStyle(position) {
  const styles:any = []
  for (const key in position) {
    styles.push(`${key}: ${position[key]}px;`)
  }
  return styles.join(' ')
}
// html
<!-- 自定义header -->
  <view class="custom-header">
    <view :style="{height: iStatusBarHeight + 'px'}">
    <!-- 这里是状态栏 class="status_bar" navigationBarHeight -->
    </view>
    <view
      class="header-content"
      :style="{height: navigationBarHeight + 'px', 'line-height': navigationBarHeight + 'px'}"
    >
      <view class="custom-title">
        <!-- :style="{opacity: opacity}" -->
        <text class="title-text">
          title名称
        </text>
      </view>
    </view>
    <view
      class="return-img"
      :style="returnStyle"
      @click="returnPage"
    >
      <text class="iconfont icon-left" />
    </view>
  </view>
<!-- 自定义header -->


//  ts
import { getMenuPosition, formatStyle } from '@/common/js/util' // 引入

// 定义变量
private iStatusBarHeight = 0
private navigationBarHeight = 0
private returnStyle = ''

private onLoad(option:pageOption) { // 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object
    this.iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight
    const menuTitle = getMenuPosition()
    this.navigationBarHeight = (menuTitle.top - this.iStatusBarHeight) * 2 + menuTitle.height // 获取计算导航栏高度
    this.returnStyle = formatStyle({ top: this.iStatusBarHeight, 'line-height': this.navigationBarHeight })
  }
2、图片加载中显示默认图问题
原理是利用api中的@load事件实现。 // 本想做一下,但发现有写好的轮子 uniapp组件库中fr-image,拿过来修改成自己想要的既可用;
3、音频歌词解析lrc srt

// 我这里用的插件,但因为没办法直接获取到歌词,所以先下载了

export function fsFileSync(url, duration) { // url 音频歌词文件路径 duration音频时长
  return new Promise((resolve, reject) => {
    uni.downloadFile({
      url,
      success: (res) => {
        if (res.statusCode === 200) {
          fs.readFile({
            filePath: res.tempFilePath,
            encoding: 'utf8',
            // position: 0,
            success(res) {
              const fileType = url.substring(url.lastIndexOf('.'), url.length)
              let musicListText: any = {
                scripts: []
              }
              if (fileType === '.lrc') {
                musicListText = lrcParser(res.data, duration) // parseLrc(res.data)
              } else {
                const parser = new srtParser2()
                musicListText.scripts = parser.fromSrt(res.data) // 解析srt
                musicListText.scripts.map((item: any) => {
                  item.start = +timeTransition(item.startTime).toFixed(3)
                  item.end = +timeTransition(item.endTime).toFixed(3)
                })
              }
              console.log(musicListText)
              resolve(musicListText)
            },
            fail(res) {
              console.error(res)
              reject(res)
            }
          })
        } else {
          reject(res)
        }
      },
      fail(res) {
        console.log(res)
        wx.showToast({ title: '歌词文件下载失败!', icon: 'none' })
        reject(res)
      }
    })
  })
}
4、音频其他问题
(1)、监听初始化放在背景音频设置src之前,防止有时onCanPlay事件有时不触发问题;

(2)、音频获取时长有时会获取不到,失效,可用setTimeout延迟获取;

(3)、播放、下一首、上一首按钮控制尽量直接调用play、pause等事件,然后在监听事件里面控制按钮的显示改变;

(5)、如为BackgroundAudioManager背景音频,可全局获取;

(6)、切换音频(更改src)之后立即获取时长duration 基本获取不到,且可能获取到上一个音频的duration。(注:如要兼容pc端小程序,则尽量让后端返音频时间长度);

(7)、在onCanplay方法中调用seek(加防抖控制不要死循环);

(8)、全局背景音频onWaiting监听方法中不要用全局的showLoading();
5、分享相关
 // 我是直接写在了个文件里,然后main.ts中引入

import { Component, Vue } from 'vue-property-decorator'
@Component({})
  
export default class Mixin extends Vue {
  private config = {
    title: '丽声英语阅读'
  }
    
  private onShareAppMessage(res:any) { // 发送给朋友
    return {
      title: this.config.title
    }
  }

  private onShareTimeline(res:any) { // 分享到朋友圈
    return {
      title: this.config.title
    }
  }
}

// main.ts

import share from '@/api/share'
Vue.mixin(share)

// 这样全局都有了。如某个页面不需要,则单独在其文件中禁用即可

// 分享小程序至朋友圈有些不同,注意查看文档developers.weixin.qq.com/miniprogram…

6、样式兼容问题
1、小米手机小米pad不好使,小米pad横屏和竖屏获取的宽度不一致(默认竖屏,当横屏时两侧留白情况下)
    /* 多行文字省略 */
    display: -webkit-box;
    overflow: hidden;
    text-overflow: ellipsis;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
   
 2、rpx单位在ipad兼容不太行
7、z-index在ios下不生效问题
    据说是:iOS的弹性滑动属性`-webkit-overflow-scrolling: touch`会导致`z-index`属性失效;
    但从官方的组件模块了解到: 原生组件的层级是**最高**的,所以页面中的其他组件无论设置 `z-index` 为多少,都无法盖在原生组件上。而`canvas` 组件是由客户端创建的原生组件。
    
    部分 CSS 样式无法应用于原生组件,例如:
    -   无法对原生组件设置 CSS 动画
    -   无法定义原生组件为 `position: fixed`
    -   不能在父级节点使用 `overflow: hidden` 来裁剪原生组件的显示区域
    
    解决方案是,可以用其他原生组件覆盖,具体看文档:

8、canvas元素被隐藏时无法生成图片

不知道什么鬼原因,亲试当canvas元素隐藏时,# wx.canvasToTempFilePath()方法不执行 与第7条差不多 canvas就是原生组件,z-index对它无效,遮挡不住,只有用后插入的其他组件遮掩之前的原生组件。还有一些其他的问题,可查看微信文档中的原生组件使用限制

9、表单组件radio-group不要使用display:flex布局

使用display:flex;会导致change事件选取有偏差,改为使用display:inline-flex即可;

10、滚动穿透问题

当一个页面较长,产生了滚动条。然后在其中有一个蒙层选择组件。例如:弹窗、勾选数据等,此时就会产生滚动穿透的问题。 解决方案1(不可行)在组件显示or隐藏时,控制变量true&false添加样式{height:100vh;overflow:hidden;} 此时可以解决了滚动穿透问题,但是页面会被默认滚动至顶部,不会定位在触发蒙层的地方; 解决方案2(官方给的):在组件显示or隐藏时,控制变量true&false添加

<page-meta :page-style="'overflow:'+(pageVisible?'hidden':'visible')"></page-meta>

即可完美解决滚动穿透问题,注意:直接放组件页面template最顶层;只能放一个