uni-app HBuilderX4.0.8 抖音小程序 子组件中onBeforeMount, onMounted 等事件不触发,defineEmits也不触发

uni-app HBuilderX4.0.8 抖音小程序 子组件中onBeforeMount, onMounted 等事件不触发,defineEmits也不触发

项目信息 详情
产品分类 uniapp/小程序/字节跳动
PC开发环境操作系统 Mac
PC开发环境操作系统版本号 14
HBuilderX类型 正式
HBuilderX版本号 4.08
第三方开发者工具版本号 4.2.2
基础库版本号 3.16.0.0
项目创建方式 HBuilderX

示例代码:

<template>  
    <view class="app" :class="[cusClass]" :style="[cusStyle]">  
        <slot name="header"></slot>  
        <slot></slot>  
        <button @click="hClick">点击</button>  
    </view>  
</template>  

<script lang="ts">  
export default {  
    name: 'app-page',  
    options: { virtualHost: true }  
};  
</script>  

<script lang="ts" setup>  
import { onMounted } from 'vue';  

const emits = defineEmits<{
    (e: 'click'): void;  
}>();  

defineProps({
    /** 宽度 */
    width: { type: String, default: undefined },  
    /**高度 */
    height: { type: String, default: undefined },  
    /** 是否需要登录 */
    login: { type: Boolean, default: true },  
    /** 是否为自定义导航栏 */
    customNav: { type: Boolean, default: false },  
    /** 自定义的样式属性 */
    cusStyle: { type: Object, default: () => ({}) }, // eslint-disable-line vue/prop-name-casing  
    /** 自定义类名 */
    cusClass: { type: String, default: '' } // eslint-disable-line vue/prop-name-casing  
});  

onMounted(() => {  
    console.log('问问');  
});  

function hClick() {  
    emits('click');  
}  
</script>  

<style scoped lang="scss">  
.app {  
    display: flex;  
    flex-direction: column;  

    .loading-view {  
        display: flex;  
        align-items: center;  
        justify-content: center;  
    }  
}  
</style>  
<template>  
    <view class="content">  
        <app-page @click="onClick">  
            <image class="logo" src="/static/logo.png"></image>  
            <view class="text-area">  
                <text class="title">c爱情恰恰es</text>  
            </view>  
        </app-page>  
    </view>  
</template>  

<script lang="ts" setup>  
import { onBeforeMount } from 'vue';  
onBeforeMount(() => {  
    console.log('43434534ere543435');  
});  

function onClick(){  
    console.log('点击');  
}  

</script>  

<style>  
.content {  
    display: flex;  
    flex-direction: column;  
    align-items: center;  
    justify-content: center;  
}  

.logo {  
    height: 200rpx;  
    width: 200rpx;  
    margin-top: 200rpx;  
    margin-left: auto;  
    margin-right: auto;  
    margin-bottom: 50rpx;  
}  

.text-area {  
    display: flex;  
    justify-content: center;  
}  

.title {  
    font-size: 36rpx;  
    color: #8f8f94;  
}  
</style>  

操作步骤:

  • 子组件查看onMountedconsole.log是否打印,
  • onClick中的console.log是否打印

预期结果:

  • 可以正常触发

实际结果:

  • 无法触发

bug描述:

  • 抖音小程序子组件中onBeforeMount, onMounted等事件不触发,defineEmits也不触发。
  • 经测试,web app、快手小程序、微信小程序均正常,且HBuilderX退回3.99也正常。
  • 可复现的附件代码已上传

tr.zip


更多关于uni-app HBuilderX4.0.8 抖音小程序 子组件中onBeforeMount, onMounted 等事件不触发,defineEmits也不触发的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

app web 微信小程序,快手小程序均正常,就抖音小程序异常

更多关于uni-app HBuilderX4.0.8 抖音小程序 子组件中onBeforeMount, onMounted 等事件不触发,defineEmits也不触发的实战教程也可以访问 https://www.itying.com/category-93-b0.html


退回3.99 是正常的

感谢反馈,而且你也提供了复现代码。
你提到子组件不能正确 emit click 事件,旧版本支持,新版本不支持。我复现了你提到的问题。
这个问题和 https://ask.dcloud.net.cn/question/188489 相似。
临时解决方案 子组件去掉 virtualHost: true 或者编写条件编译,在抖音平台 virtualHost=false
错误原因 3.99 版本在抖音小程序平台不支持 virtualHost: true ,所以写了也不会生效 新版本支持了抖音小程序的 fragment 功能,组件编写了 virtualHost=true 会使用 fragment 进行模拟
但是抖音小程序文档明确说明了这个限制:
启用 Fragment 组件节点时,需要注意以下几点:
自定义组件节点上的 id、class、style 将不再生效;
自定义组件节点上绑定的事件将不再生效; // 这一条是错误原因 因为有这个限制,会导致你的 emit 失效,这个目前是平台功能限制,产生了差异。
后面,会对抖音小程序做兼容提示,让 virtualhost=true 进行兼容处理

uni-app 中使用 HBuilderX 4.0.8 开发抖音小程序时,如果遇到 onBeforeMountonMounted 等生命周期钩子不触发,或者 defineEmits 不触发的问题,可能是以下几个原因导致的:


1. 抖音小程序的生命周期与 Vue 3 生命周期不完全一致

抖音小程序的运行环境与 Vue 3 的生命周期并不完全一致,某些 Vue 3 的生命周期钩子可能无法正常触发。特别是 onBeforeMountonMounted 这类钩子,在抖音小程序中可能无法正常工作。

解决方案: 使用抖音小程序原生的生命周期钩子来代替 Vue 3 的生命周期钩子。例如:

  • 使用 onLoad 代替 onMounted
  • 使用 onReady 代替 onBeforeMount

例如:

export default {
  onLoad() {
    console.log('组件加载完成');
  },
  onReady() {
    console.log('组件渲染完成');
  },
};

2. defineEmits 不触发

defineEmits 是 Vue 3 的 Composition API 中用于定义子组件向父组件传递事件的方法。如果 defineEmits 不触发,可能是以下原因:

  • 父组件未正确监听子组件的事件。
  • 抖音小程序的运行环境对 Vue 3 的某些特性支持不全。

解决方案: 检查父组件是否正确监听子组件的事件。例如:

子组件:

<script setup>
const emit = defineEmits(['myEvent']);

const handleClick = () => {
  emit('myEvent', 'Hello from child');
};
</script>

<template>
  <button @click="handleClick">Click Me</button>
</template>

父组件:

<template>
  <ChildComponent @myEvent="handleEvent" />
</template>

<script setup>
const handleEvent = (message) => {
  console.log('Received:', message);
};
</script>

如果仍然无法触发,可以尝试使用抖音小程序原生的 triggerEvent 方法。


3. 抖音小程序的兼容性问题

抖音小程序的运行环境对 Vue 3 的某些特性支持可能有限,导致某些 API 无法正常工作。

解决方案:

  • 使用兼容性更好的 Vue 2 语法。
  • 使用抖音小程序原生的方法,例如 Component 构造器来定义组件。

例如:

Component({
  methods: {
    handleClick() {
      this.triggerEvent('myEvent', 'Hello from child');
    },
  },
});
回到顶部