vben
2023-04-05 8e5a6b7ce547ba8edb1d767bb4d820f3b66ff95a
提交 | 用户 | age
4ff1c4 1 import { getCurrentInstance, reactive, shallowRef, watchEffect } from 'vue';
ebf7c8 2 import type { Ref } from 'vue';
8e5a6b 3
4ff1c4 4 interface Params {
V 5   excludeListeners?: boolean;
6   excludeKeys?: string[];
be2d11 7   excludeDefaultKeys?: boolean;
4ff1c4 8 }
V 9
10 const DEFAULT_EXCLUDE_KEYS = ['class', 'style'];
11 const LISTENER_PREFIX = /^on[A-Z]/;
12
979058 13 export function entries<T>(obj: Recordable<T>): [string, T][] {
4ff1c4 14   return Object.keys(obj).map((key: string) => [key, obj[key]]);
V 15 }
16
ebf7c8 17 export function useAttrs(params: Params = {}): Ref<Recordable> | {} {
4ff1c4 18   const instance = getCurrentInstance();
V 19   if (!instance) return {};
20
be2d11 21   const { excludeListeners = false, excludeKeys = [], excludeDefaultKeys = true } = params;
4ff1c4 22   const attrs = shallowRef({});
be2d11 23   const allExcludeKeys = excludeKeys.concat(excludeDefaultKeys ? DEFAULT_EXCLUDE_KEYS : []);
4ff1c4 24
V 25   // Since attrs are not reactive, make it reactive instead of doing in `onUpdated` hook for better performance
26   instance.attrs = reactive(instance.attrs);
27
28   watchEffect(() => {
29     const res = entries(instance.attrs).reduce((acm, [key, val]) => {
30       if (!allExcludeKeys.includes(key) && !(excludeListeners && LISTENER_PREFIX.test(key))) {
31         acm[key] = val;
32       }
33
34       return acm;
c9089c 35     }, {} as Recordable);
4ff1c4 36
V 37     attrs.value = res;
38   });
39
40   return attrs;
41 }