代碼分析:
// 表格實例對象
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結合條件渲染。