需求
有一個表格展示了一些進度信息,進度信息可以修改,需要點擊進度信息旁邊的編輯按鈕時,把進度變為輸入框且自動聚焦,當鼠標失去焦點時自動請求更新接口。
注:本例以vue2 + element UI為例
分析
這個需求看著挺簡單的啊,不就是默認展示數字,點擊按鈕時,把數字變成輸入框嗎,再給個自動聚焦autofocus
,再監聽一下失去焦點事件,這不就完了嗎
示意圖如下:
于是,我興沖沖寫下了如下代碼
微解釋:默認顯示數字且非編輯狀態,點擊按鈕時,顯示輸入框
<el-table-column label="完成占比" prop="progress" align="center"><template slot-scope="scope"><div v-if="!scope.row.isEditing">{{ scope.row.progress }}%<el-button size="mini" type="text" @click="handleEditPercent(scope.$index, scope.row)"><i class="el-icon-edit-outline"></i></el-button></div><el-input-numberv-else:ref="'progress' + scope.$index"v-model="scope.row.progress":min="0":max="100"size="small":controls="false"style="width: 80px;"autofocus@blur="handleBlur(scope.$index, scope.row)"></el-input-number></template>
</el-table-column>
但是,你在點擊編輯按鈕時,雖然顯示了輸入框,但是無法自動聚焦,點擊后如下所示:
解決過程
看到沒自動聚焦,于是乎我又想到手動聚焦,文檔里有這方法,然后我又興沖沖地試了下:
但是這是el-table中的el-input,都是循環渲染的,單個ref變了和值不好處理,雖然也能做,但這種方法也失敗了。
后來分析了下,el-table
屬于動態渲染組件,在表格渲染時,el-input
可能還未完全掛載到 DOM 上,所以 autofocus
屬性不能正常發揮作用。
于是就轉換了下思路,我也不需要啥啥亂七八糟的東西了,我只希望這個el-input
出現時,我能通過這個dom節點的父節點查詢到input
,然后執行focus()
方法
于是,我又封裝了個指令,這下就不用管其他亂七八糟的東西了,只需要專注于本身:
directives: {focus: {inserted: function (el) {el.querySelector('input').focus()}}
},
然后在el-input
里加了v-focus
指令,這次再點擊編輯按鈕,終于亮了
原本以為是個小功能,沒想到坑這么多!