You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue2升级Vue3后readonly修饰符报错(TS1042)的解决方法

Vue3 defineComponent中使用readonly修饰符报错TS1042的解决方法

问题

将Vue2项目升级至Vue3后,在defineComponent配置中使用TypeScript的readonly修饰符定义错误提示常量时,出现编译错误:

'readonly' modifier cannot be used here.ts(1042)

原因

TypeScript的readonly修饰符仅支持在类属性或类型/接口定义中使用,无法直接作用于普通对象字面量(如defineComponent的配置对象)的属性上。Vue3组件选项的顶层属性不兼容这类TypeScript语法。

解决方案

1. 模块级常量定义(推荐)

错误提示文本属于静态不变的常量,无需挂载到组件实例,直接在组件外部用const定义即可,天然具备只读特性:

// 组件文件顶部定义只读常量
const percentagePayableInvalidErrorMsg = "Percentage payable value is invalid.";
const percentagePayableEmptyErrorMsg = "Percentage payable value cannot be empty.";
const gstInclusiveRequestedAmountInvalidErrorMsg = "Total amount (GST Inclusive) is invalid.";
const gstInclusiveRequestedAmountEmptyErrorMsg = "Total amount (GST Inclusive) cannot be empty.";
const gstRequestedAmountInvalidErrorMsg = "Total gst amount is invalid.";
const gstRequestedAmountEmptyErrorMsg = "Total gst amount cannot be empty.";
const gstRequestedAmountLessThanCheckErrorMsg = "Total gst amount cannot be larger than total amount (GST Inclusive).";

export default defineComponent({
  name: 'SubmitExpenseClaim',
  components: { /* ... */ },
  // 其他组件选项...
  
  // 模板中可直接引用这些常量,组件方法内直接使用即可
});

2. 挂载到组件实例(使用setup语法)

如果需要将这些常量作为组件实例的属性,建议改用Vue3的setup语法,结合Vue官方的readonly API(注意与TypeScript修饰符区分):

import { defineComponent, readonly } from 'vue';

export default defineComponent({
  name: 'SubmitExpenseClaim',
  components: { /* ... */ },
  // 其他组件选项...
  
  setup() {
    // 将错误提示包装为只读对象(不需要响应式可直接省略readonly)
    const errorMessages = readonly({
      percentagePayableInvalidErrorMsg: "Percentage payable value is invalid.",
      percentagePayableEmptyErrorMsg: "Percentage payable value cannot be empty.",
      gstInclusiveRequestedAmountInvalidErrorMsg: "Total amount (GST Inclusive) is invalid.",
      gstInclusiveRequestedAmountEmptyErrorMsg: "Total amount (GST Inclusive) cannot be empty.",
      gstRequestedAmountInvalidErrorMsg: "Total gst amount is invalid.",
      gstRequestedAmountEmptyErrorMsg: "Total gst amount cannot be empty.",
      gstRequestedAmountLessThanCheckErrorMsg: "Total gst amount cannot be larger than total amount (GST Inclusive)."
    });

    return { errorMessages };
  }
});

模板中使用示例:

<div>{{ errorMessages.percentagePayableInvalidErrorMsg }}</div>

额外修正提示

你的代码存在Vue3 Options API的规范问题:数据属性(如todayDate、expenseClaim等)不能直接放在defineComponent顶层,需移入data函数:

export default defineComponent({
  // ...其他选项
  data() {
    const todayDate = new Date();
    return {
      todayDate,
      todayDateUTC: new Date(Date.UTC(todayDate.getFullYear(), todayDate.getMonth(), todayDate.getDate(), 0, 0, 0)),
      expenseClaimCreatedDate: new Date(),
      initialExpenseClaim: { /* ... */ } as ExpenseClaimModel,
      expenseClaim: JSON.parse(JSON.stringify(this.initialExpenseClaim)) as ExpenseClaimModel,
      expenseClaimLines: [],
      initialExpenseClaimLinesCount: 1,
      isAdmin: false,
      isStandardUser: false
    };
  }
});

内容的提问来源于stack exchange,提问作者Kanchana Kariyawasam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 17:47:11