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>
操作步骤:
- 子组件查看
onMounted
的console.log
是否打印, onClick
中的console.log
是否打印
预期结果:
- 可以正常触发
实际结果:
- 无法触发
bug描述:
- 抖音小程序子组件中
onBeforeMount
,onMounted
等事件不触发,defineEmits
也不触发。 - 经测试,web app、快手小程序、微信小程序均正常,且HBuilderX退回3.99也正常。
- 可复现的附件代码已上传
更多关于uni-app HBuilderX4.0.8 抖音小程序 子组件中onBeforeMount, onMounted 等事件不触发,defineEmits也不触发的实战教程也可以访问 https://www.itying.com/category-93-b0.html
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
开发抖音小程序时,如果遇到 onBeforeMount
、onMounted
等生命周期钩子不触发,或者 defineEmits
不触发的问题,可能是以下几个原因导致的:
1. 抖音小程序的生命周期与 Vue 3 生命周期不完全一致
抖音小程序的运行环境与 Vue 3 的生命周期并不完全一致,某些 Vue 3 的生命周期钩子可能无法正常触发。特别是 onBeforeMount
和 onMounted
这类钩子,在抖音小程序中可能无法正常工作。
解决方案: 使用抖音小程序原生的生命周期钩子来代替 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');
},
},
});