uni-app nvue引入vue组件时,获取data-*的数据结构不正确,且整页为vue情况下,子组件@tap事件无法获取data-*的数据
uni-app nvue引入vue组件时,获取data-*的数据结构不正确,且整页为vue情况下,子组件@tap事件无法获取data-*的数据
类别 | 信息 |
---|---|
产品分类 | uniapp/App |
PC开发环境 | Windows |
PC版本号 | window 10 |
HBuilderX类型 | 正式 |
HBuilderX版本 | 4.29 |
手机系统 | iOS |
手机版本号 | iOS 14 |
手机厂商 | 苹果 |
手机机型 | iphone 6s |
页面类型 | nvue |
vue版本 | vue2 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
示例代码:
tapOption(e) {
console.log(e)
// #ifdef APP-NVUE
var index = e.currentTarget.attr.dataIndex
// #endif
// #ifndef APP-NVUE
var index = e.currentTarget.dataset.index
// #endif
this.$emit('tapindex', {detail: {index: index}})
}
操作步骤:
- 点击列表下的某一栏
预期结果:
{
"type": "click",
"timeStamp": 1731902250741,
"target": {
"id": "",
"attr": {
"dataIndex": 2
},
"offsetLeft": 0,
"offsetTop": 0
},
"currentTarget": {
"id": "",
"attr": {
"dataIndex": 2
},
"offsetLeft": 0,
"offsetTop": 0
},
"detail": {},
"stopPropagation": "function() { [native code] }"
}
实际结果:
{
"type": "click",
"timeStamp": 1731902250741,
"target": {
"id": "",
"dataset": {
"index": 2
},
"offsetLeft": 0,
"offsetTop": 0
},
"currentTarget": {
"id": "",
"dataset": {
"index": 2
},
"offsetLeft": 0,
"offsetTop": 0
},
"detail": {},
"stopPropagation": "function() { [native code] }"
}
走的位置是:
// #ifdef APP-NVUE
var index = e.currentTarget.attr.dataIndex
// #endif
是没错的
bug描述:
index.nvue 引用了一个 子组件:report-box.vue,在子组件的列表下每栏都有点击事件:[@tap](/user/tap)="tapOption" :data-index="index"
,在nvue的情况下,获取index 应该是 e.currentTarget.attr.dataIndex
,而不是 e.currentTarget.dataset.index
看你的代码:@tap=“tapOption” :data-index=“index”, 调用子组件的地方,是能拿到index的。如果是想父组件获取点击的子组件的index的话,这样写:
父组件中:
<reportBox @click=“showIndex(index)” />
你这个是整块子组件的点击事件,我这个是子组件下的 某个栏目的点击事件 子组件: <view> <view v-for="(item,index) in list" :key="index"> <view @tap=“tapOption” :data-index=“index”>{{ item }}</view> </view> </view> <scrpit> export default { methods: { tapOption(e) { /* { “type”: “click”, “timeStamp”: 1731902250741, “target”: { “id”: “”, “attr”: { “dataIndex”: 2 }, “offsetLeft”: 0, “offsetTop”: 0 }, “currentTarget”: { “id”: “”, “attr”: { “dataIndex”: 2 }, “offsetLeft”: 0, “offsetTop”: 0 }, “detail”: {}, “stopPropagation”: “function() { [native code] }” } / console.log(e) // #ifdef APP-NVUE // 执行了这步 var index = e.currentTarget.attr.dataIndex // #endif
} } } </script>
是能解决,但它就是一个bug
以前是 e.currentTarget.attr.dataIndex 现在不知道为啥会变成 e.currentTarget.dataset.index 而且好诡异的事 用整个页面用vue的话 在子组件 现在是获取不了data-*的值
回复 7***@qq.com: 我刚才好像理解错你意思了。其实问题点在于nvue页面引用vue组件,然后vue组件里的条件编译走的却是 nvue平台是吧? 这一点我就不清楚了。 然后获取data-的方式,没看到文档有提到nvue和vue需要区别处理。。。
在uni-app中,nvue页面与vue页面存在一些差异,特别是在处理自定义属性和事件时。针对你提到的问题,我们分别来看如何在nvue中引入vue组件并正确获取data-*
属性,以及如何在整页为vue的情况下让子组件的@tap
事件获取data-*
的数据。
1. 在nvue中引入vue组件并获取data-*
属性
在nvue中引入vue组件时,由于nvue和vue的渲染机制不同,直接操作DOM或获取自定义属性可能会遇到问题。一个推荐的解决方案是通过事件机制传递数据。
Vue组件(MyComponent.vue):
<template>
<view @tap="handleTap">
<!-- 其他内容 -->
</view>
</template>
<script>
export default {
methods: {
handleTap(event) {
// 假设data-info是你要传递的数据
const dataInfo = event.currentTarget.dataset.info;
this.$emit('tap-event', dataInfo);
}
}
}
</script>
nvue页面:
<template>
<page>
<stack>
<frame src="/pages/MyComponent/MyComponent.vue" @tap-event="handleVueTapEvent" />
<!-- 注意:这里实际上不能直接监听vue组件的事件,需要通过其他方式通信,如全局事件总线 -->
</stack>
</page>
</template>
<script>
export default {
methods: {
handleVueTapEvent(data) {
console.log('Vue组件传递的数据:', data);
}
},
mounted() {
// 假设使用了一个全局事件总线来监听vue组件的事件
globalEventBus.$on('tap-event', this.handleVueTapEvent);
},
beforeDestroy() {
globalEventBus.$off('tap-event', this.handleVueTapEvent);
}
}
</script>
注意:由于nvue与vue之间的通信限制,这里示例了通过全局事件总线(需自行实现)来传递事件,实际项目中可能需要根据具体情况调整。
2. 在整页为vue的情况下,子组件@tap
事件获取data-*
的数据
在纯vue页面中,获取data-*
属性相对简单,可以直接在事件处理函数中通过event.currentTarget.dataset
访问。
父组件:
<template>
<MyComponent data-info="someData" @tap="handleChildTap" />
</template>
<script>
import MyComponent from './MyComponent.vue';
export default {
components: { MyComponent },
methods: {
handleChildTap(event) {
const dataInfo = event.detail.dataInfo; // 假设子组件通过detail传递了数据
console.log('子组件传递的数据:', dataInfo);
}
}
}
</script>
子组件(MyComponent.vue):
<template>
<view @tap="handleTap">点击我</view>
</template>
<script>
export default {
methods: {
handleTap(event) {
const dataInfo = event.currentTarget.dataset.info;
this.$emit('tap', { dataInfo });
}
}
}
</script>
这样,父组件就可以正确接收到子组件通过@tap
事件传递的data-*
数据了。