最近在用 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 into
a-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 类型。
以上就是整理的一些小问题,都不是很严重,之后会陆续记录一些这样的问题,帮助自己积累。