Vue2.0 中,代碼復用和抽象的主要形式是組件。然而,有的情況下,你仍然需要對普通 DOM 元素進行底層操作,這時候就會用到自定義指令。舉個聚焦輸入框的例子,如下:

在網上查找了很多方法,
但是在實際使用中發現了一個問題
無論是使用$ref獲取input元素然后使用focus方法:
if (column.property == "remark") { this.$nextTick(() => { this.$refs.remarkRef.focus(); // 視圖出現后使input獲取焦點 }); } else { this.$nextTick(() => { this.$refs.hitchRef.focus(); // 視圖出現后使input獲取焦點 }); }
還是使用餓了么組件自帶的autoFocus
都只有在第一次點擊按鈕的時候可以讓Input獲得焦點,在不刷新頁面的情況下,第二次以后的按鈕點擊都不會讓Input獲得焦點。猜測了一下是存才一個全局變量,當我們第一次使Input獲得焦點以后改變了這個預設變量的值,在Input失去焦點的時候並沒有將這個值重置,所以導致了后面的問題。
事實上,只要你在打開這個頁面后還沒點擊過任何內容,這個輸入框就應當還是處於聚焦狀態。現在讓我們用指令來實現這個功能:
在main.js中
// 注冊一個全局自定義指令 `v-focus` Vue.directive('focus', { // 當被綁定的元素插入到 DOM 中時…… inserted: function (el) { // 聚焦元素 el.focus() el.querySelector('input').focus() } })
如果想注冊局部指令,組件中也接受一個 directives 的選項:
directives: { // 注冊一個局部的自定義指令 v-focus focus: { // 指令的定義 inserted: function (el) { // 聚焦元素 el.querySelector("input").focus(); }, }, },
注意:directives是vue中的自定義指令,個人理解成自定義的鈎子函數。
然后你可以在模板中任何元素上使用新的 v-focus property,如下
<input v-focus>
具體代碼
<el-table-column label="調整值" width="300" align="center"> <template slot-scope="scope"> <el-input ref="inputRef" v-if="scope.row.isEditCell" v-model.number="scope.row.amount2" class="el-input" v-focus @blur="cellBlur(scope.row, scope.column)" /> <span v-else>{{ scope.row.amount2 }}</span> <el-button style="margin-left: 5px" v-if="scope.row.isEditCell" type="success" icon="el-icon-check" size="small" circle @click="submitName(scope.row)" ></el-button> <el-button v-show="scope.row.isEditCell" class="cancel-btn" size="mini" icon="el-icon-refresh" type="warning" @click.native.prevent="handleCancel(scope.row)" > cancel </el-button> </template> </el-table-column>
這樣使我們在組件中可以自用的調用v-focus方法,給他綁定定義布爾變量來控制元素是否獲得焦點
但是這里要注意的是組件<el-input>本身在頁面中渲染成了一個div元素
所以我們要在<el-input>被綁定為v-focus的同時
在自定義指令中獲取組件下通過querySelector()方法獲取input元素
