[Vue warn]: Invalid prop: type check failed for prop "right". Expected Number with value 15, got String with value "15". at <ElBacktop target=".layout-backtop-header-fixed .el-scrollbar__wrap" right="15" > at <ElMain class="layout-main" style="height: calc(100% - 85px)" > at <LayoutMain ref="layoutMainRef" >
錯誤的寫法:
Backtop 回到頂部 | Element Plus (element-plus.org)
2.
Missing required prop: "modelValue" at <Admin/org/menu onNodeClick=fn<onOrgNodeClick> class="my-flex-fill" select-first-node="" > at <AsyncComponentWrapper onNodeClick=fn<onOrgNodeClick> class="my-flex-fill" select-first-node="" >
OrgMenu 和<org-menu> 的關係是什麼?
interface Props { modelValue: number[] | null | undefined selectFirstNode: boolean } const props = withDefaults(defineProps<Props>(), { modelValue: () => [], selectFirstNode: false, })
改成:
const state = reactive({ loading: false, userFormTitle: '', filterModel: { name: '', }, total: 0, pageInput: { currentPage: 1, pageSize: 20, filter: { orgId: null, }, dynamicFilter: {}, } as PageInputUserGetPageDto, userListData: [] as Array<UserGetPageOutput>, filters: [ { field: 'name', operator: 'Contains', description: '姓名', componentName: 'el-input', defaultSelect: true, }, { field: 'mobile', operator: 'Contains', description: '手機號', componentName: 'el-input', }, { field: 'email', operator: 'Contains', description: '郵箱', componentName: 'el-input', }, { field: 'userName', operator: 'Contains', description: '用戶名', componentName: 'el-input', }, ] as Array<DynamicFilterInfo>, })
declare type ComponentEnum = 'el-input' declare type OperatorEnum = | 'Contains' | 'StartsWith' | 'EndsWith' | 'NotContains' | 'NotStartsWith' | 'NotEndsWith' | 'Equal' | 'Equals' | 'Eq' | 'NotEqual' | 'GreaterThan' | 'GreaterThanOrEqual' | 'LessThan' | 'LessThanOrEqual' | 'Range' | 'DateRange' | 'Any' | 'NotAny' | 'Custom' declare type DynamicFilterInfo = { field: string operator: OperatorEnum = 'Eq' value: string description: string defaultSelect: boolean componentName: ComponentEnum = 'el-input' }
組件component\my-select-input
<template> <el-input v-model="state.filter.value" class="my-input-with-select" clearable @keyup.enter="onSearch" v-bind="$attrs"> <template v-if="state.filters.length > 0" #prepend> <el-select v-model="state.filter.field" style="width: 100px" @change="onChange"> <el-option v-for="field in state.filters" :key="field.field" :label="field.description" :value="field.field" /> </el-select> </template> </el-input> </template> <script lang="ts" setup name="my-select-input"> import { reactive, PropType, watch } from 'vue' import { cloneDeep } from 'lodash-es' const props = defineProps({ modelValue: Object as PropType<any | undefined | null>, filters: { type: Array<DynamicFilterInfo>, default() { return [] }, }, }) const emits = defineEmits(['update:modelValue', 'search']) const filters = props.filters.filter((a) => a.componentName === 'el-input') let filter = {} as DynamicFilterInfo if (filters.length > 0) { filter = cloneDeep(filters.find((a) => a.defaultSelect) || filters[0]) } const state = reactive({ filters: filters, filter: { field: props.modelValue?.field || filter.field, operator: props.modelValue?.operator || filter.operator, value: props.modelValue?.value || filter.value, } as DynamicFilterInfo, }) const onChange = () => { state.filter.value = '' } const onSearch = () => { emits('search', cloneDeep(state.filter)) } watch( () => state.filter, () => { emits('update:modelValue', cloneDeep(state.filter)) }, { deep: true } ) </script> <style scoped lang="scss"> .my-input-with-select :deep(.el-input-group__prepend) { background-color: var(--el-fill-color-blank); } </style>