[improvement] mixins typescript (#3690)
This commit is contained in:
@@ -3,15 +3,19 @@
|
||||
*/
|
||||
import { on, off } from '../utils/dom/event';
|
||||
|
||||
export function BindEventMixin(handler) {
|
||||
function bind() {
|
||||
type BindEventMixinThis = {
|
||||
binded: boolean;
|
||||
};
|
||||
|
||||
export function BindEventMixin(handler: Function) {
|
||||
function bind(this: BindEventMixinThis) {
|
||||
if (!this.binded) {
|
||||
handler.call(this, on, true);
|
||||
this.binded = true;
|
||||
}
|
||||
}
|
||||
|
||||
function unbind() {
|
||||
function unbind(this: BindEventMixinThis) {
|
||||
if (this.binded) {
|
||||
handler.call(this, off, false);
|
||||
this.binded = false;
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Listen to click outside event
|
||||
*/
|
||||
import { on, off } from '../utils/dom/event';
|
||||
|
||||
export const ClickOutsideMixin = config => ({
|
||||
mounted() {
|
||||
this.clickOutsideHandler = event => {
|
||||
if (!this.$el.contains(event.target)) {
|
||||
this[config.method]();
|
||||
}
|
||||
};
|
||||
|
||||
on(document, config.event, this.clickOutsideHandler);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
off(document, config.event, this.clickOutsideHandler);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Listen to click outside event
|
||||
*/
|
||||
import Vue from 'vue';
|
||||
import { on, off } from '../utils/dom/event';
|
||||
|
||||
export type ClickOutsideMixinConfig = {
|
||||
event: string;
|
||||
method: string;
|
||||
};
|
||||
|
||||
export const ClickOutsideMixin = (config: ClickOutsideMixinConfig) =>
|
||||
Vue.extend({
|
||||
data() {
|
||||
const clickOutsideHandler = (event: Event) => {
|
||||
if (!this.$el.contains(event.target as Node)) {
|
||||
(this as any)[config.method]();
|
||||
}
|
||||
};
|
||||
|
||||
return { clickOutsideHandler };
|
||||
},
|
||||
|
||||
mounted() {
|
||||
on(document, config.event, this.clickOutsideHandler);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
off(document, config.event, this.clickOutsideHandler);
|
||||
}
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
export type GetContainer = (container: HTMLElement) => void;
|
||||
export type GetContainer = () => HTMLElement;
|
||||
|
||||
export type PopupMixinProps = {
|
||||
value: boolean;
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
function getElement(selector) {
|
||||
import Vue, { PropType } from 'vue';
|
||||
import { GetContainer } from './popup/type';
|
||||
|
||||
type PortalMixinOptions = {
|
||||
afterPortal?: () => void;
|
||||
};
|
||||
|
||||
function getElement(selector: string | GetContainer): Element | null {
|
||||
if (typeof selector === 'string') {
|
||||
return document.querySelector(selector);
|
||||
}
|
||||
@@ -6,10 +13,10 @@ function getElement(selector) {
|
||||
return selector();
|
||||
}
|
||||
|
||||
export function PortalMixin({ afterPortal }) {
|
||||
return {
|
||||
export function PortalMixin({ afterPortal }: PortalMixinOptions) {
|
||||
return Vue.extend({
|
||||
props: {
|
||||
getContainer: [String, Function]
|
||||
getContainer: [String, Function] as (PropType<string | GetContainer>)
|
||||
},
|
||||
|
||||
watch: {
|
||||
@@ -44,5 +51,5 @@ export function PortalMixin({ afterPortal }) {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
export function ChildrenMixin(parent, options = {}) {
|
||||
import Vue from 'vue';
|
||||
|
||||
type ChildrenMixinOptions = {
|
||||
indexKey?: any;
|
||||
};
|
||||
|
||||
export function ChildrenMixin(parent: string, options: ChildrenMixinOptions = {}) {
|
||||
const indexKey = options.indexKey || 'index';
|
||||
|
||||
return {
|
||||
return Vue.extend({
|
||||
inject: {
|
||||
[parent]: {
|
||||
default: null
|
||||
@@ -10,7 +16,7 @@ export function ChildrenMixin(parent, options = {}) {
|
||||
|
||||
computed: {
|
||||
parent() {
|
||||
return this[parent];
|
||||
return (this as any)[parent];
|
||||
},
|
||||
|
||||
[indexKey]() {
|
||||
@@ -25,7 +31,7 @@ export function ChildrenMixin(parent, options = {}) {
|
||||
|
||||
beforeDestroy() {
|
||||
if (this.parent) {
|
||||
this.parent.children = this.parent.children.filter(item => item !== this);
|
||||
this.parent.children = this.parent.children.filter((item: any) => item !== this);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -48,10 +54,10 @@ export function ChildrenMixin(parent, options = {}) {
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function ParentMixin(parent) {
|
||||
export function ParentMixin(parent: string) {
|
||||
return {
|
||||
provide() {
|
||||
return {
|
||||
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* Use scopedSlots in Vue 2.6+
|
||||
* downgrade to slots in lower version
|
||||
*/
|
||||
|
||||
export const SlotsMixin = {
|
||||
methods: {
|
||||
slots(name = 'default', props) {
|
||||
const { $slots, $scopedSlots } = this;
|
||||
if ($scopedSlots[name]) {
|
||||
return $scopedSlots[name](props);
|
||||
}
|
||||
return $slots[name];
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Use scopedSlots in Vue 2.6+
|
||||
* downgrade to slots in lower version
|
||||
*/
|
||||
import Vue from 'vue';
|
||||
|
||||
export const SlotsMixin = Vue.extend({
|
||||
methods: {
|
||||
slots(name = 'default', props: any) {
|
||||
const { $slots, $scopedSlots } = this;
|
||||
const scopedSlot = $scopedSlots[name];
|
||||
|
||||
if (scopedSlot) {
|
||||
return scopedSlot(props);
|
||||
}
|
||||
|
||||
return $slots[name];
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,29 +1,42 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
const MIN_DISTANCE = 10;
|
||||
function getDirection(x, y) {
|
||||
|
||||
function getDirection(x: number, y: number) {
|
||||
if (x > y && x > MIN_DISTANCE) {
|
||||
return 'horizontal';
|
||||
}
|
||||
|
||||
if (y > x && y > MIN_DISTANCE) {
|
||||
return 'vertical';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export const TouchMixin = {
|
||||
type TouchMixinData = {
|
||||
startX: number;
|
||||
startY: number;
|
||||
deltaX: number;
|
||||
deltaY: number;
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
direction: string;
|
||||
};
|
||||
|
||||
export const TouchMixin = Vue.extend({
|
||||
data() {
|
||||
return {
|
||||
direction: ''
|
||||
};
|
||||
return { direction: '' } as TouchMixinData;
|
||||
},
|
||||
|
||||
methods: {
|
||||
touchStart(event) {
|
||||
touchStart(event: TouchEvent) {
|
||||
this.resetTouchStatus();
|
||||
this.startX = event.touches[0].clientX;
|
||||
this.startY = event.touches[0].clientY;
|
||||
},
|
||||
|
||||
touchMove(event) {
|
||||
touchMove(event: TouchEvent) {
|
||||
const touch = event.touches[0];
|
||||
this.deltaX = touch.clientX - this.startX;
|
||||
this.deltaY = touch.clientY - this.startY;
|
||||
@@ -40,4 +53,4 @@ export const TouchMixin = {
|
||||
this.offsetY = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user