58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
import { Component, ComponentInternalInstance, VNode, VNodeTypes } from "vue";
|
||
|
||
export enum ShapeFlags {
|
||
ELEMENT = 1,
|
||
FUNCTIONAL_COMPONENT = 1 << 1,
|
||
STATEFUL_COMPONENT = 1 << 2,
|
||
COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT,
|
||
TEXT_CHILDREN = 1 << 3,
|
||
ARRAY_CHILDREN = 1 << 4,
|
||
SLOTS_CHILDREN = 1 << 5,
|
||
TELEPORT = 1 << 6,
|
||
SUSPENSE = 1 << 7,
|
||
COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,
|
||
COMPONENT_KEPT_ALIVE = 1 << 9,
|
||
}
|
||
|
||
export const isElement = (vn: VNode) => {
|
||
return Boolean(vn && vn.shapeFlag & ShapeFlags.ELEMENT);
|
||
};
|
||
|
||
export const isComponent = (
|
||
vn: VNode,
|
||
type?: VNodeTypes
|
||
): type is Component => {
|
||
return Boolean(vn && vn.shapeFlag & ShapeFlags.COMPONENT);
|
||
};
|
||
|
||
export const isArrayChildren = (
|
||
vn: VNode,
|
||
children: VNode["children"]
|
||
): children is VNode[] => {
|
||
return Boolean(vn && vn.shapeFlag & ShapeFlags.ARRAY_CHILDREN);
|
||
};
|
||
|
||
/**
|
||
* 同时支持驼峰命名和破折号命名的插槽,示例:back-icon 和 backIcon
|
||
* @param vm 组件实例
|
||
* @param name 插槽名
|
||
*/
|
||
export function convertSlotName(vm: ComponentInternalInstance, name: string) {
|
||
const camelCaseName = camelCase(name);
|
||
const kebabCaseName = kebabCase(name);
|
||
return vm.slots[camelCaseName]
|
||
? camelCaseName
|
||
: vm.slots[kebabCaseName]
|
||
? kebabCaseName
|
||
: name;
|
||
}
|
||
|
||
export function camelCase(str: string) {
|
||
return str.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : ""));
|
||
}
|
||
|
||
export function kebabCase(key: string) {
|
||
const result = key.replace(/([A-Z])/g, " $1").trim();
|
||
return result.split(" ").join("-").toLowerCase();
|
||
}
|