Vue3.0 项目开发 bug 整理与解决方案(一)

306 阅读2分钟

最近在用 vue3.0 + ts + AntD 开发项目,开发过程中遇到了一些 bug, 这里做一个简单的整理。

问题 1

问题说明: 项目做了国际化语言配置,在 i18n/index.ts 文件中做了如下配置:

import { createI18n } from 'vue-i18n' //引入 vue-i18n 组件
import { LangEnum } from '@/global/enums/style'
import cn from './cn'
import tw from './tw'
import { lang } from '@/global/settting'

// 语言数组
export const langList = [
  {
    label: '简体',
    key: LangEnum.CN
  },
  {
    label: '繁体',
    key: LangEnum.TW
  }
]
const i18n = createI18n({
  legacy: false,
  globalInjection: true,
  locale: localStorage?.lang || lang, // 从 localStorage 获取语言选择
  fallbackLocale: localStorage?.lang || lang,
  messages: {
    [LangEnum.CN]: cn,
    [LangEnum.TW]: tw
  },
  silentTranslationWarn: true,
});
export const t = i18n.global.t
export default i18n;

这样做配置后,在 vue 页面渲染调用方法直接为 {{ t('support.test.test') }} 或者 t('support.test.test')。在 ts 中的调用方法为 t('support.test.test'), 完整的应为 i18n.global.t('support.test.test'), 但在配置文件中做了一个简化, 将 i18n.global.t 作为 t 导出了, 参考语句 export const t = i18n.global.t。那么在 ts 文件中调用就遇到一个问题。我直接在 setting.ts 文件中定义全局变量, 如下代码所示:

export const tabsMenuMaster = [
  { title: 'Alive', key: 'Alive' },
  { title: 'Pilot Run', key: 'PilotRun' },
  { title: 'MP', key: 'MP' },
  { title: 'P/L', key: 'PL' },
  { title: t('tracking.common.drafts'), key: 'Drafts' }
]

此时系统就会报错提示:Cannot access 't' before initialization. 就是不能在初始化的时候识别 t 这个方法。

解决方案:就是用计算属性来定义变量,修改代码如下,问题得到解决。

export const tabsMenu = computed(() => {
  return [
    { title: 'Alive', key: 'Alive' },
    { title: 'Pilot Run', key: 'PilotRun' },
    { title: 'MP', key: 'MP' },
    { title: 'P/L', key: 'PL' },
    { title: t('tracking.common.drafts'), key: 'Drafts' }
  ]
})

问题 2

问题说明:在用 form 表单时,vue 代码如下:

 <a-form-item name="customerContactId" :label="label[13]" v-bind="config">
       <a-select v-model:value="componentInfo.customerContactId" show-search style="width:33%;"
          :placeholder="$t('tracking.common.pleaseChoose')" :options="customers" :filter-option="filterOption"
           @change="handleChange">
       </a-select>
      <a-checkbox v-model:checked="contactChecked" style="padding:0 0 0 30px">
      {{ $t('tracking.detail.sync') }}
      </a-checkbox>
</a-form-item>

此时系统会有一个警告提示:[ant-design-vue: Form.Item] FormItem can only collect one field item, you haved set ASelect, ACheield item, you haved set ASelect, ACheckbox2 field items. You can set not need to be collected fields intoa-form-item-rest`

意思就是 FormItem 只能包含一个组件,可以用 a-form-item-rest 来解决,

解决方案:将第二个组件用 包住,这样警告就没有了。代码如下:

 <a-form-item name="customerContactId" :label="label[13]" v-bind="config">
      <a-select v-model:value="componentInfo.customerContactId" show-search style="width:33%;"
          :placeholder="$t('tracking.common.pleaseChoose')" :options="customers" :filter-option="filterOption" @change="handleChange">
      </a-select>
      <a-form-item-rest>
        <a-checkbox v-model:checked="contactChecked"
          style="padding:0 0 0 30px">{{ $t('tracking.detail.sync') }}
        </a-checkbox>
      </a-form-item-rest>
</a-form-item>

问题 3

问题说明:定义了数据接口如下和常量如下:

interface FormState {
  pid: number;
  grandId: number;
  grandChname: string;
  grandEgname: string;
  childChname: string;
  childEgname: string;
  chname: string;
  egname: string;
  level: number;
}

const formState = reactive<FormState>({
  pid: undefined,
  grandId: undefined,
  grandChname: '',
  grandEgname: '',
  childChname: '',
  childEgname: '',
  chname: '',
  egname: '',
  level: 2
});

使用的过程中想要删掉 formState 中的一些属性,使用 delete formState.pid 就会报错:"delete" 运算符的操作数必须是可选的。

解决方案:将接口定义做如下修改,错误消失,代码如下:

interface FormState {
  pid?: number ;
  grandId?: number;
  grandChname?: string;
  grandEgname?: string;
  childChname?: string;
  childEgname?: string;
  chname?: string;
  egname?: string;
  level?: number;
}

因为属性本来就有可能不存在,如果用 delete 就是删除不存在的属性,所以在接口定义的时候加上 ? 符号,就表示定义的属性也具有 undefined 类型。

以上就是整理的一些小问题,都不是很严重,之后会陆续记录一些这样的问题,帮助自己积累。