Omi是Web組件化框架,怎麼又來了個插件的概念?html
能夠這麼理解: Omi插件體系能夠賦予dom元素一些能力,而且能夠和組件的實例產生關聯。jquery
且看這個例子:git
點擊這裏→在線試試github
import OmiDrag from './omi-drag.js'; OmiDrag.init(); class App extends Omi.Component { constructor(data) { super(data); } render() { return ` <div> <div omi-drag class="test">Drag Me</div> </div> `; } style(){ return ` <style> .test{ width:100px; height:100px; color:white; line-height:90px; text-align:center; background-color:#00BFF3; } </style> ` } } Omi.render(new App(),"#container");
如上面的代碼所示,經過在div上標記omi-drag,這個div就可以被用戶使用鼠標拖拽。咱們稱omi-drag.js爲omi插件。
是否是很是方便?那麼這個omi-drag是怎麼實現的?web
核心方法: Omi.extendPlugin( pluginName, handler )框架
下面的代碼就是展現瞭如何經過 Omi.extendPlugin 賦予dom拖拽的能力:dom
;(function () { var OmiDrag = {}; var Omi = typeof require === 'function' ? require('omi') : window.Omi; OmiDrag.init = function(){ Omi.extendPlugin('omi-drag',function(dom, instance){ dom.style.cursor='move'; var isMouseDown = false, preX = null, preY = null, currentX = null, currentY = null, translateX = 0, translateY = 0; dom.addEventListener('mousedown',function(evt){ isMouseDown = true; preX = evt.pageX; preY = evt.pageY; evt.stopPropagation(); },false); window.addEventListener('mousemove',function(evt){ if(isMouseDown){ currentX = evt.pageX; currentY = evt.pageY; if(preX != null){ translateX += currentX - preX; translateY += currentY - preY; dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)'; } preX = currentX; preY = currentY; evt.preventDefault(); } },false); window.addEventListener('mouseup',function(){ isMouseDown = false; preX = preY = currentX = currentY = null; },false); }); } OmiDrag.destroy = function(){ delete Omi.plugins['omi-drag']; }; if (typeof exports == "object") { module.exports = OmiDrag; } else if (typeof define == "function" && define.amd) { define([], function(){ return OmiDrag }); } else { window.OmiDrag = OmiDrag; } })();
方法: Omi.extendPlugin( pluginName, handler )函數
其中pluginName爲插件的名稱
其中handler爲處理器。handler能夠拿到標記了pluginName的dom以及dom所在的組件的實例,即 dom 和 instance。組件化
經過 Omi.extendPlugin,能夠賦予dom元素一些能力,也能夠和組件的實例(instance)產生關聯。
可是上面的例子沒有和instance產生關聯,咱們接下來試試:ui
咱們想在組件裏面可以監聽到move而且執行回調。以下:
... ... moveHandler(){ console.log('moving'); } render() { return ` <div> <div omi-drag class="test">Drag Me</div> </div> `; } ...
主要被拖動過程當中,moveHandler就不斷地被執行。插件代碼須要修改:
... window.addEventListener('mousemove',function(evt){ if(isMouseDown){ currentX = evt.pageX; currentY = evt.pageY; if(preX != null){ translateX += currentX - preX; translateY += currentY - preY; dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)'; } preX = currentX; preY = currentY; evt.preventDefault(); instance.moveHandler(evt); } },false);
咱們在裏面增長了instance.moveHandler(evt);方法,用來執行組件實例上的moveHandler方法。
這樣的話:就是組件的實例(instance)產生關聯。可是仍是有問題?若是標記了多個omi-drag 就會有問題!如:
... render() { return ` <div> <div omi-drag class="test">Drag Me</div> <div omi-drag class="test">Drag Me</div> </div> `; } ...
一般咱們系統每一個omi-drag都能對應一個回調函數,如:
... ... moveHandlerA(){ console.log('moving'); } moveHandlerB(){ console.log('moving'); } render() { return ` <div> <div omi-drag class="test">Drag Me A</div> <div omi-drag class="test">Drag Me B</div> </div> `; } ...
怎麼辦?怎麼實現?有辦法!經過dom傳遞數據給插件。
先來看最後實現的效果:
... ... moveHandlerA(){ console.log('moving'); } moveHandlerB(){ console.log('moving'); } render() { return ` <div> <div omi-drag class="test" dragMove="moveHandlerA" >Drag Me A</div> <div omi-drag class="test" dragMove="moveHandlerB" >Drag Me B</div> </div> `; } ...
omi-drag修改的地方:
... var handlerName = dom.getAttribute('dragMove'); window.addEventListener('mousemove',function(evt){ if(isMouseDown){ currentX = evt.pageX; currentY = evt.pageY; if(preX != null){ translateX += currentX - preX; translateY += currentY - preY; dom.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px)'; } preX = currentX; preY = currentY; evt.preventDefault(); instance[handlerName](evt); } },false); ...