插件体系

Omi是Web组件化框架,怎么又来了个插件的概念?

可以这么理解: Omi插件体系可以赋予dom元素一些能力,并且可以和组件的实例产生关联。

omi-drag

且看这个例子:

点击这里→在线试试

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是怎么实现的?

Omi.extendPlugin

核心方法: Omi.extendPlugin( pluginName, handler )

下面的代码就是展示了如何通过 Omi.extendPlugin 赋予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产生关联,我们接下来试试:

关联instance

我们想在组件里面能够监听到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);
...
  • 通过 var handlerName = dom.getAttribute('dragMove') 拿到dom上声明的dragMove
  • 通过 instancehandlerName 去执行对应的方法

点击这里→在线试试

更多插件

相关

  • Omi的Github地址https://github.com/AlloyTeam/omi
  • 如果想体验一下Omi框架,可以访问 Omi Playground
  • 如果想使用Omi框架或者开发完善Omi框架,可以访问 Omi使用文档
  • 如果你想获得更佳的阅读体验,可以访问 Docs Website
  • 如果你懒得搭建项目脚手架,可以试试 omi-cli
  • 如果你有Omi相关的问题可以 New issue
  • 如果想更加方便的交流关于Omi的一切可以加入QQ的Omi交流群(256426170)

Omi教程-插件体系的更多相关文章

  1. Geronimo tomcat: 在 Apache Geronimo 插件体系中将 Apache Tomcat 这个优秀的 Web 容器整合至其中

    Apache Geronimo 灵活的插件体系将 Tomcat, OpenJPA, OpenEJB, ActiveMQ 等第三方组件集成至其中.本文从多角度介绍了在 Apache Geronimo 中 ...

  2. Omi教程-组件

    组件 Omi框架完全基于组件体系设计,我们希望开发者可以像搭积木一样制作Web程序,一切皆是组件,组件也可以嵌套子组件形成新的组件,新的组件又可以当作子组件嵌套至任意组件形成新的组件... 简单组件 ...

  3. Omi框架Store体系的前世今生

    原文链接-https://github.com/AlloyTeam/omi Store 体系 先说说Store系统是干什么的!为什么要造这样一个东西?能够系统架构带来什么? 当我们组件之间,拥有共享的 ...

  4. ABP入门教程2 - 体系架构

    点这里进入ABP入门教程目录 介绍 应用程序代码库的分层是一种广泛接受的技术,可帮助降低复杂性并提高代码可重用性.为了实现分层体系结构,ASP.NET Boilerplate遵循域驱动设计的原理. D ...

  5. atitit.插件体系设计总结o73.doc

    1. 两大类型:微内核(级联树形结构)与巨内核(管理容器,并联结构). 1 2. 通用插件接口 1 3. 插件的绑定and 初始化 2 4. 微内核插件平台设计 2 5. 参考 2 1. 两大类型:微 ...

  6. Omi教程-组件通讯

    组件通讯 Omi框架组建间的通讯非常遍历灵活,因为有许多可选方案进行通讯: 通过在组件上声明 data-* 传递给子节点 通过在组件上声明 data 传递给子节点 父容器设置 childrenData ...

  7. Omi教程-使用group-data通讯

    写在前面 Omi框架组建间的通讯非常遍历灵活,上篇文章介绍了几种通讯方式,其中childrenData的方式可以批量传递数据给组件,但是有很多场景下data的来源不一定非要都从childrenData ...

  8. Omi教程-通讯通讯攻略大全

    组件通讯 Omi框架组建间的通讯非常遍历灵活,因为有许多可选方案进行通讯: 通过在组件上声明 data-* 传递给子节点 通过在组件上声明 data 传递给子节点 (支持复杂数据类型的映射) 父容器设 ...

  9. Omi教程-生命周期和事件处理

    生命周期 名称 含义 时机 constructor 构造函数 new的时候 install 初始化安装,这可以拿到用户传进的data进行处理 实例化 installed 安装完成,HTML已经插入页面 ...

随机推荐

  1. 实时 Django 终于来了 —— Django Channels 入门指南

    Reference: http://www.oschina.net/translate/in_deep_with_django_channels_the_future_of_real_time_app ...

  2. Ubuntu切换默认语言

    不得不说,从Ubuntu到Debian,又到CentOS 7,我胡汉三又回来了... 然后又装了个中文版的Ubuntu16.04LTS,不得不说,Ubuntu对中文的支持真的很好 不过,还是不太习惯, ...

  3. call的初步理解

    首先说下call的本质是一个函数 模Function.prototype.call = function(context){ // this表示某函数,函数里面的this先被替换成context,然后 ...

  4. margin的简单应用

    今晚学了盒模型的marg部分,简单仿下京东的官网首页部分 第一次制作,尽管看来实在惨不忍睹,毕竟娘不嫌儿丑,之后多加努力吧,这几天尽量加快学习进度,能单独制作一张精美的网页最好 附上代码 <!D ...

  5. Compilation err ororg.eclipse.jdt.internal.compiler.classfmt.ClassFormatException

    严重: Compilation errororg.eclipse.jdt.internal.compiler.classfmt.ClassFormatExceptionat org.eclipse.j ...

  6. Android测试点

    记录下之前项目测试中涉及到的Android测试点: 1.APP基本功能 按照back log整理测试用例,测试中发现有需求变动.或未考虑完全,及时更新测试用例. 测试用例包括:全功能点用例+重点功能快 ...

  7. iOS 之 绘图简介

    iOS 实现图形编程主要有三种技术:UIKit.Core Graphics.OpenGL. 绘图需要在图形环境中进行,图形环境分为三种:屏幕图形环境.off screen 位图环境和PDF图形环境.在 ...

  8. 2.1. 托管对象模型是什么(Core Data 应用程序实践指南)

    托管对象模型是一种数据结构.在这里,数据结构.纲要.对象图.数据模型.托管对象模型这些术语是一个意思.它们是对同一个东西不同场景的描述.比如,对Core Data 而言是托管对象模型,对设计器来说是对 ...

  9. 负载均衡 Lvs DR 模式笔记

    先来一张原理图,相当于ip-tun模式把tunl0的那块网卡配置在eth0:0的这个接口上,避免了兼容性的问题

  10. 如何用C语言封装 C++的类,在 C里面使用

    本文给出了一种方法.基本思想是,写一个 wrapper文件,把 C++类封装起来,对外只提供C语言的接口,和 C++i相关的都在  wrapper的实现文件里实现. 1. apple.h #ifnde ...