@dazhicheng/hooks 1.4.37 → 1.4.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -4,4 +4,4 @@ export { usePriorityValue, usePriorityValues, getPriorityValues } from "./usePri
4
4
  export * from "./tools";
5
5
  export { useIsScroll } from "./useIsScroll";
6
6
  export { useDebounceFn } from "./useDebounce";
7
- export { useElementScreenshot } from "./useElementScreenshot";
7
+ export { useElementScreenshot, type ComponentCaptureOptions, type ComponentCaptureOutput, type ElementScreenshotOptions, } from "./useElementScreenshot";
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import t,{toType as e}from"vue-types/shim";import{kebabToCamelCase as n,getFirstNonNullOrUndefined as r,debounce as o}from"@dazhicheng/utils";import{getCurrentInstance as a,useSlots as i,useAttrs as u,computed as c,toValue as s,ref as l,nextTick as f}from"vue";import{toJpeg as d,toPng as p,toBlob as m}from"html-to-image";class w extends t{static get style(){return e("style",{type:[String,Object],default:void 0})}static get VNodeChild(){return e("VNodeChild",{default:void 0})}}function y(t){const e="tt";return{prefixCls:`${e}-${t}`,prefixVar:e}}function h(t,e,o){const s=a(),l=i(),f=u();return c(()=>{const a=s?.vnode?.props||{},i={};for(const[t,e]of Object.entries(a))i[n(t)]=e;const u=void 0===i?.[t]?void 0:e[t];return r(l[t],f[t],u,o?.value?.[t])})}function v(t,e){const n={};return Object.keys(t).forEach(r=>{n[r]=h(r,t,e)}),n}function g(t){const e={};for(const[n,r]of Object.entries(t))e[n]=s(r);return e}function b(t,e){return t in e}function C(t,e=new Map){if(null!==t&&"object"==typeof t){let n=e.get(t);return n||(Array.isArray(t)?(n=[],e.set(t,n),t.forEach((t,r)=>{n[r]=C(t,e)})):(n={},e.set(t,n),Object.keys(t).forEach(r=>{b(r,t)&&(n[r]=C(t[r],e))})),n)}return t}function k(...t){for(const e of t)if(null!=e)return e}function E(t){return t.split("-").filter(Boolean).map((t,e)=>0===e?t:t.charAt(0).toUpperCase()+t.slice(1)).join("")}function j(){const t=l(!1);return{hasScrollbar:t,update:e=>{if(!e.value)return;const n=e.value;t.value=n.scrollHeight>n.clientHeight}}}function F(t,e,n){const r=o(t,e??200,n);return{run:r,cancel:r.cancel,flush:r.flush}}function x(t){const e=s(t);if(!e)throw new Error("Target element not found");return e}function R(t){return{pixelRatio:t?.pixelRatio??Math.min(window.devicePixelRatio||2,3),backgroundColor:t?.backgroundColor??"#ffffff",cacheBust:t?.cacheBust??!0,quality:t?.quality??1,skipFontsReady:t?.skipFontsReady??!1}}async function O(t){t||"undefined"!=typeof document&&"fonts"in document&&await document.fonts.ready}async function A(t=16){await f(),await new Promise(t=>requestAnimationFrame(()=>t())),await new Promise(t=>requestAnimationFrame(()=>t())),t>0&&await new Promise(e=>setTimeout(e,t))}function T(){const t=l(!1),e=l(null);return{captureToBlob:async function(n,r){t.value=!0,e.value=null;try{return await async function(t,e){await A(e?.deferCaptureMs??16),await O(e?.skipFontsReady);const n=x(t),r=await m(n,R(e));if(!r)throw new Error("Failed to generate screenshot blob");return r}(n,r)}catch(t){const n=t instanceof Error?t:new Error(String(t));throw e.value=n,n}finally{t.value=!1}},captureToDataUrl:async function(n,r){t.value=!0,e.value=null;try{const t=r?.format??"png";await A(r?.deferCaptureMs??16),await O(r?.skipFontsReady);const e=x(n);return"jpeg"===t?await d(e,R(r)):await p(e,R(r))}catch(t){const n=t instanceof Error?t:new Error(String(t));throw e.value=n,n}finally{t.value=!1}},isCapturing:t}}export{C as deepCopy,k as getFirstNonNullOrUndefined,g as getPriorityValues,b as isValidKey,E as kebabToCamelCase,w as propTypes,F as useDebounceFn,y as useDesign,T as useElementScreenshot,j as useIsScroll,h as usePriorityValue,v as usePriorityValues};
1
+ import t,{toType as n}from"vue-types/shim";import{kebabToCamelCase as e,getFirstNonNullOrUndefined as r,debounce as o,isNumber as a}from"@dazhicheng/utils";import{getCurrentInstance as i,useSlots as c,useAttrs as u,computed as s,toValue as l,ref as f,render as d,nextTick as p,isVNode as w,h}from"vue";import{toBlob as m,toJpeg as y,toPng as v}from"html-to-image";class g extends t{static get style(){return n("style",{type:[String,Object],default:void 0})}static get VNodeChild(){return n("VNodeChild",{default:void 0})}}function b(t){const n="tt";return{prefixCls:`${n}-${t}`,prefixVar:n}}function C(t,n,o){const a=i(),l=c(),f=u();return s(()=>{const i=a?.vnode?.props||{},c={};for(const[t,n]of Object.entries(i))c[e(t)]=n;const u=void 0===c?.[t]?void 0:n[t];return r(l[t],f[t],u,o?.value?.[t])})}function x(t,n){const e={};return Object.keys(t).forEach(r=>{e[r]=C(r,t,n)}),e}function E(t){const n={};for(const[e,r]of Object.entries(t))n[e]=l(r);return n}function S(t,n){return t in n}function j(t,n=new Map){if(null!==t&&"object"==typeof t){let e=n.get(t);return e||(Array.isArray(t)?(e=[],n.set(t,e),t.forEach((t,r)=>{e[r]=j(t,n)})):(e={},n.set(t,e),Object.keys(t).forEach(r=>{S(r,t)&&(e[r]=j(t[r],n))})),e)}return t}function k(...t){for(const n of t)if(null!=n)return n}function F(t){return t.split("-").filter(Boolean).map((t,n)=>0===n?t:t.charAt(0).toUpperCase()+t.slice(1)).join("")}function M(){const t=f(!1);return{hasScrollbar:t,update:n=>{if(!n.value)return;const e=n.value;t.value=e.scrollHeight>e.clientHeight}}}function O(t,n,e){const r=o(t,n??200,e);return{run:r,cancel:r.cancel,flush:r.flush}}function R(t){const n=l(t);if(!n)throw new Error("Target element not found");return n}async function T(t=16){await p(),await new Promise(t=>requestAnimationFrame(()=>t())),await new Promise(t=>requestAnimationFrame(()=>t())),t>0&&await new Promise(n=>setTimeout(n,t))}function q(t,n){t.style.cssText=n?.containerStyle??"position:fixed;left:-10000px;top:0;pointer-events:none;z-index:-1;",n?.containerStyle&&/width\s*:/i.test(n.containerStyle)||(t.style.width=function(t){const n=t?.width??document.documentElement.clientWidth;if(a(t?.width)&&n>0)return`${Math.round(n)}px`;const e=document.documentElement.clientWidth||window.innerWidth;return`${Math.round(e)}px`}(n))}function A(){const t=f(!1),n=f(null),e=i()?.appContext??null;async function r(t,n){await async function(t){t||"undefined"!=typeof document&&"fonts"in document&&await document.fonts.ready}(n?.skipFontsReady);const e=function(t){return{pixelRatio:t?.pixelRatio??Math.min(window.devicePixelRatio||2,3),backgroundColor:t?.backgroundColor??"#ffffff",cacheBust:t?.cacheBust??!0,quality:t?.quality??1,skipFontsReady:t?.skipFontsReady??!1,filter:t?.filter}}(n);if("blob"===(n?.output??"dataUrl")){const n=await m(t,e);if(!n)throw new Error("Failed to generate screenshot blob");return n}return"jpeg"===(n?.format??"png")?await y(t,e):await v(t,e)}async function o(t,n){const r=document.body,o=document.createElement("div");q(o,n),r.appendChild(o);try{const r=function(t,n){const r=w(t)?t:h(t,n?.props);return e&&(r.appContext=e),r}(t,n);d(r,o),await p(),await(n?.beforeCapture?.(o)),await p(),await T(n?.deferCaptureMs??16);const a=n?.selector,i=a?o.querySelector(a):o.firstChild;if(!i)throw new Error(`截图元素没有找到: ${a}`);return{container:o,target:i}}catch(t){throw d(null,o),o.remove(),t}}return{captureToBlob:async function(e,o){t.value=!0,n.value=null;try{return await async function(t,n){await T(n?.deferCaptureMs??16);const e=R(t);return await r(e,{...n,output:"blob"})}(e,o)}catch(t){const e=t instanceof Error?t:new Error(String(t));throw n.value=e,e}finally{t.value=!1}},captureToDataUrl:async function(e,o){t.value=!0,n.value=null;try{await T(o?.deferCaptureMs??16);const t=R(e);return await r(t,{...o,output:"dataUrl"})}catch(t){const e=t instanceof Error?t:new Error(String(t));throw n.value=e,e}finally{t.value=!1}},captureComponent:async function(e,a){t.value=!0,n.value=null;const{container:i,target:c}=await o(e,a);try{return await r(c,a)}catch(t){const e=t instanceof Error?t:new Error(String(t));throw n.value=e,e}finally{!function(t){d(null,t),t.remove()}(i),t.value=!1}},isCapturing:t}}export{j as deepCopy,k as getFirstNonNullOrUndefined,E as getPriorityValues,S as isValidKey,F as kebabToCamelCase,g as propTypes,O as useDebounceFn,b as useDesign,A as useElementScreenshot,M as useIsScroll,C as usePriorityValue,x as usePriorityValues};
2
2
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/propTypes.ts","../src/useDesign.ts","../src/usePriorityValue.ts","../src/tools.ts","../src/useIsScroll.ts","../src/useDebounce.ts","../src/useElementScreenshot.ts"],"sourcesContent":["import type { VueTypeDef } from 'vue-types'\r\nimport VueTypes, { toType } from 'vue-types/shim'\r\n\r\n// export type VueNode = VNodeChild | JSX.Element\r\n\r\nexport class propTypes extends VueTypes {\r\n static get style(): VueTypeDef<any> {\r\n return toType('style', {\r\n type: [String, Object],\r\n default: undefined,\r\n })\r\n }\r\n\r\n static get VNodeChild(): VueTypeDef<any> {\r\n return toType('VNodeChild', {\r\n default: undefined,\r\n })\r\n }\r\n}\r\n","export function useDesign(scope: string) {\r\n const values = {\r\n prefixCls: 'tt',\r\n }\r\n\r\n return {\r\n prefixCls: `${values.prefixCls}-${scope}`,\r\n prefixVar: values.prefixCls,\r\n }\r\n}\r\n","import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue'\r\nimport { getFirstNonNullOrUndefined, kebabToCamelCase } from '@dazhicheng/utils'\r\n\r\nimport { computed, getCurrentInstance, toValue, unref, useAttrs, useSlots } from 'vue'\r\n\r\n/**\r\n * 依次从插槽、attrs、props、state 中获取值\r\n * @param key\r\n * @param props\r\n * @param state\r\n */\r\nfunction usePriorityValue<\r\n T extends Record<string, any>,\r\n S extends Record<string, any>,\r\n K extends keyof T = keyof T,\r\n>(key: K, props: T, state: Readonly<Ref<NoInfer<S>>> | undefined) {\r\n const instance = getCurrentInstance()\r\n const slots = useSlots()\r\n const attrs = useAttrs() as T\r\n\r\n const value = computed((): T[K] => {\r\n // props不管有没有传,都会有默认值,会影响这里的顺序,\r\n // 通过判断原始props是否有值来判断是否传入\r\n const rawProps = (instance?.vnode?.props || {}) as T\r\n\r\n const standardRawProps = {} as T\r\n\r\n for (const [key, value] of Object.entries(rawProps)) {\r\n standardRawProps[kebabToCamelCase(key) as K] = value\r\n }\r\n const propsKey = standardRawProps?.[key] === undefined ? undefined : props[key]\r\n\r\n // slot可以关闭\r\n return getFirstNonNullOrUndefined(\r\n slots[key as string],\r\n attrs[key],\r\n propsKey,\r\n state?.value?.[key as keyof S]\r\n ) as T[K]\r\n })\r\n\r\n return value\r\n}\r\n\r\n/**\r\n * 批量获取state中的值(每个值都是ref)\r\n * @param props\r\n * @param state\r\n */\r\nfunction usePriorityValues<\r\n T extends Record<string, any>,\r\n S extends Ref<Record<string, any>> = Readonly<Ref<NoInfer<T>, NoInfer<T>>>,\r\n>(props: T, state: S | undefined) {\r\n const result: { [K in keyof T]: ComputedRef<T[K]> } = {} as never\r\n\r\n ;(Object.keys(props) as (keyof T)[]).forEach(key => {\r\n result[key] = usePriorityValue(key as keyof typeof props, props, state)\r\n })\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * 批量获取state中的值(集中在一个computed,用于透传)\r\n * @param props\r\n * @param state\r\n */\r\nfunction useForwardPriorityValues<\r\n T extends Record<string, any>,\r\n S extends Ref<Record<string, any>> = Readonly<Ref<NoInfer<T>, NoInfer<T>>>,\r\n>(props: T, state: S | undefined) {\r\n const computedResult: { [K in keyof T]: ComputedRef<T[K]> } = {} as never\r\n\r\n ;(Object.keys(props) as (keyof T)[]).forEach(key => {\r\n computedResult[key] = usePriorityValue(key as keyof typeof props, props, state)\r\n })\r\n\r\n return computed(() => {\r\n const unwrapResult: Record<string, any> = {}\r\n Object.keys(props).forEach(key => {\r\n unwrapResult[key] = unref(computedResult[key])\r\n })\r\n return unwrapResult as { [K in keyof T]: T[K] }\r\n })\r\n}\r\n\r\n/**\r\n * 将包含ComputedRef的对象转换为普通值对象\r\n * @param props - 包含ComputedRef的响应式对象\r\n * @returns 解包后的普通对象,所有值都是原始值而非响应式引用\r\n */\r\nfunction getPriorityValues<\r\n T extends Record<string, MaybeRefOrGetter<any>>,\r\n S extends {\r\n [K in keyof T]: T[K] extends MaybeRefOrGetter<infer U> ? U : T[K]\r\n },\r\n>(props: T): S {\r\n // 创建解包后的对象类型\r\n const standardProps: S = {} as never\r\n\r\n // 遍历props对象的每个键值对\r\n for (const [key, value] of Object.entries(props)) {\r\n // 使用toValue解包计算属性值,并赋值给新对象\r\n standardProps[key as keyof T] = toValue(value)\r\n }\r\n\r\n return standardProps\r\n}\r\n\r\nexport { getPriorityValues, useForwardPriorityValues, usePriorityValue, usePriorityValues }\r\n","/**\r\n * 判断对象中是否包含该属性\r\n * @param key 键\r\n * @param object 对象\r\n * @returns 是否包含\r\n */\r\nexport function isValidKey(\r\n key: string | number | symbol,\r\n object: object\r\n): key is keyof typeof object {\r\n return key in object\r\n}\r\n\r\n/**\r\n * 深拷贝\r\n * 兼容函数,对象,相互引用场景\r\n * @param target 需要深拷贝的原对象\r\n * @return 深拷贝后的对象\r\n */\r\nexport function deepCopy<T>(target: T, map = new Map()) {\r\n if (target !== null && typeof target === 'object') {\r\n let res = map.get(target)\r\n if (res) return res\r\n if (Array.isArray(target)) {\r\n res = []\r\n map.set(target, res)\r\n target.forEach((item, index) => {\r\n res[index] = deepCopy(item, map)\r\n })\r\n } else {\r\n res = {}\r\n map.set(target, res)\r\n Object.keys(target).forEach(key => {\r\n if (isValidKey(key, target)) res[key] = deepCopy(target[key], map)\r\n })\r\n }\r\n return res\r\n }\r\n return target\r\n}\r\n\r\n\r\n/**\r\n * 获取第一个非 null 和非 undefined 的值\r\n * @description 从传入的多个值中返回第一个既不是 null 也不是 undefined 的值\r\n * @template T 返回值类型\r\n * @param args 要检查的值数组\r\n * @returns 第一个非 null 和非 undefined 的值,如果都是 null 或 undefined 则返回 undefined\r\n *\r\n * @example\r\n * getFirstNonNullOrUndefined(null, undefined, 1, 2) // 返回 1\r\n * getFirstNonNullOrUndefined(null, undefined) // 返回 undefined\r\n * getFirstNonNullOrUndefined('', null, 'test') // 返回 ''\r\n */\r\nexport function getFirstNonNullOrUndefined(...args: any[]): any {\r\n for (const value of args) {\r\n if (value !== undefined && value !== null) {\r\n return value\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\n\r\n/**\r\n * 将短横线命名转换为驼峰命名\r\n * @description 将形如 'my-component-name' 的短横线命名法转换为 'myComponentName' 的驼峰命名法\r\n * @param str 要转换的短横线命名字符串\r\n * @returns 转换后的驼峰命名字符串\r\n *\r\n * @example\r\n * kebabToCamelCase('my-component') // 返回 'myComponent'\r\n * kebabToCamelCase('my--component') // 返回 'myComponent'\r\n * kebabToCamelCase('-my-component-') // 返回 'myComponent'\r\n */\r\nexport function kebabToCamelCase(str: string): string {\r\n return str\r\n .split('-')\r\n .filter(Boolean)\r\n .map((word, index) => (index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)))\r\n .join('')\r\n}","import type { Ref } from 'vue'\r\nimport { ref } from 'vue'\r\n\r\nexport function useIsScroll(): {\r\n hasScrollbar: Ref<boolean>\r\n update: (elementRef: Ref<HTMLDivElement>) => void\r\n} {\r\n const hasScrollbar = ref(false)\r\n\r\n const update = (elementRef: Ref<HTMLDivElement>): void => {\r\n if (!elementRef.value) return\r\n const element = elementRef.value\r\n hasScrollbar.value = element.scrollHeight > element.clientHeight\r\n }\r\n\r\n return { hasScrollbar, update }\r\n}\r\n","import { debounce } from \"@dazhicheng/utils\";\r\nexport type DebounceSettings = {\r\n /**\r\n * 前沿触发\r\n */\r\n leading?: boolean | undefined;\r\n /**\r\n * 最大等待时间\r\n */\r\n maxWait?: number | undefined;\r\n /**\r\n * 尾部触发\r\n */\r\n trailing?: boolean | undefined;\r\n};\r\ntype noop = (...args: unknown[]) => unknown;\r\n\r\n/**\r\n * 防抖函数 Hook 返回类型\r\n */\r\ntype UseDebounceFnReturn<T extends noop> = {\r\n /**\r\n * 防抖函数,保持原函数的完整签名\r\n */\r\n run: (...args: Parameters<T>) => ReturnType<T>;\r\n /**\r\n * 取消防抖\r\n */\r\n cancel: () => void;\r\n /**\r\n * 立即执行防抖函数,保持原函数的完整签名\r\n */\r\n flush: (...args: Parameters<T>) => ReturnType<T>;\r\n};\r\n\r\n/**\r\n * 防抖函数 Hook\r\n * @param fn 要防抖的函数\r\n * @param wait 延迟时间(毫秒)默认200\r\n * @param options 防抖选项\r\n * @returns 返回防抖后的函数和相关控制方法\r\n */\r\nexport function useDebounceFn<T extends noop>(\r\n fn: T,\r\n wait?: number,\r\n options?: DebounceSettings,\r\n): UseDebounceFnReturn<T> {\r\n const debounced = debounce(fn, wait ?? 200, options);\r\n return {\r\n /**\r\n * 防抖函数,保持原函数的返回类型\r\n * 如果原函数是异步的,返回 Promise;如果是同步的,返回原始类型\r\n */\r\n run: debounced as unknown as (...args: Parameters<T>) => ReturnType<T>,\r\n\r\n /**\r\n * 取消防抖\r\n */\r\n cancel: debounced.cancel,\r\n\r\n /**\r\n * 立即执行防抖函数,保持原函数的返回类型\r\n */\r\n flush: debounced.flush as unknown as (...args: Parameters<T>) => ReturnType<T>,\r\n };\r\n}\r\n","import type { MaybeRefOrGetter } from \"vue\";\r\nimport { nextTick, ref, toValue } from \"vue\";\r\nimport { toBlob, toPng as htmlToPng, toJpeg as htmlToJpeg } from \"html-to-image\";\r\ntype ScreenshotTarget = HTMLElement | null | undefined;\r\ntype CaptureFormat = \"png\" | \"jpeg\";\r\n/**\r\n * 截图配置项\r\n */\r\nexport interface ElementScreenshotOptions {\r\n /**\r\n * 输出格式\r\n * 默认 png\r\n */\r\n format?: CaptureFormat;\r\n\r\n /**\r\n * jpeg 输出质量\r\n * 取值范围 0 到 1\r\n * 默认 1\r\n */\r\n quality?: number;\r\n\r\n /**\r\n * 渲染像素比\r\n * 默认 min(devicePixelRatio, 3)\r\n */\r\n pixelRatio?: number;\r\n\r\n /**\r\n * 背景色\r\n * 默认 #ffffff\r\n */\r\n backgroundColor?: string;\r\n\r\n /**\r\n * 资源防缓存参数\r\n * 默认 true\r\n */\r\n cacheBust?: boolean;\r\n\r\n /**\r\n * 是否跳过 document.fonts.ready\r\n * 默认 false\r\n */\r\n skipFontsReady?: boolean;\r\n\r\n /**\r\n * 截图前额外延迟毫秒数\r\n * 用于保证 loading 先渲染\r\n * 默认 16\r\n */\r\n deferCaptureMs?: number;\r\n}\r\n\r\n/**\r\n * 解析截图目标元素\r\n * @param target 截图目标元素或其 ref 或 getter\r\n * @returns 可用的 HTMLElement\r\n */\r\nfunction resolveTarget(target: MaybeRefOrGetter<ScreenshotTarget>): HTMLElement {\r\n const node = toValue(target);\r\n if (!node) {\r\n throw new Error(\"Target element not found\");\r\n }\r\n return node;\r\n}\r\n\r\n/**\r\n * 构建 html-to-image 渲染参数\r\n * @param options 截图配置项\r\n * @returns 渲染参数对象\r\n */\r\nfunction getRenderOptions(options?: ElementScreenshotOptions) {\r\n return {\r\n pixelRatio: options?.pixelRatio ?? Math.min(window.devicePixelRatio || 2, 3),\r\n backgroundColor: options?.backgroundColor ?? \"#ffffff\",\r\n cacheBust: options?.cacheBust ?? true,\r\n quality: options?.quality ?? 1,\r\n skipFontsReady: options?.skipFontsReady ?? false,\r\n };\r\n}\r\n\r\n/**\r\n * 截图前等待字体加载完成\r\n * @param skipFontsReady 是否跳过字体等待\r\n */\r\nasync function ensureFontsReady(skipFontsReady?: boolean) {\r\n if (skipFontsReady) return;\r\n if (typeof document === \"undefined\" || !(\"fonts\" in document)) return;\r\n await document.fonts.ready;\r\n}\r\n\r\n/**\r\n * 让出一帧\r\n * 确保 loading 先渲染\r\n */\r\nasync function waitPaintFrame(deferCaptureMs = 16) {\r\n await nextTick();\r\n await new Promise<void>(resolve => requestAnimationFrame(() => resolve()));\r\n await new Promise<void>(resolve => requestAnimationFrame(() => resolve()));\r\n if (deferCaptureMs > 0) {\r\n await new Promise<void>(resolve => setTimeout(resolve, deferCaptureMs));\r\n }\r\n}\r\n\r\n/**\r\n * DOM 截图 Hook\r\n * @returns 截图方法与状态\r\n */\r\nexport function useElementScreenshot() {\r\n const isCapturing = ref(false);\r\n const lastError = ref<Error | null>(null);\r\n\r\n /**\r\n * 清空最近一次错误\r\n */\r\n // function resetError() {\r\n // lastError.value = null;\r\n // }\r\n\r\n /**\r\n * 渲染目标元素并输出基础 Blob\r\n * @param target 截图目标元素或其 ref 或 getter\r\n * @param options 截图配置项\r\n * @returns 截图 Blob\r\n */\r\n async function renderToBaseBlob(\r\n target: MaybeRefOrGetter<ScreenshotTarget>,\r\n options?: ElementScreenshotOptions,\r\n ): Promise<Blob> {\r\n await waitPaintFrame(options?.deferCaptureMs ?? 16);\r\n await ensureFontsReady(options?.skipFontsReady);\r\n const node = resolveTarget(target);\r\n const blob = await toBlob(node, getRenderOptions(options));\r\n if (!blob) {\r\n throw new Error(\"Failed to generate screenshot blob\");\r\n }\r\n return blob;\r\n }\r\n\r\n /**\r\n * 导出 Blob\r\n * @param target 截图目标元素或其 ref 或 getter\r\n * @param options 截图配置项\r\n * @returns 截图 Blob\r\n */\r\n async function captureToBlob(\r\n target: MaybeRefOrGetter<ScreenshotTarget>,\r\n options?: ElementScreenshotOptions,\r\n ): Promise<Blob> {\r\n isCapturing.value = true;\r\n lastError.value = null;\r\n try {\r\n return await renderToBaseBlob(target, options);\r\n } catch (error) {\r\n const finalError = error instanceof Error ? error : new Error(String(error));\r\n lastError.value = finalError;\r\n throw finalError;\r\n } finally {\r\n isCapturing.value = false;\r\n }\r\n }\r\n\r\n /**\r\n * 导出 DataURL\r\n * @param target 截图目标元素或其 ref 或 getter\r\n * @param options 截图配置项\r\n * @returns 截图 DataURL\r\n */\r\n async function captureToDataUrl(\r\n target: MaybeRefOrGetter<ScreenshotTarget>,\r\n options?: ElementScreenshotOptions,\r\n ): Promise<string> {\r\n isCapturing.value = true;\r\n lastError.value = null;\r\n try {\r\n const format = options?.format ?? \"png\";\r\n await waitPaintFrame(options?.deferCaptureMs ?? 16);\r\n await ensureFontsReady(options?.skipFontsReady);\r\n const node = resolveTarget(target);\r\n if (format === \"jpeg\") {\r\n return await htmlToJpeg(node, getRenderOptions(options));\r\n }\r\n return await htmlToPng(node, getRenderOptions(options));\r\n } catch (error) {\r\n const finalError = error instanceof Error ? error : new Error(String(error));\r\n lastError.value = finalError;\r\n throw finalError;\r\n } finally {\r\n isCapturing.value = false;\r\n }\r\n }\r\n\r\n return {\r\n captureToBlob,\r\n captureToDataUrl,\r\n isCapturing,\r\n };\r\n}\r\n"],"names":["propTypes","VueTypes","style","toType","type","String","Object","default","undefined","VNodeChild","useDesign","scope","values","prefixCls","prefixVar","usePriorityValue","key","props","state","instance","getCurrentInstance","slots","useSlots","attrs","useAttrs","computed","rawProps","vnode","standardRawProps","value","entries","kebabToCamelCase","propsKey","getFirstNonNullOrUndefined","usePriorityValues","result","keys","forEach","getPriorityValues","standardProps","toValue","isValidKey","object","deepCopy","target","map","Map","res","get","Array","isArray","set","item","index","args","str","split","filter","Boolean","word","charAt","toUpperCase","slice","join","useIsScroll","hasScrollbar","ref","update","elementRef","element","scrollHeight","clientHeight","useDebounceFn","fn","wait","options","debounced","debounce","run","cancel","flush","resolveTarget","node","Error","getRenderOptions","pixelRatio","Math","min","window","devicePixelRatio","backgroundColor","cacheBust","quality","skipFontsReady","async","ensureFontsReady","document","fonts","ready","waitPaintFrame","deferCaptureMs","nextTick","Promise","resolve","requestAnimationFrame","setTimeout","useElementScreenshot","isCapturing","lastError","captureToBlob","blob","toBlob","renderToBaseBlob","error","finalError","captureToDataUrl","format","htmlToJpeg","htmlToPng"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/propTypes.ts","../src/useDesign.ts","../src/usePriorityValue.ts","../src/tools.ts","../src/useIsScroll.ts","../src/useDebounce.ts","../src/useElementScreenshot.ts"],"sourcesContent":["import type { VueTypeDef } from 'vue-types'\r\nimport VueTypes, { toType } from 'vue-types/shim'\r\n\r\n// export type VueNode = VNodeChild | JSX.Element\r\n\r\nexport class propTypes extends VueTypes {\r\n static get style(): VueTypeDef<any> {\r\n return toType('style', {\r\n type: [String, Object],\r\n default: undefined,\r\n })\r\n }\r\n\r\n static get VNodeChild(): VueTypeDef<any> {\r\n return toType('VNodeChild', {\r\n default: undefined,\r\n })\r\n }\r\n}\r\n","export function useDesign(scope: string) {\r\n const values = {\r\n prefixCls: 'tt',\r\n }\r\n\r\n return {\r\n prefixCls: `${values.prefixCls}-${scope}`,\r\n prefixVar: values.prefixCls,\r\n }\r\n}\r\n","import type { ComputedRef, MaybeRefOrGetter, Ref } from 'vue'\r\nimport { getFirstNonNullOrUndefined, kebabToCamelCase } from '@dazhicheng/utils'\r\n\r\nimport { computed, getCurrentInstance, toValue, unref, useAttrs, useSlots } from 'vue'\r\n\r\n/**\r\n * 依次从插槽、attrs、props、state 中获取值\r\n * @param key\r\n * @param props\r\n * @param state\r\n */\r\nfunction usePriorityValue<\r\n T extends Record<string, any>,\r\n S extends Record<string, any>,\r\n K extends keyof T = keyof T,\r\n>(key: K, props: T, state: Readonly<Ref<NoInfer<S>>> | undefined) {\r\n const instance = getCurrentInstance()\r\n const slots = useSlots()\r\n const attrs = useAttrs() as T\r\n\r\n const value = computed((): T[K] => {\r\n // props不管有没有传,都会有默认值,会影响这里的顺序,\r\n // 通过判断原始props是否有值来判断是否传入\r\n const rawProps = (instance?.vnode?.props || {}) as T\r\n\r\n const standardRawProps = {} as T\r\n\r\n for (const [key, value] of Object.entries(rawProps)) {\r\n standardRawProps[kebabToCamelCase(key) as K] = value\r\n }\r\n const propsKey = standardRawProps?.[key] === undefined ? undefined : props[key]\r\n\r\n // slot可以关闭\r\n return getFirstNonNullOrUndefined(\r\n slots[key as string],\r\n attrs[key],\r\n propsKey,\r\n state?.value?.[key as keyof S]\r\n ) as T[K]\r\n })\r\n\r\n return value\r\n}\r\n\r\n/**\r\n * 批量获取state中的值(每个值都是ref)\r\n * @param props\r\n * @param state\r\n */\r\nfunction usePriorityValues<\r\n T extends Record<string, any>,\r\n S extends Ref<Record<string, any>> = Readonly<Ref<NoInfer<T>, NoInfer<T>>>,\r\n>(props: T, state: S | undefined) {\r\n const result: { [K in keyof T]: ComputedRef<T[K]> } = {} as never\r\n\r\n ;(Object.keys(props) as (keyof T)[]).forEach(key => {\r\n result[key] = usePriorityValue(key as keyof typeof props, props, state)\r\n })\r\n\r\n return result\r\n}\r\n\r\n/**\r\n * 批量获取state中的值(集中在一个computed,用于透传)\r\n * @param props\r\n * @param state\r\n */\r\nfunction useForwardPriorityValues<\r\n T extends Record<string, any>,\r\n S extends Ref<Record<string, any>> = Readonly<Ref<NoInfer<T>, NoInfer<T>>>,\r\n>(props: T, state: S | undefined) {\r\n const computedResult: { [K in keyof T]: ComputedRef<T[K]> } = {} as never\r\n\r\n ;(Object.keys(props) as (keyof T)[]).forEach(key => {\r\n computedResult[key] = usePriorityValue(key as keyof typeof props, props, state)\r\n })\r\n\r\n return computed(() => {\r\n const unwrapResult: Record<string, any> = {}\r\n Object.keys(props).forEach(key => {\r\n unwrapResult[key] = unref(computedResult[key])\r\n })\r\n return unwrapResult as { [K in keyof T]: T[K] }\r\n })\r\n}\r\n\r\n/**\r\n * 将包含ComputedRef的对象转换为普通值对象\r\n * @param props - 包含ComputedRef的响应式对象\r\n * @returns 解包后的普通对象,所有值都是原始值而非响应式引用\r\n */\r\nfunction getPriorityValues<\r\n T extends Record<string, MaybeRefOrGetter<any>>,\r\n S extends {\r\n [K in keyof T]: T[K] extends MaybeRefOrGetter<infer U> ? U : T[K]\r\n },\r\n>(props: T): S {\r\n // 创建解包后的对象类型\r\n const standardProps: S = {} as never\r\n\r\n // 遍历props对象的每个键值对\r\n for (const [key, value] of Object.entries(props)) {\r\n // 使用toValue解包计算属性值,并赋值给新对象\r\n standardProps[key as keyof T] = toValue(value)\r\n }\r\n\r\n return standardProps\r\n}\r\n\r\nexport { getPriorityValues, useForwardPriorityValues, usePriorityValue, usePriorityValues }\r\n","/**\r\n * 判断对象中是否包含该属性\r\n * @param key 键\r\n * @param object 对象\r\n * @returns 是否包含\r\n */\r\nexport function isValidKey(\r\n key: string | number | symbol,\r\n object: object\r\n): key is keyof typeof object {\r\n return key in object\r\n}\r\n\r\n/**\r\n * 深拷贝\r\n * 兼容函数,对象,相互引用场景\r\n * @param target 需要深拷贝的原对象\r\n * @return 深拷贝后的对象\r\n */\r\nexport function deepCopy<T>(target: T, map = new Map()) {\r\n if (target !== null && typeof target === 'object') {\r\n let res = map.get(target)\r\n if (res) return res\r\n if (Array.isArray(target)) {\r\n res = []\r\n map.set(target, res)\r\n target.forEach((item, index) => {\r\n res[index] = deepCopy(item, map)\r\n })\r\n } else {\r\n res = {}\r\n map.set(target, res)\r\n Object.keys(target).forEach(key => {\r\n if (isValidKey(key, target)) res[key] = deepCopy(target[key], map)\r\n })\r\n }\r\n return res\r\n }\r\n return target\r\n}\r\n\r\n\r\n/**\r\n * 获取第一个非 null 和非 undefined 的值\r\n * @description 从传入的多个值中返回第一个既不是 null 也不是 undefined 的值\r\n * @template T 返回值类型\r\n * @param args 要检查的值数组\r\n * @returns 第一个非 null 和非 undefined 的值,如果都是 null 或 undefined 则返回 undefined\r\n *\r\n * @example\r\n * getFirstNonNullOrUndefined(null, undefined, 1, 2) // 返回 1\r\n * getFirstNonNullOrUndefined(null, undefined) // 返回 undefined\r\n * getFirstNonNullOrUndefined('', null, 'test') // 返回 ''\r\n */\r\nexport function getFirstNonNullOrUndefined(...args: any[]): any {\r\n for (const value of args) {\r\n if (value !== undefined && value !== null) {\r\n return value\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\n\r\n/**\r\n * 将短横线命名转换为驼峰命名\r\n * @description 将形如 'my-component-name' 的短横线命名法转换为 'myComponentName' 的驼峰命名法\r\n * @param str 要转换的短横线命名字符串\r\n * @returns 转换后的驼峰命名字符串\r\n *\r\n * @example\r\n * kebabToCamelCase('my-component') // 返回 'myComponent'\r\n * kebabToCamelCase('my--component') // 返回 'myComponent'\r\n * kebabToCamelCase('-my-component-') // 返回 'myComponent'\r\n */\r\nexport function kebabToCamelCase(str: string): string {\r\n return str\r\n .split('-')\r\n .filter(Boolean)\r\n .map((word, index) => (index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)))\r\n .join('')\r\n}","import type { Ref } from 'vue'\r\nimport { ref } from 'vue'\r\n\r\nexport function useIsScroll(): {\r\n hasScrollbar: Ref<boolean>\r\n update: (elementRef: Ref<HTMLDivElement>) => void\r\n} {\r\n const hasScrollbar = ref(false)\r\n\r\n const update = (elementRef: Ref<HTMLDivElement>): void => {\r\n if (!elementRef.value) return\r\n const element = elementRef.value\r\n hasScrollbar.value = element.scrollHeight > element.clientHeight\r\n }\r\n\r\n return { hasScrollbar, update }\r\n}\r\n","import { debounce } from \"@dazhicheng/utils\";\r\nexport type DebounceSettings = {\r\n /**\r\n * 前沿触发\r\n */\r\n leading?: boolean | undefined;\r\n /**\r\n * 最大等待时间\r\n */\r\n maxWait?: number | undefined;\r\n /**\r\n * 尾部触发\r\n */\r\n trailing?: boolean | undefined;\r\n};\r\ntype noop = (...args: unknown[]) => unknown;\r\n\r\n/**\r\n * 防抖函数 Hook 返回类型\r\n */\r\ntype UseDebounceFnReturn<T extends noop> = {\r\n /**\r\n * 防抖函数,保持原函数的完整签名\r\n */\r\n run: (...args: Parameters<T>) => ReturnType<T>;\r\n /**\r\n * 取消防抖\r\n */\r\n cancel: () => void;\r\n /**\r\n * 立即执行防抖函数,保持原函数的完整签名\r\n */\r\n flush: (...args: Parameters<T>) => ReturnType<T>;\r\n};\r\n\r\n/**\r\n * 防抖函数 Hook\r\n * @param fn 要防抖的函数\r\n * @param wait 延迟时间(毫秒)默认200\r\n * @param options 防抖选项\r\n * @returns 返回防抖后的函数和相关控制方法\r\n */\r\nexport function useDebounceFn<T extends noop>(\r\n fn: T,\r\n wait?: number,\r\n options?: DebounceSettings,\r\n): UseDebounceFnReturn<T> {\r\n const debounced = debounce(fn, wait ?? 200, options);\r\n return {\r\n /**\r\n * 防抖函数,保持原函数的返回类型\r\n * 如果原函数是异步的,返回 Promise;如果是同步的,返回原始类型\r\n */\r\n run: debounced as unknown as (...args: Parameters<T>) => ReturnType<T>,\r\n\r\n /**\r\n * 取消防抖\r\n */\r\n cancel: debounced.cancel,\r\n\r\n /**\r\n * 立即执行防抖函数,保持原函数的返回类型\r\n */\r\n flush: debounced.flush as unknown as (...args: Parameters<T>) => ReturnType<T>,\r\n };\r\n}\r\n","import type { Component, VNode } from \"vue\";\r\nimport type { MaybeRefOrGetter } from \"vue\";\r\nimport { getCurrentInstance, h, isVNode, nextTick, ref, render, toValue } from \"vue\";\r\nimport { isNumber } from \"@dazhicheng/utils\";\r\nimport { toBlob, toPng as htmlToPng, toJpeg as htmlToJpeg } from \"html-to-image\";\r\n\r\ntype ScreenshotTarget = HTMLElement | null | undefined;\r\ntype CaptureFormat = \"png\" | \"jpeg\";\r\nexport type ComponentCaptureOutput = \"dataUrl\" | \"blob\";\r\n\r\n/**\r\n * 截图配置项\r\n */\r\nexport interface ElementScreenshotOptions {\r\n /**\r\n * 输出格式\r\n * 默认 png\r\n */\r\n format?: CaptureFormat;\r\n\r\n /**\r\n * jpeg 输出质量\r\n * 取值范围 0 到 1\r\n * 默认 1\r\n */\r\n quality?: number;\r\n\r\n /**\r\n * 渲染像素比\r\n * 默认 min(devicePixelRatio, 3)\r\n */\r\n pixelRatio?: number;\r\n\r\n /**\r\n * 背景色\r\n * 默认 #ffffff\r\n */\r\n backgroundColor?: string;\r\n\r\n /**\r\n * 资源防缓存参数\r\n * 默认 true\r\n */\r\n cacheBust?: boolean;\r\n\r\n /**\r\n * 是否跳过 document.fonts.ready\r\n * 默认 false\r\n */\r\n skipFontsReady?: boolean;\r\n\r\n /**\r\n * 截图前额外延迟毫秒数\r\n * 用于保证 loading 先渲染\r\n * 默认 16\r\n */\r\n deferCaptureMs?: number;\r\n /**\r\n * html-to-image 节点过滤(返回 false 的节点及其子树不会出现在截图中)\r\n */\r\n filter?: (domNode: HTMLElement) => boolean;\r\n}\r\n\r\n/**\r\n * 离屏挂载组件并截图的配置项\r\n */\r\nexport interface ComponentCaptureOptions extends ElementScreenshotOptions {\r\n /**\r\n * 传给组件的 props\r\n */\r\n props?: Record<string, unknown>;\r\n\r\n /**\r\n * 离屏容器行内样式\r\n * 若未设置 width,会与 width 选项合并\r\n */\r\n containerStyle?: string;\r\n\r\n /**\r\n * 离屏容器宽度(px)\r\n * 默认 document.documentElement.clientWidth(当前页面视口宽)\r\n */\r\n width: number;\r\n\r\n /**\r\n * 截图目标在离屏容器内的选择器\r\n * 未传则使用容器第一个子元素\r\n */\r\n selector?: string;\r\n\r\n /**\r\n * 输出类型\r\n * dataUrl 为 DataURL 字符串,blob 为 Blob\r\n * 默认 dataUrl\r\n */\r\n output?: ComponentCaptureOutput;\r\n\r\n /**\r\n * 组件挂载并完成 nextTick 后的钩子(如同步表单值)\r\n * @param container 离屏挂载根容器\r\n */\r\n beforeCapture?: (container: HTMLElement) => void | Promise<void>;\r\n}\r\n\r\nconst DEFAULT_OFFSCREEN_CONTAINER_STYLE = \"position:fixed;left:-10000px;top:0;pointer-events:none;z-index:-1;\";\r\n\r\n/**\r\n * 解析截图目标元素\r\n */\r\nfunction resolveTarget(target: MaybeRefOrGetter<ScreenshotTarget>): HTMLElement {\r\n const node = toValue(target);\r\n if (!node) {\r\n throw new Error(\"Target element not found\");\r\n }\r\n return node;\r\n}\r\n\r\n/**\r\n * 构建 html-to-image 渲染参数\r\n */\r\nfunction getRenderOptions(options?: ElementScreenshotOptions) {\r\n return {\r\n pixelRatio: options?.pixelRatio ?? Math.min(window.devicePixelRatio || 2, 3),\r\n backgroundColor: options?.backgroundColor ?? \"#ffffff\",\r\n cacheBust: options?.cacheBust ?? true,\r\n quality: options?.quality ?? 1,\r\n skipFontsReady: options?.skipFontsReady ?? false,\r\n filter: options?.filter,\r\n // includeStyleProperties: [\"hidden\"],\r\n };\r\n}\r\n\r\n/**\r\n * 截图前等待字体加载完成\r\n */\r\nasync function ensureFontsReady(skipFontsReady?: boolean) {\r\n if (skipFontsReady) return;\r\n if (typeof document === \"undefined\" || !(\"fonts\" in document)) return;\r\n await document.fonts.ready;\r\n}\r\n\r\n/**\r\n * 让出一帧,确保 DOM 绘制完成\r\n */\r\nasync function waitPaintFrame(deferCaptureMs = 16) {\r\n await nextTick();\r\n await new Promise<void>(resolve => requestAnimationFrame(() => resolve()));\r\n await new Promise<void>(resolve => requestAnimationFrame(() => resolve()));\r\n if (deferCaptureMs > 0) {\r\n await new Promise<void>(resolve => setTimeout(resolve, deferCaptureMs));\r\n }\r\n}\r\n\r\nfunction resolveOffscreenWidth(options?: ComponentCaptureOptions): string {\r\n const width = options?.width ?? document.documentElement.clientWidth;\r\n if (isNumber(options?.width) && width > 0) {\r\n return `${Math.round(width)}px`;\r\n }\r\n const viewportWidth = document.documentElement.clientWidth || window.innerWidth;\r\n return `${Math.round(viewportWidth)}px`;\r\n}\r\n\r\nfunction applyOffscreenContainerStyle(container: HTMLElement, options?: ComponentCaptureOptions) {\r\n container.style.cssText = options?.containerStyle ?? DEFAULT_OFFSCREEN_CONTAINER_STYLE;\r\n if (!options?.containerStyle || !/width\\s*:/i.test(options.containerStyle)) {\r\n container.style.width = resolveOffscreenWidth(options);\r\n }\r\n}\r\n\r\n/**\r\n * DOM 截图 Hook\r\n */\r\nexport function useElementScreenshot() {\r\n const isCapturing = ref(false);\r\n const lastError = ref<Error | null>(null);\r\n const fallbackAppContext = getCurrentInstance()?.appContext ?? null;\r\n\r\n /**\r\n * 对已有 DOM 节点执行 html-to-image 截图\r\n */\r\n async function renderTargetToResult(\r\n target: HTMLElement,\r\n options?: ElementScreenshotOptions & { output?: ComponentCaptureOutput },\r\n ): Promise<string | Blob> {\r\n await ensureFontsReady(options?.skipFontsReady);\r\n const renderOptions = getRenderOptions(options);\r\n const output = options?.output ?? \"dataUrl\";\r\n\r\n if (output === \"blob\") {\r\n const blob = await toBlob(target, renderOptions);\r\n if (!blob) {\r\n throw new Error(\"Failed to generate screenshot blob\");\r\n }\r\n return blob;\r\n }\r\n\r\n const format = options?.format ?? \"png\";\r\n if (format === \"jpeg\") {\r\n return await htmlToJpeg(target, renderOptions);\r\n }\r\n return await htmlToPng(target, renderOptions);\r\n }\r\n\r\n /**\r\n * 离屏挂载组件并解析截图目标\r\n */\r\n function resolveRenderVNode(component: Component | VNode, options?: ComponentCaptureOptions): VNode {\r\n const vnode = isVNode(component) ? component : h(component, options?.props);\r\n if (fallbackAppContext) {\r\n vnode.appContext = fallbackAppContext;\r\n }\r\n return vnode;\r\n }\r\n\r\n async function mountComponentOffscreen(component: Component | VNode, options?: ComponentCaptureOptions) {\r\n const host = document.body;\r\n const container = document.createElement(\"div\");\r\n applyOffscreenContainerStyle(container, options);\r\n host.appendChild(container);\r\n\r\n try {\r\n const vnode = resolveRenderVNode(component, options);\r\n render(vnode, container);\r\n await nextTick();\r\n await options?.beforeCapture?.(container);\r\n await nextTick();\r\n await waitPaintFrame(options?.deferCaptureMs ?? 16);\r\n const selector = options?.selector;\r\n const target = selector\r\n ? (container.querySelector(selector) as HTMLElement | null)\r\n : (container.firstChild as HTMLElement);\r\n if (!target) {\r\n throw new Error(`截图元素没有找到: ${selector}`);\r\n }\r\n return { container, target };\r\n } catch (error) {\r\n render(null, container);\r\n container.remove();\r\n throw error;\r\n }\r\n }\r\n\r\n function unmountOffscreen(container: HTMLElement) {\r\n render(null, container);\r\n container.remove();\r\n }\r\n\r\n async function renderToBaseBlob(\r\n target: MaybeRefOrGetter<ScreenshotTarget>,\r\n options?: ElementScreenshotOptions,\r\n ): Promise<Blob> {\r\n await waitPaintFrame(options?.deferCaptureMs ?? 16);\r\n const node = resolveTarget(target);\r\n const result = await renderTargetToResult(node, { ...options, output: \"blob\" });\r\n return result as Blob;\r\n }\r\n\r\n async function captureToBlob(\r\n target: MaybeRefOrGetter<ScreenshotTarget>,\r\n options?: ElementScreenshotOptions,\r\n ): Promise<Blob> {\r\n isCapturing.value = true;\r\n lastError.value = null;\r\n try {\r\n return await renderToBaseBlob(target, options);\r\n } catch (error) {\r\n const finalError = error instanceof Error ? error : new Error(String(error));\r\n lastError.value = finalError;\r\n throw finalError;\r\n } finally {\r\n isCapturing.value = false;\r\n }\r\n }\r\n\r\n async function captureToDataUrl(\r\n target: MaybeRefOrGetter<ScreenshotTarget>,\r\n options?: ElementScreenshotOptions,\r\n ): Promise<string> {\r\n isCapturing.value = true;\r\n lastError.value = null;\r\n try {\r\n await waitPaintFrame(options?.deferCaptureMs ?? 16);\r\n const node = resolveTarget(target);\r\n const result = await renderTargetToResult(node, { ...options, output: \"dataUrl\" });\r\n return result as string;\r\n } catch (error) {\r\n const finalError = error instanceof Error ? error : new Error(String(error));\r\n lastError.value = finalError;\r\n throw finalError;\r\n } finally {\r\n isCapturing.value = false;\r\n }\r\n }\r\n\r\n /**\r\n * 截取传入的组件\r\n */\r\n async function captureComponent(\r\n component: Component | VNode,\r\n options?: ComponentCaptureOptions & { output?: \"dataUrl\" },\r\n ): Promise<string>;\r\n async function captureComponent(\r\n component: Component | VNode,\r\n options: ComponentCaptureOptions & { output: \"blob\" },\r\n ): Promise<Blob>;\r\n async function captureComponent(\r\n component: Component | VNode,\r\n options?: ComponentCaptureOptions,\r\n ): Promise<string | Blob> {\r\n isCapturing.value = true;\r\n lastError.value = null;\r\n const { container, target } = await mountComponentOffscreen(component, options);\r\n try {\r\n return await renderTargetToResult(target, options);\r\n } catch (error) {\r\n const finalError = error instanceof Error ? error : new Error(String(error));\r\n lastError.value = finalError;\r\n throw finalError;\r\n } finally {\r\n unmountOffscreen(container);\r\n isCapturing.value = false;\r\n }\r\n }\r\n\r\n return {\r\n captureToBlob,\r\n captureToDataUrl,\r\n captureComponent,\r\n isCapturing,\r\n };\r\n}\r\n"],"names":["propTypes","VueTypes","style","toType","type","String","Object","default","undefined","VNodeChild","useDesign","scope","values","prefixCls","prefixVar","usePriorityValue","key","props","state","instance","getCurrentInstance","slots","useSlots","attrs","useAttrs","computed","rawProps","vnode","standardRawProps","value","entries","kebabToCamelCase","propsKey","getFirstNonNullOrUndefined","usePriorityValues","result","keys","forEach","getPriorityValues","standardProps","toValue","isValidKey","object","deepCopy","target","map","Map","res","get","Array","isArray","set","item","index","args","str","split","filter","Boolean","word","charAt","toUpperCase","slice","join","useIsScroll","hasScrollbar","ref","update","elementRef","element","scrollHeight","clientHeight","useDebounceFn","fn","wait","options","debounced","debounce","run","cancel","flush","resolveTarget","node","Error","async","waitPaintFrame","deferCaptureMs","nextTick","Promise","resolve","requestAnimationFrame","setTimeout","applyOffscreenContainerStyle","container","cssText","containerStyle","test","width","document","documentElement","clientWidth","isNumber","Math","round","viewportWidth","window","innerWidth","resolveOffscreenWidth","useElementScreenshot","isCapturing","lastError","fallbackAppContext","appContext","renderTargetToResult","skipFontsReady","fonts","ready","ensureFontsReady","renderOptions","pixelRatio","min","devicePixelRatio","backgroundColor","cacheBust","quality","getRenderOptions","output","blob","toBlob","format","htmlToJpeg","htmlToPng","mountComponentOffscreen","component","host","body","createElement","appendChild","isVNode","h","resolveRenderVNode","render","beforeCapture","selector","querySelector","firstChild","error","remove","captureToBlob","renderToBaseBlob","finalError","captureToDataUrl","captureComponent","unmountOffscreen"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
+ import type { Component, VNode } from "vue";
1
2
  import type { MaybeRefOrGetter } from "vue";
2
3
  type ScreenshotTarget = HTMLElement | null | undefined;
3
4
  type CaptureFormat = "png" | "jpeg";
5
+ export type ComponentCaptureOutput = "dataUrl" | "blob";
4
6
  /**
5
7
  * 截图配置项
6
8
  */
@@ -42,14 +44,60 @@ export interface ElementScreenshotOptions {
42
44
  * 默认 16
43
45
  */
44
46
  deferCaptureMs?: number;
47
+ /**
48
+ * html-to-image 节点过滤(返回 false 的节点及其子树不会出现在截图中)
49
+ */
50
+ filter?: (domNode: HTMLElement) => boolean;
51
+ }
52
+ /**
53
+ * 离屏挂载组件并截图的配置项
54
+ */
55
+ export interface ComponentCaptureOptions extends ElementScreenshotOptions {
56
+ /**
57
+ * 传给组件的 props
58
+ */
59
+ props?: Record<string, unknown>;
60
+ /**
61
+ * 离屏容器行内样式
62
+ * 若未设置 width,会与 width 选项合并
63
+ */
64
+ containerStyle?: string;
65
+ /**
66
+ * 离屏容器宽度(px)
67
+ * 默认 document.documentElement.clientWidth(当前页面视口宽)
68
+ */
69
+ width: number;
70
+ /**
71
+ * 截图目标在离屏容器内的选择器
72
+ * 未传则使用容器第一个子元素
73
+ */
74
+ selector?: string;
75
+ /**
76
+ * 输出类型
77
+ * dataUrl 为 DataURL 字符串,blob 为 Blob
78
+ * 默认 dataUrl
79
+ */
80
+ output?: ComponentCaptureOutput;
81
+ /**
82
+ * 组件挂载并完成 nextTick 后的钩子(如同步表单值)
83
+ * @param container 离屏挂载根容器
84
+ */
85
+ beforeCapture?: (container: HTMLElement) => void | Promise<void>;
45
86
  }
46
87
  /**
47
88
  * DOM 截图 Hook
48
- * @returns 截图方法与状态
49
89
  */
50
90
  export declare function useElementScreenshot(): {
51
91
  captureToBlob: (target: MaybeRefOrGetter<ScreenshotTarget>, options?: ElementScreenshotOptions) => Promise<Blob>;
52
92
  captureToDataUrl: (target: MaybeRefOrGetter<ScreenshotTarget>, options?: ElementScreenshotOptions) => Promise<string>;
93
+ captureComponent: {
94
+ (component: Component | VNode, options?: ComponentCaptureOptions & {
95
+ output?: "dataUrl";
96
+ }): Promise<string>;
97
+ (component: Component | VNode, options: ComponentCaptureOptions & {
98
+ output: "blob";
99
+ }): Promise<Blob>;
100
+ };
53
101
  isCapturing: import("vue").Ref<boolean, boolean>;
54
102
  };
55
103
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dazhicheng/hooks",
3
- "version": "1.4.37",
3
+ "version": "1.4.39",
4
4
  "description": "",
5
5
  "main": "./dist/index.esm.js",
6
6
  "module": "./dist/index.esm.js",
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "vue-types": "^5.1.2",
26
26
  "html-to-image": "^1.11.13",
27
- "@dazhicheng/utils": "1.3.36"
27
+ "@dazhicheng/utils": "1.3.38"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "element-plus": "^2.7.0"