開發一個可自定義組件化門戶配置頁面,期間採用了vue框架做爲前端視圖引擎,做爲一個剛入手vue的萌新,開發第一個功能就遇到了攔路虎。須要一個拖動而且可改變大小的容器盒子。當時查看vue開發文檔,查找github都沒找到一個本身歡心的實現,因此與其求人,還不如求己。因此vuedragx這個輪子就有了,x
表明它不止可拖動。
github地址:github.com/464884492/v…javascript
因此有了以上思路,就須要一次掌握三個重要知識html
記住,無論使用什麼樣的框架,須要學習某種技能,須要學習api各類方法的用法,最好的途徑就是查看對應官方文檔前端
vue 開發自定義指令地址 cn.vuejs.org/v2/guide/cu…
通讀一篇,而後敲黑板畫重點vue
官方是麼說的 在 Vue2.0 中,代碼複用和抽象的主要形式是組件。然而,有的狀況下,你仍然須要對普通 DOM 元素進行底層操做,這時候就會用到自定義指令java
顯而易見,經過須要使用鼠標產生的位移,經過啥啥實在是比較爲難在下了node
針對vue指令,官方給開發這提供了幾個勾子函數,來注入開發者開發的功能,所謂的鉤子函數,我的理解也就是在正常的代碼中插入預埋的未實現的函數接口git
vue對開發着提供(bind、inserted、update、componentUpdated、unbind)注入點。github
每個鉤子都帶有參數 el、binding、vnode、oldVnodeexpress
{dragable:true,resizeable:true}
,不過vuedragx並無使用此方法傳值,統一經過binding.value傳值關於vue指令的鉤子函數,參數等相關說明,基本從官網引用過來的。我以爲有必要再次在強調如下,使用第三方的框架,最好途徑就是查閱官方文檔。其次能夠看看對應的源碼,若是有的話。api
上邊在vue指令介紹中,強調了查閱官方文檔的重要性,那麼針對javascript的api又該在那裏查閱呢?固然是 MDN,沒有第二
MDN中關於MouseEvent說明的地址: developer.mozilla.org/zh-CN/docs/…,開發vuedragx須要MouseEvent中最重要的兩個屬性MouseEvent.pageX
、MouseEvent.pageY
這個屬性將基於文檔的邊緣,考慮任何頁面的水平方向上的滾動。舉個例子,若是頁面向右滾動 200px 並出現了滾動條,這部分在窗口以外,而後鼠標點擊距離窗口左邊 100px 的位置,pageX 所返回的值將是 300。
作爲延伸,分別查看了MonuseEvent中其餘對應座標的屬性
因此,他們之間的關係應該是這樣的
用過jQuery的小夥伴,應該多少了解 trigger``triggerHandler
方法,觸發自定義事件,有了jq的幫助,自定義事件用的是那麼駕輕就熟,如絲版順滑。作爲對比,咱們先看看jq是如何使用自定義事件的
// 添加一個適當的事件監聽器$( '#foo').on( 'custom', function(event, param1, param2) {alert(param1 + "\n" + param2);});$( '#foo').trigger( 'custom', [ 'Custom', 'Event']);複製代碼
對,就是這麼簡單,定義,傳參一鼓作氣!
不過用Vue後,這些功能都要用原生的代碼實現,業界也愈來愈強調原生代碼呼聲也愈來愈高。或許這句是es標準逐步完善,瀏覽器逐步兼容新api帶來的利好。這裏應該向IE6致敬(逃)。
言歸正傳,標準接口是如何使用自定義事件的呢?因而有找到了MDN developer.mozilla.org/zh-CN/docs/…,找到了demo
// 添加一個適當的事件監聽器obj.addEventListener( "custom", function(e) {console.log( JSON.stringify(e.detail));})// 建立並分發事件var event = new CustomEvent( "custom", { "detail":{ "Custom": true}});obj.dispatchEvent(event)複製代碼
在我看來,定義事件的樣子,基本沒變,惟一參數傳遞變得複雜了。總有那麼一丟丟不美好。
鼠標在目標對象上下左邊邊緣移動時,鼠標須要顯示不一樣的resize樣式,提醒用戶當前可操做的類型。基本思路是獲取當前對象的在文檔對應的left和top值,與上邊講解的MouseEvent中的 pageX、pageY加上可容忍的邊沿值作比較,分別分如下幾種狀況
因此具體代碼是這樣的
判斷當前鼠標是否在拖動對象上就沒有那麼費勁了,直接在onmousemove事件中經過
e.target.classList.contains(cfg.dragBarClass)
判斷便可
經過計算獲得鼠標移動的deltx和delty值,分別更新width和heigth屬性。當前在向左和向上調整大小,還須要調整對一個的left和height屬性值
拖動,不改變目標對象大小,直接用計算的deltx和delty更新對應的left和top屬性便可,若是須要限制移動區域,須要計算父容器對應內邊距的座標
function setConstraint(data) {if (cfg.dragContainerId) {let constraintDom = document.querySelector( "#" + cfg.dragContainerId);let constraintRect = constraintDom.getBoundingClientRect();if (data.left <= 0) data.left = 0;if (data.top <= 0) data.top = 0;if (data.top + data.height+data.borderTop+data.borderBottom >= constraintRect.height) data.top = constraintRect.height - data.height-data.borderTop-data.borderBottom;if (data.left + data.width+data.borderLeft+data.borderRight > constraintRect.width) data.left = constraintRect.width - data.width-data.borderLeft-data.borderRight;}}複製代碼
雖然功能不大,但要把每個環節說清楚,感受仍是很費力。真羨慕那些會寫書的開發人員,文檔能力那是至關的好。寫文檔真的比不了寫代碼,不過仍是要寫,否則別人怎麼知道你代碼是作啥的。