chore: merge src and src-next

This commit is contained in:
chenjiahan
2020-07-15 20:02:00 +08:00
parent 6672b34618
commit 0304fcb6fa
382 changed files with 464 additions and 24746 deletions
+8 -76
View File
@@ -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;
};
}
+5 -1
View File
@@ -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)
];
}
+4 -4
View File
@@ -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 -2
View File
@@ -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;
-71
View File
@@ -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
View File
@@ -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
View File
@@ -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 = {
+5 -5
View File
@@ -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;
}
-33
View File
@@ -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));
}