vue3开发uniapp转字节小程序注意事项

vue3开发uniapp转字节小程序注意事项

  • 1.provide-inject 跨层通信不支持问题
  • 2.不能自定义头部,需要去申请
  • 3.不能使用moment 日期插件
  • 4.不要再组件中使用onShow、onLoad等生命周期
  • 5.picker-view、picker-view-column抖音小程序无法选中问题

开发相关地址 1.抖音开放平台 2.开发者平台
项目本身是vue3+ts+uniapp写的微信小程序,因产品需求要转换成抖音小程序

1.provide-inject 跨层通信不支持问题

uniapp转的抖音小程序,在使用隔代注入时,因为底层生命周期问题没办法在setup声明周期中拿到inject的数据,后写了demo问了抖音技术客服,说是uniapp自身问题。。。没提供解决方案
https://github.com/dcloudio/uni-app/issues/3360#issuecomment-1074913528
目前解决方案:1.使用store去平替,但要注意响应式数据相关业务
2.使用正常传参方式(不推荐)
3.使用eventsBus (不推荐)
vue3开发uniapp转字节小程序注意事项_第1张图片

2.不能自定义头部,需要去申请

https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/open-capacity/basic-capacities/custom-page-structure

3.不能使用moment 日期插件

使用moment包会导致编译预览时无法预览vue3开发uniapp转字节小程序注意事项_第2张图片
解决方案
utils/index.ts

/**
 * 处理时间格式
 * @param format 格式 eg:yyyy-MM-dd HH:mm:ss
 * @param date  时间对象|字符串
 */
export const formatTime = (
  format = 'yyyy-MM-dd HH:mm:ss',
  date: Date | string = new Date(),
  padZero = true,
): string => {
  if (typeof date === 'string') date = new Date(date)
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()
  const formatMap: { [key: string]: any } = {
    yyyy: year.toString(),
    MM: padZero ? month.toString().padStart(2, '0') : month.toString(),
    dd: padZero ? day.toString().padStart(2, '0') : day.toString(),
    HH: padZero ? hour.toString().padStart(2, '0') : hour.toString(),
    mm: padZero ? minute.toString().padStart(2, '0') : minute.toString(),
    ss: padZero ? second.toString().padStart(2, '0') : second.toString(),
  }
  return format.replace(/yyyy|MM|dd|HH|mm|ss/g, (match) => formatMap[match])
}

使用方法

const formattedDate = formatTime();
console.log(formattedDate); // 输出:当前时间,格式为 'yyyy-MM-dd HH:mm:ss'
const customFormat = formatTime('dd/MM/yyyy HH:mm');
console.log(customFormat); // 输出:例如 '21/09/2024 15:30'
const date = new Date('2023-01-01T12:00:00');
const formattedDate = formatTime('yyyy-MM-dd', date);
console.log(formattedDate); // 输出:'2023-01-01'
const formattedDate = formatTime('MM-dd-yyyy', '2024-09-21');
console.log(formattedDate); // 输出:'09-21-2024'
const formattedDate = formatTime('HH:mm:ss', new Date(), false);
console.log(formattedDate); // 输出:例如 '3:5:7'
// 转换中文日期字符串为标准格式
const str = '2024年09月21日'
const dateStr = str.replace(/年|月/g, '-').replace(//, '')
// 使用 formatTime 获取格式化的日期
console.log(formatTime('yyyy-MM-dd', dateStr)) // 2024-09-21

4.不要再组件中使用onShow、onLoad等生命周期

在微信小程序中:子组件中使用onShowonLoad是可以生效的
在抖音小程序中:不生效
查了一下官方文档:onShowonLoad是属于页面及生命周期,而不是组件及。同时官网也没有在在组件中使用的例子,所以我们不要因为微信好使而就不规范写法

官方Vue3 页面及组件生命周期流程图
vue3开发uniapp转字节小程序注意事项_第3张图片
微信小程序中可以生效
vue3开发uniapp转字节小程序注意事项_第4张图片
抖音小程序中无效果
vue3开发uniapp转字节小程序注意事项_第5张图片
解决方案

  • 如果已经使用了,那么请尽快用类似的解决方案平替
  • 本项目使用的是vue3,所以使用暴露方法,在根组件中调用子组件事件,也可以使用其他同理方案

子组件

<script setup lang="ts">
// onShow(() => {
//   bannerList.value.length > 1 && (isAutoPlay.value = true)
// })

const handleChildShow = () => {
  bannerList.value.length > 1 && (isAutoPlay.value = true)
}

defineExpose({
  handleChildShow,
})
</script>

父/根组件

<script setup lang="ts">
import BannerCom from './components/bannerCom.vue'
const bannerComRef = ref<typeof BannerCom>()
onShow(() => {
  bannerComRef.value && bannerComRef.value?.handleChildShow()
})
</script>
<template>
	<!-- 图片 -->
	<banner-com ref="bannerComRef" />
</template>

5.picker-view、picker-view-column抖音小程序无法选中问题

分析大概原因是,dom节点加载的问题(可能不准确)
:immediate-change="true" 官方上demo这个为true时就有问题 所以应先变为false

解决方案

等出发了选中结束事件在去拿值就准确了

<script setup lang="ts">
const isBindEnd = ref(true)
const bindEnd = () => {
  isBindEnd.value = true
}
// 切换事件
const bindChange: UniHelper.PickerViewOnChange = (e) => {
  isBindEnd.value = false
}

// 确定按钮
const onClickConfirmPopup = (): void => {
if (!isBindEnd.value) return
  // 单列
  emit('confirm-popup', singleSelectObj)
}
onClosePopup()
}

// 关闭弹出层
const onClosePopup = (): void => {
  emit('close-popup')
}

</script>
<template>
 <text @tap="onClickConfirmPopup">确定</text>
   <picker-view
     :immediate-change="false"
     indicator-class="indicatorClass"
     :value="valueList"
     @change="bindChange"
     @pickstart="isBindEnd = false"
     @pickend="bindEnd"
     class="picker-view"
   >
     <picker-view-column>
       <view class="item" v-for="item in singleList" :key="item.id"
         >{{ item.name }}{{ popupUnit }}</view
       >
     </picker-view-column>
   </picker-view>
</template>

你可能感兴趣的:(vue3.0,uniApp,uni-app,小程序,vue)