ivew通過render渲染函數動態生成的Input輸入框實現雙向綁定


問題:iview中表格組件通過render函數動態生成Input組件輸入框插入表格中,具體UI樣式如圖,動態生成的Input輸入框組件無法綁定v-model,這個時候我們需要實現雙線綁定的功能。

解決:render函數生成Input框並且實現雙向綁定的寫法。

//這里只展示核心代碼片段
render: (h, params)=>{
      return h('Input', {
		   props:{
		       value:params.row.curSum,
		       autosize: true
		   }                    	
		   on: {
		         'on-blur': (event) => {
		             this.dataList.curSum=event.target.value;
		         }
		    }
	})
}

vue中有對render渲染函數的詳細說明,這里不再描述,如果不慎了解可以閱讀vue官方文檔中的渲染函數章節:https://cn.vuejs.org/v2/guide/render-function.html。首先渲染Input組件時需要給value屬性賦值,這個作用是父組件的value值改變,能夠傳遞到子組件Input中。同時Input子組件中通過觸發父組件的自定義函數on-blur將值傳遞給父組件(在ivew中Input子組件源碼中通過this.$emit('on-blur', event)將值傳入父組件),在父組件中觸發on-blur事件后將值綁定在data對象上,這樣就實現了雙向綁定。

問題二:如上實現了雙向綁定,但是引來了一個新的問題,當我們在一個輸入框中輸完值,點擊第二個輸入框進行輸入時會觸發前一個輸入框的blur事件,之前我們為了實現雙向綁定,會在輸入框失焦時給data對象賦值,這個時候會引發整個一行輸入框dom的重新繪制,從而使當前聚焦的input失焦,這個時候用戶必須再點一次才能聚焦,這樣非常影響用戶體驗。

解決方法:對於這個問題也進行了一段時間的探索,第一思路是官方有沒有解決方案?,可惜查了很多資料也沒有好的解決方案。第二思路想通過修改ivew的組件源碼來解決這個問題,但是這樣會導致之后iview UI庫的版本管理會非常麻煩,可行性非常低。想了很久想到了第三種解決方案,通過hacker方法,能不能在用戶點擊Input輸入框聚焦后,當數據綁定完成以及dom渲染完成以后在手動進行一次聚焦,也就是自動聚焦以后再手動觸發一次聚焦。我們對上面的代碼進行改進:

render: (h, params)=>{
      return h('Input', {
		   props:{
		       value:params.row.curSum,
		       autosize: true
		   },
                   attrs: {
                       id: rwmc+'params.index'//保證每個輸入框的id唯一
                   },                    	
		   on: {
                         'on-focus': () => {
                               this.$nextTick(()=>{	                      
                                     document.getElementById('rwmc'+params.index).
                                     childNodes.forEach(item=>{
		                         if(item.tagName == 'INPUT'){
		                             item.focus();
		                         }
		                     })
		               })                        
                          },
		         'on-blur': (event) => {
		             this.dataList.curSum=event.target.value;
		         }
		    }
	})
}

這里,我們在之前的render函數中加了on-focus自定義事件。我們給每個Input定義一個id屬性(注意保持id的唯一性)。當input觸發父組件的on-focus事件時,我們在事件回調函數中調用vue的this.$nextTick方法,(這個方法是vue提供的一個api,它的作用是等dom渲染完成之后才執行的方法,具體$nextTick的作用可以參考vue官方文檔https://cn.vuejs.org/v2/api/#Vue-nextTick ),由於前一個input框blur事件重新賦值后引起一整行dom重繪,在這里調用該方法是就是為了等到表格的dom都重新渲染完成后才觸發之后的處理邏輯,在nextTick的回調函數中我們通過之前定義的id找到該dom下的input並手動聚焦。這樣就完美的解決的之前數據框點擊兩次才聚焦的問題。

總結:個人用vue時間不長,但是感覺到vue非常的強大。vue官網定義vue是一套用於構建用戶界面的漸進式框架。對於初學的前端和后端同學只需要了解基本的前端知識就可以快速的利用vue開發簡單的前端應用,但是對於復雜的應用vue提供了豐富的api可成熟的解決方案,可以完美的應對復雜的應用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM