Skip to content

Commit

Permalink
feat: 抽象元素和实例关系管理功能, 防止同一个元素上多次调用同一个指令, 会生成多个anyTouch实例
Browse files Browse the repository at this point in the history
  • Loading branch information
any86 committed Apr 18, 2019
1 parent 1a79f92 commit 3bb62db
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 72 deletions.
46 changes: 46 additions & 0 deletions __tests__/vue/instanceManage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import InstanceManage from '../../src/vueDirective/InstanceManage';
class ABC {
a: number;

constructor() {
this.a = 1;
};

setA(v: number) {
this.a = v;
}

getA() {
return this.a;
}
};


const el = document.createElement('div');
const im = new InstanceManage(ABC);

test('getInstanceByIndex', () => {
im.getOrCreateInstanceByEl(el);
const instance = im.getInstanceByIndex(0);
expect(instance).toBeDefined();
expect(instance instanceof ABC).toBeTruthy();
});

test('removeInstanceByIndex', () => {
im.removeInstanceByIndex(0);
expect(im.stock.length).toBe(0);
});

test('getIndexByEl, 如果元素存在返回索引, 不存在返回-1', () => {
const index = im.getIndexByEl(el);
expect(index).toBe(-1);

// 新建
im.getOrCreateInstanceByEl(el);
expect(im.getIndexByEl(el)).toBe(0);
expect(im.stock.length).toBe(1);

// get
im.getOrCreateInstanceByEl(el);
expect(im.stock.length).toBe(1);
});
2 changes: 1 addition & 1 deletion example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ new Vue({
// atBox.on('panmove', ev => {
// console.log('atBox');
// })
console.log(AnyTouch.vTouch);
// console.log(AnyTouch.vTouch);


this.$refs.circle.addEventListener('animationend', e=>{
Expand Down
2 changes: 1 addition & 1 deletion src/AnyTouch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface Options {
isPreventDefault?: boolean;
style?: { [key: string]: string };
};
export default class {
export class AnyTouch{
// 识别器
static Tap = Tap;
static Press = Press;
Expand Down
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import AnyTouch from './AnyTouch';
import {AnyTouch} from './AnyTouch';
import VueDirective from './vueDirective';
export default class extends AnyTouch {
// vue指令版
Expand Down
53 changes: 23 additions & 30 deletions src/vueDirective/InstanceManage.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,60 @@
import AnyTouch from '../AnyTouch';
interface Manage { el: HTMLElement, instance: AnyTouch };
/**
* 管理实例和元素的映射关系
* 一个元素只能对应一个实例
*/
export default class {
manages: Manage[] = [];
export default class <T extends { new(...arys: any): any }> {
// 存储映射关系
stock: { el: HTMLElement, instance: InstanceType<T> }[] = [];
ClassObject: T;

constructor() {
this.manages = [];
constructor(ClassObject: T) {
this.stock = [];
this.ClassObject = ClassObject;
};

/**
* 获取元素在_manages中的索引
* 获取元素在stock中的索引
* @param {Element} 元素
* @returns {Number} 元素索引
*/
getManageIndex(el: HTMLElement): number {
for (let i = 0, len = this.manages.length; i < len; i++) {
if (el === this.manages[i].el) {
getIndexByEl(el: HTMLElement): number {
for (let i = 0, len = this.stock.length; i < len; i++) {
if (el === this.stock[i].el) {
return i;
}
}
return -1;
};

/**
* 存储实例
* @param {AnyTouch} 实例
* @return {Number} 添加后的索引
*/
addToManage(el: HTMLElement, instance: AnyTouch): number {
return this.manages.push({ el, instance })
};

/**
* 获取实例
* @param {Number} 索引
* @return {AnyTouch} 实例
* @return {InstanceType<T>} 实例
*/
getInstanceByIndex(index: number): AnyTouch {
return (this.manages[index] || {}).instance;
getInstanceByIndex(index: number): InstanceType<T> {
return this.stock[index]!.instance;
};

/**
* 删除指定实例
* @param {Number} 索引
*/
removeInstanceByIndex(index: number):void{
this.manages.splice(index, 1);
removeInstanceByIndex(index: number): void {
this.stock.splice(index, 1);
};

/**
* 获取实例, 如果没有新建
* @param {Element} 目标元素
* @param {AnyTouch} AnyTouch实例
* @param {InstanceType<T>} InstanceType<T>实例
*/
getOrCreateInstanceByEl (el: HTMLElement):AnyTouch {
const manageIndex = this.getManageIndex(el);
// 防止同一个元素上同一个指令实例化多个AnyTouch
getOrCreateInstanceByEl(el: HTMLElement): InstanceType<T> {
const manageIndex = this.getIndexByEl(el);
// 防止同一个元素上同一个指令实例化多个InstanceType<T>
if (-1 === manageIndex) {
// 新建实例
const instance = new AnyTouch(el);
this.addToManage(el, instance);
const instance = new this.ClassObject(el);
this.stock.push({el, instance});
return instance;
} else {
return this.getInstanceByIndex(manageIndex);
Expand Down
31 changes: 0 additions & 31 deletions src/vueDirective/const/events.ts

This file was deleted.

18 changes: 10 additions & 8 deletions src/vueDirective/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,27 @@
import { Computed } from '../interface';
import { VueConstructor } from 'Vue/types/vue';
import InstanceManage from './InstanceManage';
import { AnyTouch } from '../AnyTouch';

// 管理实例和元素的映射关系
const iManage = new InstanceManage();
const iManage = new InstanceManage(AnyTouch);
// 导出指令
const plugin = {
install(Vue: VueConstructor) {
const _bindEvent = (el: HTMLElement, binding: any) => {
let instance = iManage.getOrCreateInstanceByEl(el);

// 匹配AnyTouch设置
if ('config' === binding.arg) {
instance.set(binding.value);
}

// 匹配手势, 无"-""
else if (/^((?!-).)*$/.test(binding.arg)) {
console.log(binding.modifiers);
// console.log(binding.modifiers);
// 绑定事件
instance.on(binding.arg, (ev: Computed) => {
if (!!binding.modifiers.preventDefault) {
if(binding.modifiers.prevent) {
if (binding.modifiers.prevent) {
ev.preventDefault();
}
}
Expand All @@ -46,11 +48,11 @@ const plugin = {
* @param {Element} 关联元素
*/
const _unbindEvent = (el: HTMLElement) => {
const manageIndex = iManage.getManageIndex(el);
const index = iManage.getIndexByEl(el);
// 防止一个元素上的多个手势指令会重复触发删除
if (-1 !== manageIndex && undefined !== iManage.manages[manageIndex]) {
iManage.getInstanceByIndex(manageIndex).destroy();
iManage.removeInstanceByIndex(manageIndex);
if (-1 !== index && undefined !== iManage.getInstanceByIndex(index)) {
iManage.getInstanceByIndex(index).destroy();
iManage.removeInstanceByIndex(index);
}
};

Expand Down

0 comments on commit 3bb62db

Please sign in to comment.