Vue3 + TypeScript + Element Plus 表格实例null检查方法
代码分析:
// 表格实例对象
const tableRef = ref<ElTableExtendedInstance | null>(null);
// 表格列配置列表
const columnConfigs = ref<IColumnConfig[]>([{ prop: "index", label: "序号", width: 60 },{ prop: "batchNo", label: "批号", width: 120 },{ prop: "validityDate", label: "有效期至", width: 110 },{ prop: "amount", label: "库存数量", width: 80 }
]);
const tableColumnWidth = useTableColumnWidth(tableRef.value, columnConfigs.value);
在 Vue 3 中,要确保 tableRef.value
不为 null 时再调用 useTableColumnWidth
,可以通过以下几种方式实现:
方法 1:使用 onMounted
+ 条件判断(推荐)
typescript
复制
下载
import { ref, onMounted } from 'vue'// 表格实例对象 const tableRef = ref<ElTableExtendedInstance | null>(null); // 表格列配置列表 const columnConfigs = ref<IColumnConfig[]>([...]);// 声明响应式变量 const tableColumnWidth = ref<any>(null);onMounted(() => {// 确保 DOM 已挂载if (tableRef.value) {tableColumnWidth.value = useTableColumnWidth(tableRef.value, columnConfigs.value);} else {console.error("表格实例未挂载!");} });
方法 2:使用 watch
监听引用变化
typescript
复制
下载
import { ref, watch } from 'vue'const tableRef = ref<ElTableExtendedInstance | null>(null); const columnConfigs = ref<IColumnConfig[]>([...]); const tableColumnWidth = ref<any>(null);// 监听 tableRef 变化 watch(tableRef, (newVal) => {if (newVal) {tableColumnWidth.value = useTableColumnWidth(newVal, columnConfigs.value);} }, { immediate: true }); // immediate: true 确保初始值被检查
方法 3:使用计算属性 + 防御性检查
typescript
复制
下载
import { ref, computed } from 'vue'const tableRef = ref<ElTableExtendedInstance | null>(null); const columnConfigs = ref<IColumnConfig[]>([...]);// 计算属性自动处理 null 情况 const tableColumnWidth = computed(() => {return tableRef.value ? useTableColumnWidth(tableRef.value, columnConfigs.value): null; // 或返回默认值 });
方法 4:在模板中使用 v-if 延迟渲染(结合方法1)
vue
复制
下载
<template><!-- 确保表格存在时才渲染依赖组件 --><el-table v-if="dataLoaded" ref="tableRef"></el-table><dependent-component v-else>加载中...</dependent-component> </template><script setup> import { ref, onMounted } from 'vue'const dataLoaded = ref(false); const tableRef = ref(null);// 先获取数据再设置表格引用 fetchData().then(() => {dataLoaded.value = true;onMounted(() => {if (tableRef.value) {useTableColumnWidth(tableRef.value, columnConfigs.value);}}); }); </script>
最佳实践建议:
-
组合式函数优化:修改
useTableColumnWidth
使其内部处理 null 情况
typescript
复制
下载
// 修改后的组合式函数 export function useTableColumnWidth(table: Ref<ElTableExtendedInstance | null>,columns: Ref<IColumnConfig[]> ) {watchEffect(() => {if (table.value) {// 实际处理逻辑console.log('处理列宽', columns.value);}}); }// 使用方式 useTableColumnWidth(tableRef, columnConfigs); // 无需 .value
-
可选链操作符(Optional Chaining):
typescript
复制
下载
// 调用时安全访问 tableRef.value?.doSomething();
错误处理建议:
typescript
复制
下载
// 在可能出错的地方添加类型守卫 if (!tableRef.value) {throw new Error("表格实例未初始化!"); }// 或使用断言函数 function assertTableInitialized(table: unknown): asserts table is ElTableExtendedInstance {if (!table) throw new Error("表格实例未初始化!"); }// 使用 assertTableInitialized(tableRef.value); useTableColumnWidth(tableRef.value, columnConfigs.value);
核心原则:
-
在组件挂载完成(
onMounted
)后再访问 DOM 引用 -
使用响应式 API(
watch
,computed
)处理引用变化 -
通过防御性编程(null 检查)避免运行时错误
-
修改工具函数使其支持响应式处理
注意:如果表格在
v-if
中,需要确保条件为真时引用才有效,此时推荐使用方法4结合条件渲染。