uni-app 【报Bug】APP export default (Vue as VueConstructor<Vue & xx>).extend({...}) 形式导出的组件在真机无法渲染

uni-app 【报Bug】APP export default (Vue as VueConstructor<Vue & xx>).extend({…}) 形式导出的组件在真机无法渲染

示例代码:

// foo.vue  

interface SomeProps {  
    foo: number  
}  

export default (Vue as VueConstructor<Vue & SomeProps>).extend({  
    ...  
})

操作步骤:

如上代码,真机调试

预期结果:

希望可以正常渲染组件;或者有可以避免ts报错更好的办法

实际结果:

组件无法渲染

bug描述:

Vue2 + Typescript 的 uniapp 项目,组件渲染异常

代码如下:

// foo.vue  

interface SomeProps {  
    foo: number  
}  

export default (Vue as VueConstructor<Vue & SomeProps>).extend({  
    ...  
})

用上述形式导出的vue组件,在App真机调试时无法渲染,H5正常。

背景:

为了避免出现像图中的报错(声明不在data、computed等上定义的属性时ts会报如图的错。。。),所以用了以上的写法,结果出现了真机无法渲染的问题。

希望可以正常渲染组件;或者有可以解决类似ts报错问题,又不影响uniapp组件渲染的更好的办法。


信息类别 信息内容
产品分类 uniapp/App
PC开发环境 Mac
PC版本号 12.01
HBuilderX类型 正式
HBuilderX版本 3.2.16
手机系统 Android
手机版本号 Android 10
手机厂商 华为
手机机型 HONOR ViewPad6
页面类型 vue
vue版本 vue2
打包方式 云端
项目创建方式 HBuilderX

更多关于uni-app 【报Bug】APP export default (Vue as VueConstructor<Vue & xx>).extend({...}) 形式导出的组件在真机无法渲染的实战教程也可以访问 https://www.itying.com/category-93-b0.html

13 回复

自顶一下

更多关于uni-app 【报Bug】APP export default (Vue as VueConstructor<Vue & xx>).extend({...}) 形式导出的组件在真机无法渲染的实战教程也可以访问 https://www.itying.com/category-93-b0.html


每日自顶

每日自顶。。

每日自顶。。。

每日自顶。。。。

每日自顶。。。。。

解决了吗

没呢。放弃了这种写法,不放 this 上,另外写了个变量存数据,曲线救国了

虽迟但到。。。找到原因和解决办法了老哥,不知道还对你有帮助不

终于发现了原因,真的吊诡,原因如下图:
详情链接:https://github.com/dcloudio/uni-app/blob/dev/packages/webpack-uni-mp-loader/lib/babel/scoped-component-traverse.js
大致原因就是 uniapp 在解析 “export default Vue.extend({components: {}})” 的时候判断了导出的变量名必须为 “Vue.extend”,改个名字都不行,不然就会导致引入的组件渲染异常。。不得不吐槽文档居然没半点信息。
知道原因这个问题就很好解决了,只有保证写的是 “Vue.extend” 即可。引入 Vue 的时候先定义个别名,再声明个变量 Vue 随便怎么操作都行。
举个例子: import _Vue from ‘vue’

const Vue = _Vue as AnyType

export default Vue.extend({…})

这个问题的根本原因是 uni-app 在 App 平台对 Vue 组件的导出方式有特殊处理要求。你使用的 (Vue as VueConstructor<Vue & SomeProps>).extend() 这种 TypeScript 增强写法在 H5 平台可以正常工作,但在 App 平台的真机环境中,uni-app 的编译机制无法正确识别这种导出形式。

解决方案:

  1. 标准导出方式(推荐) 使用 uni-app 支持的标准 Vue 组件导出方式:
// foo.vue
<script lang="ts">
import Vue from 'vue'

interface SomeProps {
    foo: number
}

export default Vue.extend({
    props: {
        foo: {
            type: Number,
            required: true
        }
    },
    // 其他组件选项
})
</script>
  1. 使用装饰器语法(如果需要更严格的类型检查) 安装并配置 vue-property-decorator
// foo.vue
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'

@Component
export default class FooComponent extends Vue {
    @Prop({ type: Number, required: true })
    foo!: number
    
    // 其他组件逻辑
}
</script>
  1. 如果必须使用你的原始写法 可以尝试将类型断言移到组件内部:
// foo.vue
<script lang="ts">
import Vue from 'vue'

interface SomeProps {
    foo: number
}

const ComponentOptions = {
    props: {
        foo: {
            type: Number,
            required: true
        }
    }
}

export default Vue.extend(ComponentOptions) as VueConstructor<Vue & SomeProps>
</script>
回到顶部