a***@aliyun.com
a***@aliyun.com
  • 发布:2022-04-13 15:01
  • 更新:2022-04-17 14:42
  • 阅读:1198

【报Bug】uni-app(HBuilderX)编译代码后供支付宝小程序工具再编译报错 : SyntaxError: ..."xxxxModel" is read-only

分类:uni-app

产品分类: uniapp/小程序/阿里

PC开发环境操作系统: Windows

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

HBuilderX类型: 正式

HBuilderX版本号: 3.3.13

第三方开发者工具版本号: 2.7.2

基础库版本号: 2.x

项目创建方式: HBuilderX

示例代码:
<template>  
  <view class="content">  
    <image class="logo" src="/static/logo.png"></image>  
    <view class="text-area">  
      <text class="title">{{title}}</text>  
    </view>  

    <uni-forms ref="testForm" v-model="testModel" errShowType="toast">  
      <uni-forms-item name="firestName" :rules="[{required: true, errorMessage: '姓名不能为空白'}]" label-width="0">  
        <uni-easyinput v-model="testModel.firstName" type="text" prefix-icon="person" maxlength="20" placeholder="请输入姓名" />  
      </uni-forms-item>  
    </uni-forms>  
  </view>  
</template>  

<script setup>  
  import {  
    ref,  
    reactive  
  } from 'vue'  
  const title = ref('这是首页')  

  const testForm = ref(null)  

  // 如果用 const、reactive,则编译为支付宝小程序时,报错:   
  /*  
  ERROR in ./pages/index:  
  Thread Loader (Worker 1)  
  SyntaxError: .../test-mp-alipay/unpackage/dist/dev/mp-alipay/pages/index/index.js: "testModel" is read-only  

    73 |           k: "testForm"  
    74 |         }),  
  > 75 |         f: common_vendor.o(($event) => common_vendor.isRef(testModel) ? testModel.value = $event : testModel = $event),  
       |                                                                                                    ^  
    76 |         g: common_vendor.p({  
    77 |           errShowType: "toast",  
    78 |           modelValue: common_vendor.unref(testModel)  

      at transpile (C:\snapshot\code-repo\out\target\bundle\node_modules\babel-loader\lib\index.js:65:13)  
      at Object.<anonymous> (C:\snapshot\code-repo\out\target\bundle\node_modules\babel-loader\lib\index.js:173:20)  
  */  
  const testModel = reactive({  
    firstName: ''  
  })  
</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>

操作步骤:

复现错误步骤如下:

  1. <template> 中定义表单:

    ...  
    <uni-forms ref="testForm" v-model="testModel" errShowType="toast">  
      <uni-forms-item name="firestName" :rules="[{required: true, errorMessage: '姓名不能为空白'}]" label-width="0">  
        <uni-easyinput v-model="testModel.firstName" type="text" prefix-icon="person" maxlength="20" placeholder="请输入姓名" />  
      </uni-forms-item>  
    </uni-forms>  
    ...
  2. <script setup> 中定义表单中绑定义变量:

    import {  
    ref,  
    reactive  
    } from 'vue'  
    const title = ref('这是首页')  
    
    const testForm = ref(null)  
    // 注:使用 const 使用支付宝小程序工具编辑时就错报了!!!  
    const testModel = reactive({firstName: ''})
  3. 使用 HBuildX ,点:运行/ 运行到小程序模拟器 / 支付宝小程度开发者工具, 支付宝小程序开发者工具编译就会报错。

预期结果:

uni-app 转换出来的小程序代码,正常应该是应该可以通过支付宝小程序开发工具编译的。

说明:为什么项目中会用 const?
这是因为:在项目中使用 vscode 之类开发工具,配置 ESLint + prettier 后,在写代码时,使用 let 定义变量之后,如果仅一次赋值,则保存时会自动更正为 const 。这有利于提高代码质量

实际结果:

uni-app 转换出来的小程序代码,通过支付宝小程序开发工具编译的报错
错误如下:

 ERROR in ./pages/index:  
  Thread Loader (Worker 1)  
  SyntaxError: e:/learn_workspace/vue3.0/uni-app-hello/test-mp-alipay/unpackage/dist/dev/mp-alipay/pages/index/index.js: "testModel" is read-only  

    73 |           k: "testForm"  
    74 |         }),  
  > 75 |         f: common_vendor.o(($event) => common_vendor.isRef(testModel) ? testModel.value = $event : testModel = $event),  
       |                                                                                                    ^  
    76 |         g: common_vendor.p({  
    77 |           errShowType: "toast",  
    78 |           modelValue: common_vendor.unref(testModel)  

      at transpile (C:\snapshot\code-repo\out\target\bundle\node_modules\babel-loader\lib\index.js:65:13)  
      at Object.<anonymous> (C:\snapshot\code-repo\out\target\bundle\node_modules\babel-loader\lib\index.js:173:20)

bug描述:

uni-app 编译出来的代码存在bug ,使用支付宝小程序开发者工具编译会报错

【复现步骤】 使用 HBuildX ,点:运行/ 运行到小程序模拟器 / 支付宝小程度开发者工具, 支付宝小程序开发者工具编译就会报如下错误:

  ERROR in ./pages/index:  
  Thread Loader (Worker 1)  
  SyntaxError:  .../test-mp-alipay/unpackage/dist/dev/mp-alipay/pages/index/index.js: "testModel" is read-only  

    73 |           k: "testForm"  
    74 |         }),  
  > 75 |         f: common_vendor.o(($event) => common_vendor.isRef(testModel) ? testModel.value = $event : testModel = $event),  
       |                                                                                                    ^  
    76 |         g: common_vendor.p({  
    77 |           errShowType: "toast",  
    78 |           modelValue: common_vendor.unref(testModel)  

      at transpile (C:\snapshot\code-repo\out\target\bundle\node_modules\babel-loader\lib\index.js:65:13)  
      at Object.<anonymous> (C:\snapshot\code-repo\out\target\bundle\node_modules\babel-loader\lib\index.js:173:20)

完整的代码,请查阅附件

2022-04-13 15:01 负责人:无 分享
已邀请:
DCloud_UNI_FXY

DCloud_UNI_FXY

非Bug,当绑定v-model="testModel"时,就意味着要给testModel重新赋值,重新赋值的话,就不能声明为const

  • a***@aliyun.com (作者)

    希望DCloud 官方再处理下此类 bug。


    如果改为:const testModel = ref({firstName: ''}) 就没得问题,这就可以说明 uni-app 在编译或转换为小程序代码时,有特殊的处理,但没考虑到表单 v-model 会帮定 const .... reactive(....) 之类的变量 ???

    2022-04-14 19:44

  • DCloud_UNI_FXY

    回复 a***@aliyun.com: ref的赋值方式是testModel.value = $event,这个不会触发const的限制,而reactive的赋值方式是testModel = $event,会触发限制,你使用标准的vue项目,一样有这样的问题

    2022-04-14 19:52

  • a***@aliyun.com (作者)

    回复 DCloud_UNI_FXY: 首先感谢您的再次回复。



    1. 如果按我说的写法,使用 vue 标准项目,并且使用 cli 方式创建,在 h5 下运行,亲测是一点问题都没有的,目前就是在经uni-app转换为支付宝小程序代码后,在小程序工具编译就会抛异常。

    2. 理论上来讲,对于 const testModel = reactive({.....}) 这种,uni-app转换为小程序代码,应改是“绑定”(比如用 Object.assign(testModel, $event)), 而不是重新赋值(testModel = $event), 我表达可能不太准确,但大致意思就是对于 const 这种变量不能重新赋值,本身这也是违反了 es6的语法规则。

    3. 如果您代表 DCloud 官方认为这真不是个bug或问题,那此类问题就些结束吧。我再考虑其他小程序开发技术方案。

    2022-04-16 12:19

  • DCloud_UNI_FXY

    回复 a***@aliyun.com: Object.assign(testModel,$event) 跟 testModel = $event 表达的意义不同,v-model需要的是=


    你认为标准vue项目没问题,是没在发行模式测试,你可以npm run build之后,预览,修改input里的值,一样会触发Assignment to constant variable.


    <script setup>    
    import { reactive } from 'vue'
    const model = reactive({})
    </script>
    <template>
    <input v-model="model"/>
    </template>

    2022-04-17 14:40

该问题目前已经被锁定, 无法添加新回复