chore: merge src and src-next
This commit is contained in:
@@ -1,86 +1,18 @@
|
||||
/**
|
||||
* Create a basic component with common options
|
||||
*/
|
||||
import '../../locale';
|
||||
import { isFunction } from '..';
|
||||
import { camelize } from '../format/string';
|
||||
import { SlotsMixin } from '../../mixins/slots';
|
||||
import Vue, {
|
||||
VNode,
|
||||
VueConstructor,
|
||||
ComponentOptions,
|
||||
RenderContext,
|
||||
} from 'vue';
|
||||
import { DefaultProps, FunctionComponent } from '../types';
|
||||
|
||||
export interface VantComponentOptions extends ComponentOptions<Vue> {
|
||||
functional?: boolean;
|
||||
install?: (Vue: VueConstructor) => void;
|
||||
}
|
||||
|
||||
export type TsxBaseProps<Slots> = {
|
||||
key: string | number;
|
||||
// hack for jsx prop spread
|
||||
props: any;
|
||||
class: any;
|
||||
style: string | object[] | object;
|
||||
scopedSlots: Slots;
|
||||
};
|
||||
|
||||
export type TsxComponent<Props, Events, Slots> = (
|
||||
props: Partial<Props & Events & TsxBaseProps<Slots>>
|
||||
) => VNode;
|
||||
|
||||
function install(this: ComponentOptions<Vue>, Vue: VueConstructor) {
|
||||
const { name } = this;
|
||||
Vue.component(name as string, this);
|
||||
Vue.component(camelize(`-${name}`), this);
|
||||
}
|
||||
|
||||
// unify slots & scopedSlots
|
||||
export function unifySlots(context: RenderContext) {
|
||||
// use data.scopedSlots in lower Vue version
|
||||
const scopedSlots = context.scopedSlots || context.data.scopedSlots || {};
|
||||
const slots = context.slots();
|
||||
|
||||
Object.keys(slots).forEach((key) => {
|
||||
if (!scopedSlots[key]) {
|
||||
scopedSlots[key] = () => slots[key];
|
||||
}
|
||||
});
|
||||
|
||||
return scopedSlots;
|
||||
}
|
||||
|
||||
// should be removed after Vue 3
|
||||
function transformFunctionComponent(
|
||||
pure: FunctionComponent
|
||||
): VantComponentOptions {
|
||||
return {
|
||||
functional: true,
|
||||
props: pure.props,
|
||||
model: pure.model,
|
||||
render: (h, context): any =>
|
||||
pure(h, context.props, unifySlots(context), context),
|
||||
};
|
||||
}
|
||||
// function install(this: any, Vue: VueConstructor) {
|
||||
// const { name } = this;
|
||||
// Vue.component(name as string, this);
|
||||
// Vue.component(camelize(`-${name}`), this);
|
||||
// }
|
||||
|
||||
export function createComponent(name: string) {
|
||||
return function <Props = DefaultProps, Events = {}, Slots = {}>(
|
||||
sfc: VantComponentOptions | FunctionComponent
|
||||
): TsxComponent<Props, Events, Slots> {
|
||||
if (isFunction(sfc)) {
|
||||
sfc = transformFunctionComponent(sfc);
|
||||
}
|
||||
|
||||
if (!sfc.functional) {
|
||||
sfc.mixins = sfc.mixins || [];
|
||||
sfc.mixins.push(SlotsMixin);
|
||||
}
|
||||
|
||||
return function (sfc: any) {
|
||||
sfc.name = name;
|
||||
sfc.install = install;
|
||||
// sfc.install = install;
|
||||
|
||||
return sfc as TsxComponent<Props, Events, Slots>;
|
||||
return sfc;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,5 +10,9 @@ type CreateNamespaceReturn = [
|
||||
|
||||
export function createNamespace(name: string): CreateNamespaceReturn {
|
||||
name = 'van-' + name;
|
||||
return [createComponent(name), createBEM(name), createI18N(name)];
|
||||
return [
|
||||
createComponent(name),
|
||||
createBEM(name),
|
||||
createI18N(name)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { isServer } from '..';
|
||||
import { inBrowser } from '..';
|
||||
import { EventHandler } from '../types';
|
||||
|
||||
// eslint-disable-next-line import/no-mutable-exports
|
||||
export let supportsPassive = false;
|
||||
|
||||
if (!isServer) {
|
||||
if (inBrowser) {
|
||||
try {
|
||||
const opts = {};
|
||||
Object.defineProperty(opts, 'passive', {
|
||||
@@ -25,7 +25,7 @@ export function on(
|
||||
handler: EventHandler,
|
||||
passive = false
|
||||
) {
|
||||
if (!isServer) {
|
||||
if (inBrowser) {
|
||||
target.addEventListener(
|
||||
event,
|
||||
handler,
|
||||
@@ -35,7 +35,7 @@ export function on(
|
||||
}
|
||||
|
||||
export function off(target: EventTarget, event: string, handler: EventHandler) {
|
||||
if (!isServer) {
|
||||
if (inBrowser) {
|
||||
target.removeEventListener(event, handler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* requestAnimationFrame polyfill
|
||||
*/
|
||||
|
||||
import { isServer } from '..';
|
||||
import { inBrowser } from '..';
|
||||
|
||||
let prev = Date.now();
|
||||
|
||||
@@ -16,7 +16,7 @@ function fallback(fn: FrameRequestCallback): number {
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
const root = (isServer ? global : window) as Window;
|
||||
const root = (inBrowser ? window : global) as Window;
|
||||
|
||||
/* istanbul ignore next */
|
||||
const iRaf = root.requestAnimationFrame || fallback;
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
import Vue, { RenderContext, VNodeData } from 'vue';
|
||||
import { ObjectIndex } from './types';
|
||||
|
||||
type Context = RenderContext & { data: VNodeData & ObjectIndex };
|
||||
|
||||
type InheritContext = Partial<VNodeData> & ObjectIndex;
|
||||
|
||||
const inheritKey = [
|
||||
'ref',
|
||||
'style',
|
||||
'class',
|
||||
'attrs',
|
||||
'nativeOn',
|
||||
'directives',
|
||||
'staticClass',
|
||||
'staticStyle',
|
||||
];
|
||||
|
||||
const mapInheritKey: ObjectIndex = { nativeOn: 'on' };
|
||||
|
||||
// inherit partial context, map nativeOn to on
|
||||
export function inherit(
|
||||
context: Context,
|
||||
inheritListeners?: boolean
|
||||
): InheritContext {
|
||||
const result = inheritKey.reduce((obj, key) => {
|
||||
if (context.data[key]) {
|
||||
obj[mapInheritKey[key] || key] = context.data[key];
|
||||
}
|
||||
return obj;
|
||||
}, {} as InheritContext);
|
||||
|
||||
if (inheritListeners) {
|
||||
result.on = result.on || {};
|
||||
Object.assign(result.on, context.data.on);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// emit event
|
||||
export function emit(context: Context, eventName: string, ...args: any[]) {
|
||||
const listeners = context.listeners[eventName];
|
||||
if (listeners) {
|
||||
if (Array.isArray(listeners)) {
|
||||
listeners.forEach((listener) => {
|
||||
listener(...args);
|
||||
});
|
||||
} else {
|
||||
listeners(...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mount functional component
|
||||
export function mount(Component: any, data?: VNodeData) {
|
||||
const instance = new Vue({
|
||||
el: document.createElement('div'),
|
||||
props: Component.props,
|
||||
render(h) {
|
||||
return h(Component, {
|
||||
props: this.$props,
|
||||
...data,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
document.body.appendChild(instance.$el);
|
||||
|
||||
return instance;
|
||||
}
|
||||
+3
-6
@@ -1,14 +1,11 @@
|
||||
import Vue from 'vue';
|
||||
|
||||
export { createNamespace } from './create';
|
||||
export { addUnit } from './format/unit';
|
||||
|
||||
export const inBrowser = typeof window !== 'undefined';
|
||||
export const isServer: boolean = Vue.prototype.$isServer;
|
||||
export { createNamespace } from './create';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
export function noop() {}
|
||||
|
||||
export const inBrowser = typeof window !== 'undefined'
|
||||
|
||||
export function isDef(val: unknown): boolean {
|
||||
return val !== undefined && val !== null;
|
||||
}
|
||||
|
||||
+4
-9
@@ -2,12 +2,11 @@
|
||||
* Vue Router support
|
||||
*/
|
||||
|
||||
import { RenderContext } from 'vue/types';
|
||||
import VueRouter, { RawLocation } from 'vue-router/types';
|
||||
import type { Router, RouteLocation } from 'vue-router';
|
||||
|
||||
export type RouteConfig = {
|
||||
url?: string;
|
||||
to?: RawLocation;
|
||||
to?: RouteLocation;
|
||||
replace?: boolean;
|
||||
};
|
||||
|
||||
@@ -19,7 +18,7 @@ function isRedundantNavigation(err: Error) {
|
||||
);
|
||||
}
|
||||
|
||||
export function route(router: VueRouter, config: RouteConfig) {
|
||||
export function route(router: Router, config: RouteConfig) {
|
||||
const { to, url, replace } = config;
|
||||
if (to && router) {
|
||||
const promise = router[replace ? 'replace' : 'push'](to);
|
||||
@@ -37,14 +36,10 @@ export function route(router: VueRouter, config: RouteConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
export function functionalRoute(context: RenderContext) {
|
||||
route(context.parent && context.parent.$router, context.props);
|
||||
}
|
||||
|
||||
export type RouteProps = {
|
||||
url?: string;
|
||||
replace?: boolean;
|
||||
to?: RawLocation;
|
||||
to?: RouteLocation;
|
||||
};
|
||||
|
||||
export const routeProps = {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { isServer } from '..';
|
||||
import { inBrowser } from '..';
|
||||
|
||||
export function isAndroid(): boolean {
|
||||
/* istanbul ignore next */
|
||||
return isServer ? false : /android/.test(navigator.userAgent.toLowerCase());
|
||||
return inBrowser ? /android/.test(navigator.userAgent.toLowerCase()) : false;
|
||||
}
|
||||
|
||||
export function isIOS(): boolean {
|
||||
/* istanbul ignore next */
|
||||
return isServer
|
||||
? false
|
||||
: /ios|iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase());
|
||||
return inBrowser
|
||||
? /ios|iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase())
|
||||
: false;
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import { VNode } from 'vue';
|
||||
|
||||
function flattenVNodes(vnodes: VNode[]) {
|
||||
const result: VNode[] = [];
|
||||
|
||||
function traverse(vnodes: VNode[]) {
|
||||
vnodes.forEach((vnode) => {
|
||||
result.push(vnode);
|
||||
|
||||
if (vnode.componentInstance) {
|
||||
traverse(vnode.componentInstance.$children.map((item) => item.$vnode));
|
||||
}
|
||||
|
||||
if (vnode.children) {
|
||||
traverse(vnode.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
traverse(vnodes);
|
||||
return result;
|
||||
}
|
||||
|
||||
// sort children instances by vnodes order
|
||||
export function sortChildren(children: Vue[], parent: Vue) {
|
||||
const { componentOptions } = parent.$vnode;
|
||||
if (!componentOptions || !componentOptions.children) {
|
||||
return;
|
||||
}
|
||||
|
||||
const vnodes = flattenVNodes(componentOptions.children);
|
||||
children.sort((a, b) => vnodes.indexOf(a.$vnode) - vnodes.indexOf(b.$vnode));
|
||||
}
|
||||
Reference in New Issue
Block a user