半驯之马
半驯之马
  • 发布:2022-12-30 11:27
  • 更新:2023-12-01 09:19
  • 阅读:980

【报Bug】vue3 使用setup语法糖的情况下,调用getCurrentPages无法获取到上一页使用defineExpose暴露出来的数据

分类:uni-app

产品分类: uniapp/H5

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: win10

HBuilderX类型: 正式

HBuilderX版本号: 3.6.15

浏览器平台: Chrome

浏览器版本: 108.0.5359.125

项目创建方式: HBuilderX

示例代码:

首页代码

<template>  
    <view class="content">  
        <navigator url="/pages/test/test" hover-class="navigator-hover">  
            <button type="default">跳转到新页面</button>  
        </navigator>  
    </view>  
</template>  

<script setup>  
    const pageCb = () => {  
        console.log('nextPage call !')  
    }  

    defineExpose({  
        pageCb  
    })  
</script>  

<style>  

</style>  

test页面中,调用上一页的pageCb 函数代码

<template>  
    <view>  
        <button type="default" @tap="handleClick">调用上一页的pageCb函数</button>  
    </view>  
</template>  

<script setup>  
    const handleClick = () => {  
        let pages = getCurrentPages()  
        let prevPage = pages[pages.length - 2]  
        console.log(prevPage.$vm,'prevPage.$vm')  
        console.log(prevPage.$vm.pageCb,'prevPage.$vm.pageCb')  
        prevPage.$vm?.pageCb?.()  
    }  
</script>  

<style>  

</style>  

操作步骤:

首页跳转至其他页面,在该页面中,调用getCurrentPages,获取首页实例,调用首页defineExpose暴露出来的pageCb函数,结果为undefined

预期结果:

应能正确调用上一页的$vm实例中暴露出来的函数

实际结果:

无法获取到上一页的$vm实例中暴露出来的函数

bug描述:

vue3 使用setup语法糖的情况下,调用getCurrentPages无法获取到上一页使用defineExpose暴露出来的数据

在HBuilderX版本号3.6.4中不会出现该问题,不知道这个问题是不是因为3.6.13版本中将vite 依赖版本升级至最新 3.1.8而导致的

2022-12-30 11:27 负责人:无 分享
已邀请:

最佳回复

DCloud_UNI_WZF

DCloud_UNI_WZF

pagesItem._.exposed

  • 半驯之马 (作者)

    为什么是这样引用,3.5.x的版本是可以通过pagesItem.$vm,xx直接调用的,getCurrentPages对应的文档上也没有具体的说明

    2022-12-30 13:37

  • 半驯之马 (作者)

    且以下划线_命名的变量,通常代表是私有变量

    2022-12-30 13:47

  • DCloud_UNI_WZF

    回复 半驯之马: 我这边测试 HBuilderX 3.5.x 及 3.6.4 无法通过 pagesItem.$vm,xx 拿到页面 defineExpose 的数据

    vue 设计 defineExpose 的使用方式是父组件获取子组件 defineExpose 的数据,uniapp 目前对该使用方式的支持是ok的

    uniapp并不支持 页面间通过 defineExpose 通信,可以使用 eventChannel 等方式

    2022-12-30 15:14

  • 半驯之马 (作者)

    回复 DCloud_UNI_WZF: 不是,你没理解我的意思,我的意思是上一个页面中定义了一个pageCb的函数,在当前页面中,我想调用上一个页面的pageCb函数,在vue2中,是通过getCurrentPages获取页面栈,执行pagesItem.$vm.pageCb,这是可行的对吧,但是在vue3中,我使用了setup的语法糖,同样定义了pageCb函数,打印pagesItem.$vm.pageCb得到的值是undefined,这是不是不合理

    2022-12-30 15:43

  • 半驯之马 (作者)

    回复 DCloud_UNI_WZF: 而且在HBuilderX版本号3.6.4中,同样的代码,是可以获取到pagesItem.$vm.pageCb的,你可以用我提问的示例代码实验一下

    2022-12-30 15:45

  • DCloud_UNI_WZF

    回复 半驯之马: 我理解你的意思了,只不过你说之前版本可以,我理解是vue3 defineExpose 这样用可以,结果你说的的 vue2 获取页面事件

    这两者压根不是一码事,defineExpose 也不是这么用的,如果你想获取页面setup中定义的数据,可以通过pageItem.$.setupState

    2022-12-30 16:49

  • 半驯之马 (作者)

    回复 DCloud_UNI_WZF: 我之所以提到defineExpose ,是因为之前的版本,必须要调用defineExpose来暴露对应的数据,这样getCurrentPages获取到的页面栈中,才会有对应的数据,我是之前写的代码,现在升级HBuilderX版本后发现失效了,才来提的bug

    2022-12-30 18:13

  • 半驯之马 (作者)

    为什么之前的版本通过defineExpose暴露数据后,其他页面就可以通过pageItem.$vm.xx获取,而现在则要pageItem.$.setupState,官方并没有在更新日志中提到,所以我认为这是个bug

    2022-12-30 18:17

  • DCloud_UNI_WZF

    回复 半驯之马: 提供下你的测试工程

    2022-12-30 20:33

  • 半驯之马 (作者)

    回复 DCloud_UNI_WZF: 你好,我上传了test的zip文件,可供复现

    2023-01-03 09:12

  • DCloud_UNI_WZF

    回复 半驯之马: 使用你提供的测试工程,HBuilderX 3.6.4 test 同样无法获取到 index defineExpose 暴露的pageCb

    2023-01-03 11:27

  • 半驯之马 (作者)

    回复 DCloud_UNI_WZF: 真的吗?我用测试代码,在HBuilderX 3.6.4下,录制了一个视频,已上传到附件,证实代码是可以获取到pageCb的,请看test-video.zip这个附件

    2023-01-03 13:32

  • DCloud_UNI_WZF

    回复 半驯之马: 看了你的视频,不确定哪里的差异,这边无法复现,也可以加我微信远程看下 13641039885

    但是这样使用本身不在框架的考虑范围,所以确定了原因,也不一定会安排人力处理该问题,建议改用框架支持的通信方式

    2023-01-03 13:49

  • 半驯之马 (作者)

    回复 DCloud_UNI_WZF: 明白了,多谢!

    2023-01-03 14:05

  • 竹林遇风

    回复 半驯之马: pageItem.$.setupState是什么方法

    2023-03-10 16:31

  • d大强

    回复 半驯之马: 在小程序中无法使用。报错,is not a function

    2023-10-07 10:32

命三千

命三千

我做小程序也遇到这个问题,用getCurrentPages,获取不到上一个页面的变量。官方好像也没有文档说一下怎么这个vue3.2语法糖怎么获取上一页变量

竹林遇风

竹林遇风

楼主,后来怎么解决这个问题的

  • 半驯之马 (作者)

    官方的说法是pagesItem.$vm这种调用方法不在官方的规范内,我后面都改用uni.$emit了

    2023-03-16 18:38

d大强

d大强

官方文档里只是写了对vue2的用法,vue3不兼容,可也没有在文档里说明,这太不友好了。搜了好多帖子才找到如何用的。
这种方式 pageItem.$.setupState, 可以用的, 不用在上一个页面中 defineExpose ,里面的变量和方法,都可以直接用。
另外一种就得在上一个页面中使用 defineExpose, 然后使用的页面,才可以 用 ,用的方式:pageItem.$.exposed.functionName();
h5中可以这么用,小程序中没测试,不知道能用吧。

d大强

d大强

我用了 这种方法 pageItem.$.exposed.functionName(); 后,在运行的时候, 都可以正常获取的到,但是,在发布H5后, 部署完后, 就不能用了, 我真是醉了。

  • YUANRJ

    参考下 https://ask.dcloud.net.cn/question/164801

    2023-12-01 10:23

  • d大强

    回复 YUANRJ: 你的那种方法,在开发环境中是可以的,但是在发布生成H5后,生产环境中,是错误的。提示pageItem.$vm.$.function() 中的 $ 属性 undefined, 这个 $ 属性在生产环境中是不存在的。

    现在的解决方法是: pageitem._.exposed.function()

    2023-12-22 10:51

要回复问题请先登录注册