Vue中提示报错handlers[i].call is not a function解决方法

本文解决了一个关于调用生命周期钩子函数导致的'handlers[i].callisnotafunction'错误,通过检查并修正未定义的方法或不完整的钩子函数实现,确保了功能的稳定性和降低了后续风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示报错信息handlers[i].call is not a function.....

虽然提示报错了功能还是目前来说还是可以使用,但是给后面留下来了非常大的风险性

那么首先你得知道这个提示是什么原因引起的~

从报错的handlers[i].call 入手查找原因--这个错误是 调用相关的生命周期钩子函数引起来的错误

生命周期钩子函数---那么有了方向我们去找相应报错页面

查看你的页面相关  生命周期钩子函数 是否有 声明了未定义方法 或是 只声名了钩子函数:

例如如图(生命周期钩子请自查看官网API,图文只举例其中一个)

把钩子删除,或是把你定义的方法写完全了就可以了!!

<template> <div ref="wrapRef" :class="getWrapperClass"> <BasicForm ref="formRef" submitOnReset v-bind="getFormProps" v-if="getBindValues.useSearchForm" :tableAction="tableAction" @register="registerForm" @submit="handleSearchInfoChange" @advanced-change="redoHeight" @field-value-change="useDebounceFn(redoHeight, 300)()" class="search-form"> <template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys"> <slot :name="item" v-bind="data || {}"></slot> </template> </BasicForm> <button @click="getFrom">123123</button> <Table ref="tableElRef" v-bind="getBindValues" class="ant-table-striped" :rowClassName="getCellStyle" v-show="getEmptyDataIsShowTable" @change="handleTableChange" @resizeColumn="handleResizeColumn"> <template #[item]="data" v-for="item in Object.keys($slots)" :key="item"> <slot :name="item" v-bind="data || {}"></slot> </template> <template #headerCell="{ column }"> <HeaderCell :column="getcolumn(column)" /> </template> <template #bodyCell="data"> <slot name="bodyCell" v-bind="data || {}"></slot> </template> </Table> </div> </template> <script lang="ts"> import type { BasicTableProps, TableActionType, SizeType, ColumnChangeParam } from './types/table'; import { BasicForm, useForm } from '@/components/Form'; import { PageWrapperFixedHeightKey } from '@/enums/pageEnum'; import { InnerHandlers } from './types/table'; import { defineComponent, ref, computed, unref, toRaw, inject, watchEffect, onMounted, reactive, watch } from 'vue'; import { Table } from 'ant-design-vue'; import HeaderCell from './components/HeaderCell.vue'; import { usePagination } from './hooks/usePagination'; import { useColumns } from './hooks/useColumns'; import { useDataSource } from './hooks/useDataSource'; import { useLoading } from './hooks/useLoading'; import { useRowSelection } from './hooks/useRowSelection'; import { useTableScroll } from './hooks/useTableScroll'; import { useTableScrollTo } from './hooks/useScrollTo'; import { useCustomRow } from './hooks/useCustomRow'; import { useTableStyle } from './hooks/useTableStyle'; import { useTableHeader } from './hooks/useTableHeader'; import { useTableExpand } from './hooks/useTableExpand'; import { createTableContext } from './hooks/useTableContext'; import { useTableFooter } from './hooks/useTableFooter'; import { useTableForm } from './hooks/useTableForm'; import { useDesign } from '@/hooks/web/useDesign'; import { useDebounceFn } from '@vueuse/core'; import { omit } from 'lodash-es'; import { basicProps } from './props'; import { isFunction } from '@/utils/is'; import { warn } from '@/utils/log'; export default defineComponent({ name: 'BasicTable', components: { Table, BasicForm, HeaderCell, }, props: { ...basicProps, loading: { type: Boolean, default: false, // 默认值 }, dataSource: { type: Array, default: () => [], // 允许外部传入数据源,默认为空数组 }, pagination: { type: Object, default: () => ({}), // 默认值 }, }, emits: [ 'fetch-success', 'fetch-error', 'selection-change', 'register', 'row-click', 'row-dbClick', 'row-contextmenu', 'row-mouseenter', 'row-mouseleave', 'edit-end', 'edit-cancel', 'edit-row-end', 'edit-change', 'expanded-rows-change', 'change', 'columns-change', 'changeMenu', ], setup(props, { attrs, emit, slots, expose }) { const tableElRef = ref(null); const tableData = ref<Recordable[]>([]); const wrapRef = ref(null); const formRef = ref(null); const innerPropsRef = ref<Partial<BasicTableProps>>(); const { prefixCls } = useDesign('basic-table'); const [registerForm, formActions] = useForm(); const getProps = computed(() => { return { ...props, ...unref(innerPropsRef) } as BasicTableProps; }); const isFixedHeightPage = inject(PageWrapperFixedHeightKey, false); watchEffect(() => { unref(isFixedHeightPage) && props.canResize && warn("'canResize' of BasicTable may not work in PageWrapper with 'fixedHeight' (especially in hot updates)"); }); const { getLoading, setLoading } = useLoading(getProps); const { getPaginationInfo, getPagination, setPagination, setShowPagination, getShowPagination } = usePagination(getProps); const { getRowSelection, getRowSelectionRef, getSelectRows, setSelectedRows, clearSelectedRowKeys, getSelectRowKeys, deleteSelectRowByKey, setSelectedRowKeys, } = useRowSelection(getProps, tableData, emit); const { getExpandOption, expandAll, expandRows, collapseAll, getIsExpanded } = useTableExpand(getProps, tableData, emit); const { handleTableChange: onTableChange, getDataSourceRef, getDataSource, getRawDataSource, getFetchParams, setTableData, updateTableDataRecord, deleteTableDataRecord, insertTableDataRecord, findTableDataRecord, fetch, getRowKey, reload, getAutoCreateKey, updateTableData, } = useDataSource( getProps, { tableData, getPaginationInfo, setLoading, setPagination, getFieldsValue: formActions.getFieldsValue, clearSelectedRowKeys, expandAll, }, emit, ); const addFakeData = () => { if (props.dataSource.length === 0) { tableData.value = []; } else { tableData.value = props.dataSource; // 使用传入的数据源 } }; function handleTableChange(...args) { onTableChange.call(undefined, ...args); emit('change', ...args); // 解决通过useTable注册onChange时不起作用的问题 const { onChange } = unref(getProps); onChange && isFunction(onChange) && onChange.call(undefined, ...args); } const { getViewColumns, getColumns, setCacheColumnsByField, setCacheColumns, setColumns, getColumnsRef, getCacheColumns } = useColumns( getProps, getPaginationInfo, ); const { getScrollRef, redoHeight } = useTableScroll(getProps, tableElRef, getColumnsRef, getRowSelectionRef, getDataSourceRef, wrapRef, formRef); const { scrollTo } = useTableScrollTo(tableElRef, getDataSourceRef); const { customRow } = useCustomRow(getProps, { setSelectedRowKeys, getSelectRowKeys, clearSelectedRowKeys, getAutoCreateKey, emit, }); const { getRowClassName } = useTableStyle(getProps, prefixCls); const handlers: InnerHandlers = { onColumnsChange: (data: ColumnChangeParam[]) => { emit('columns-change', data); unref(getProps).onColumnsChange?.(data); }, }; const { getHeaderProps } = useTableHeader(getProps, slots, handlers); const { getFooterProps } = useTableFooter(getProps, getScrollRef, tableElRef, getDataSourceRef); const { getFormProps, replaceFormSlotKey, getFormSlotKeys, handleSearchInfoChange } = useTableForm(getProps, slots, fetch, getLoading); const getBindValues = computed(() => { const dataSource = unref(getDataSourceRef); let propsData: Recordable = { ...attrs, ...unref(getProps), customRow: unref(getProps).customRow || customRow, ...unref(getHeaderProps), scroll: unref(getScrollRef), loading: unref(getLoading), tableLayout: 'fixed', rowSelection: unref(getRowSelectionRef), rowKey: unref(getRowKey), columns: toRaw(unref(getViewColumns)), pagination: toRaw(unref(getPaginationInfo)), dataSource, footer: unref(getFooterProps), ...unref(getExpandOption), }; propsData = omit(propsData, ['class', 'onChange']); return propsData; }); const getWrapperClass = computed(() => { const values = unref(getBindValues); return [ prefixCls, attrs.class, { [`${prefixCls}-form-container`]: values.useSearchForm, [`${prefixCls}--inset`]: values.inset, }, ]; }); const getEmptyDataIsShowTable = computed(() => { const { emptyDataIsShowTable, useSearchForm } = unref(getProps); if (emptyDataIsShowTable || !useSearchForm) { return true; } return !!unref(getDataSourceRef).length; }); function getcolumn(column: any) { // console.log(column); if (!column.hasOwnProperty('fixed') && column.hasOwnProperty('width') && (column.key != undefined || column.key != null)) { column.resizable = true; } return column; } function handleResizeColumn(w, col) { col.width = w; } function setProps(props: Partial<BasicTableProps>) { innerPropsRef.value = { ...unref(innerPropsRef), ...props }; } const tableAction: TableActionType = { reload, getSelectRows, setSelectedRows, clearSelectedRowKeys, getSelectRowKeys, deleteSelectRowByKey, setPagination, setTableData, updateTableDataRecord, deleteTableDataRecord, insertTableDataRecord, findTableDataRecord, redoHeight, setSelectedRowKeys, setColumns, setLoading, getDataSource, getRawDataSource, getFetchParams, setProps, getRowSelection, getPaginationRef: getPagination, getColumns, getCacheColumns, emit, updateTableData, setShowPagination, getShowPagination, setCacheColumnsByField, expandAll, expandRows, collapseAll, getIsExpanded, scrollTo, getSize: () => { return unref(getBindValues).size as SizeType; }, setCacheColumns, }; createTableContext({ ...tableAction, wrapRef, getBindValues }); expose(tableAction); emit('register', tableAction, formActions); onMounted(() => { addFakeData(); // 添加假数据 }); function getCellStyle(record, index) { return index % 2 === 0 ? 'ant-table-row-even' : 'ant-table-row-odd'; // 根据索引返回不同的类名 } function getFrom() { console.log(formActions.submit,useForm(),formRef) } return { getCellStyle, formRef, tableElRef, getBindValues, getLoading, registerForm, handleSearchInfoChange, getEmptyDataIsShowTable, handleTableChange, getRowClassName, wrapRef, tableAction, redoHeight, getFormProps: getFormProps as any, replaceFormSlotKey, getFormSlotKeys, getWrapperClass, columns: getViewColumns, useDebounceFn, getcolumn, handleResizeColumn, getFrom }; }, }); </script> <style lang="less"> .ant-table-tbody > tr.ant-table-row-even > td { background-color: #fafafa; } .ant-table-resize-handle { border-left: 1px solid #fafafa !important; // width: 1px !important; } .ant-table-tbody > tr.ant-table-row-odd > td { background-color: #fff; } @border-color: #cecece4d; @prefix-cls: ~'@{namespace}-basic-table'; [data-theme='dark'] { .ant-table-tbody > tr:hover.ant-table-row-selected > td, .ant-table-tbody > tr.ant-table-row-selected td { background-color: #262626; } } .@{prefix-cls} { max-width: 100%; height: 100%; &-row__striped { td { background-color: @app-content-background; } } &-form-container { .ant-form { width: 100%; padding: 10px 10px 0; margin-bottom: 10px; background-color: @component-background; } } .ant-table-cell { .ant-tag { margin-right: 0; } } .ant-table-wrapper { height: 100%; background-color: @component-background; border-radius: 2px; .ant-table-title { min-height: 40px; padding: 0 !important; } .ant-table.ant-table-bordered .ant-table-title { border: none !important; } } .ant-table { width: 100%; overflow-x: hidden; &-title { display: flex; border-bottom: none; justify-content: space-between; align-items: center; } } .ant-table-pagination.ant-pagination { margin: 10px 0 0; padding: 0 10px 10px; } .ant-table-footer { padding: 0; .ant-table-wrapper { padding: 0; } table { border: none !important; } .ant-table-body { overflow-x: hidden !important; } td { padding: 12px 8px; } } &--inset { .ant-table-wrapper { padding: 0; } } } </style> 获取formRef.value为null
最新发布
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值