mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-04-05 07:03:00 +08:00
update:修改自定义指令的创建方式
This commit is contained in:
parent
17b0c27d96
commit
ca9bbf7673
@ -5,7 +5,6 @@ components.d.ts
|
||||
.gitignore
|
||||
public
|
||||
yarn.*
|
||||
vite-env.*
|
||||
.prettierrc.*
|
||||
visualizer.*
|
||||
visualizer.html
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
- 弃用 yarn 包管理器,使用 pnpm 作为模板包管理器
|
||||
- 新增路由切换时的内容区域动画
|
||||
- 更新了一些组件名称
|
||||
- 更新了自定义指令创建方式,改为函数式
|
||||
|
||||
### Fixes
|
||||
|
||||
|
89
src/App.tsx
89
src/App.tsx
@ -1,95 +1,16 @@
|
||||
import RayGlobalProvider from '@/components/RayGlobalProvider/index'
|
||||
import { RouterView } from 'vue-router'
|
||||
import AppNaiveGlobalProvider from '@/components/AppComponents/AppNaiveGlobalProvider/index'
|
||||
import AppStyleProvider from '@/components/AppComponents/AppStyleProvider/index'
|
||||
import GlobalSpin from '@/spin/index'
|
||||
import LockScreen from '@/components/AppComponents/AppLockScreen/index'
|
||||
|
||||
import { getStorage } from '@/utils/cache'
|
||||
import { get } from 'lodash-es'
|
||||
import { useSetting } from '@/store'
|
||||
import { addClass, removeClass, addStyle, colorToRgba } from '@/utils/element'
|
||||
|
||||
import type { SettingState } from '@/store/modules/setting/type'
|
||||
|
||||
const App = defineComponent({
|
||||
name: 'App',
|
||||
setup() {
|
||||
const settingStore = useSetting()
|
||||
|
||||
const { themeValue } = storeToRefs(settingStore)
|
||||
|
||||
/** 同步主题色变量至 body, 如果未获取到缓存值则已默认值填充 */
|
||||
const syncPrimaryColorToBody = () => {
|
||||
const {
|
||||
appPrimaryColor: { primaryColor, primaryFadeColor },
|
||||
} = __APP_CFG__ // 默认主题色
|
||||
const body = document.body
|
||||
|
||||
const primaryColorOverride = getStorage<SettingState>(
|
||||
'piniaSettingStore',
|
||||
'localStorage',
|
||||
)
|
||||
|
||||
if (primaryColorOverride) {
|
||||
const _p = get(
|
||||
primaryColorOverride,
|
||||
'primaryColorOverride.common.primaryColor',
|
||||
primaryColor,
|
||||
)
|
||||
const _fp = colorToRgba(_p, 0.3)
|
||||
|
||||
/** 设置全局主题色 css 变量 */
|
||||
body.style.setProperty('--ray-theme-primary-color', _p)
|
||||
body.style.setProperty(
|
||||
'--ray-theme-primary-fade-color',
|
||||
_fp || primaryFadeColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** 隐藏加载动画 */
|
||||
const hiddenLoadingAnimation = () => {
|
||||
/** pre-loading-animation 是默认 id */
|
||||
const el = document.getElementById('pre-loading-animation')
|
||||
|
||||
if (el) {
|
||||
addStyle(el, {
|
||||
display: 'none',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
syncPrimaryColorToBody()
|
||||
hiddenLoadingAnimation()
|
||||
|
||||
/** 切换主题时, 同步更新 body class 以便于进行自定义 css 配置 */
|
||||
watch(
|
||||
() => themeValue.value,
|
||||
(newData) => {
|
||||
/**
|
||||
*
|
||||
* 初始化时根据当前主题色进行初始化 body 的 class 属性
|
||||
*
|
||||
* 根据 themeValue 进行初始化
|
||||
*/
|
||||
const body = document.body
|
||||
const darkClassName = 'ray-template--dark'
|
||||
const lightClassName = 'ray-template--light'
|
||||
|
||||
newData
|
||||
? removeClass(body, lightClassName)
|
||||
: removeClass(body, darkClassName)
|
||||
|
||||
addClass(body, newData ? darkClassName : lightClassName)
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
)
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<RayGlobalProvider>
|
||||
<AppNaiveGlobalProvider>
|
||||
<LockScreen />
|
||||
<AppStyleProvider />
|
||||
|
||||
<GlobalSpin>
|
||||
{{
|
||||
@ -97,7 +18,7 @@ const App = defineComponent({
|
||||
description: () => 'lodaing...',
|
||||
}}
|
||||
</GlobalSpin>
|
||||
</RayGlobalProvider>
|
||||
</AppNaiveGlobalProvider>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
5
src/components/AppComponents/AppStyleProvider/index.scss
Normal file
5
src/components/AppComponents/AppStyleProvider/index.scss
Normal file
@ -0,0 +1,5 @@
|
||||
.app-style-provider {
|
||||
position: fixed;
|
||||
display: none;
|
||||
z-index: -999999;
|
||||
}
|
106
src/components/AppComponents/AppStyleProvider/index.tsx
Normal file
106
src/components/AppComponents/AppStyleProvider/index.tsx
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
*
|
||||
* @author Ray <https://github.com/XiaoDaiGua-Ray>
|
||||
*
|
||||
* @date 2023-07-08
|
||||
*
|
||||
* @workspace ray-template
|
||||
*
|
||||
* @remark 今天也是元气满满撸代码的一天
|
||||
*/
|
||||
|
||||
import './index.scss'
|
||||
|
||||
import { getStorage } from '@/utils/cache'
|
||||
import { get } from 'lodash-es'
|
||||
import { useSetting } from '@/store'
|
||||
import { addClass, removeClass, addStyle, colorToRgba } from '@/utils/element'
|
||||
|
||||
import type { SettingState } from '@/store/modules/setting/type'
|
||||
|
||||
const AppStyleProvider = defineComponent({
|
||||
name: 'AppStyleProvider',
|
||||
setup() {
|
||||
const settingStore = useSetting()
|
||||
|
||||
const { themeValue } = storeToRefs(settingStore)
|
||||
|
||||
/** 同步主题色变量至 body, 如果未获取到缓存值则已默认值填充 */
|
||||
const syncPrimaryColorToBody = () => {
|
||||
const {
|
||||
appPrimaryColor: { primaryColor, primaryFadeColor },
|
||||
} = __APP_CFG__ // 默认主题色
|
||||
const body = document.body
|
||||
|
||||
const primaryColorOverride = getStorage<SettingState>(
|
||||
'piniaSettingStore',
|
||||
'localStorage',
|
||||
)
|
||||
|
||||
if (primaryColorOverride) {
|
||||
const _p = get(
|
||||
primaryColorOverride,
|
||||
'primaryColorOverride.common.primaryColor',
|
||||
primaryColor,
|
||||
)
|
||||
const _fp = colorToRgba(_p, 0.38)
|
||||
|
||||
/** 设置全局主题色 css 变量 */
|
||||
body.style.setProperty('--ray-theme-primary-color', _p)
|
||||
body.style.setProperty(
|
||||
'--ray-theme-primary-fade-color',
|
||||
_fp || primaryFadeColor,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** 隐藏加载动画 */
|
||||
const hiddenLoadingAnimation = () => {
|
||||
/** pre-loading-animation 是默认 id */
|
||||
const el = document.getElementById('pre-loading-animation')
|
||||
|
||||
if (el) {
|
||||
addStyle(el, {
|
||||
display: 'none',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/** 切换主题时, 同步更新 body class 以便于进行自定义 css 配置 */
|
||||
const updateGlobalThemeClass = (bool: boolean) => {
|
||||
/**
|
||||
*
|
||||
* 初始化时根据当前主题色进行初始化 body 的 class 属性
|
||||
*
|
||||
* 根据 themeValue 进行初始化
|
||||
*/
|
||||
const body = document.body
|
||||
const darkClassName = 'ray-template--dark'
|
||||
const lightClassName = 'ray-template--light'
|
||||
|
||||
bool
|
||||
? removeClass(body, lightClassName)
|
||||
: removeClass(body, darkClassName)
|
||||
|
||||
addClass(body, bool ? darkClassName : lightClassName)
|
||||
}
|
||||
|
||||
syncPrimaryColorToBody()
|
||||
hiddenLoadingAnimation()
|
||||
|
||||
watch(
|
||||
() => themeValue.value,
|
||||
(ndata) => {
|
||||
updateGlobalThemeClass(ndata)
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
)
|
||||
},
|
||||
render() {
|
||||
return <div class="app-style-provider"></div>
|
||||
},
|
||||
})
|
||||
|
||||
export default AppStyleProvider
|
@ -1,6 +1,6 @@
|
||||
## 描述
|
||||
|
||||
> 该组件包存放依赖系统数据的公共组件。
|
||||
> 该组件包存放依赖系统数据的公共组件和与项目绑定的一些组件。
|
||||
|
||||
## 约束
|
||||
|
||||
|
@ -25,11 +25,14 @@
|
||||
|
||||
import type { Directive } from 'vue'
|
||||
import type { RoleBindingValue } from './type'
|
||||
import type { CustomDirectiveFC } from '@/directives/type'
|
||||
|
||||
const demoDirective: Directive<HTMLElement, RoleBindingValue> = {
|
||||
beforeMount: (el, binding) => {
|
||||
console.log(el, binding)
|
||||
},
|
||||
const demoDirective: CustomDirectiveFC<HTMLElement, RoleBindingValue> = () => {
|
||||
return {
|
||||
beforeMount: (el, binding) => {
|
||||
console.log(el, binding)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default demoDirective
|
||||
|
@ -9,7 +9,7 @@
|
||||
* @remark 今天也是元气满满撸代码的一天
|
||||
*/
|
||||
|
||||
import type { DirectiveModules } from '@/directives/type'
|
||||
import type { DirectiveModules, CustomDirectiveFC } from '@/directives/type'
|
||||
|
||||
export const combineDirective = <
|
||||
T extends Record<string, DirectiveModules>,
|
||||
@ -18,16 +18,16 @@ export const combineDirective = <
|
||||
directiveModules: T,
|
||||
) => {
|
||||
const directives = Object.keys(directiveModules).reduce((pre, curr) => {
|
||||
if (directiveModules[curr]?.default) {
|
||||
const value = directiveModules[curr]?.default
|
||||
const fc = directiveModules[curr]?.default
|
||||
|
||||
pre[curr] = value
|
||||
if (typeof fc === 'function') {
|
||||
pre[curr] = fc
|
||||
|
||||
return pre
|
||||
} else {
|
||||
throw new Error('directiveModules[curr]?.default is undefined')
|
||||
throw new Error('directiveModules[curr] is not function')
|
||||
}
|
||||
}, {} as Record<K, T[K]['default']>)
|
||||
}, {} as Record<K, CustomDirectiveFC<unknown, unknown>>)
|
||||
|
||||
return directives
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import type { DirectiveModules } from '@/directives/type'
|
||||
* 并且会将文件夹名称识别为指令名称
|
||||
* 每个文件下的 index.ts 文件视为每个指令的入口(也就是指令的处理逻辑, 需要暴露出一个 Directive 类型的对象)
|
||||
*/
|
||||
export const setupDirective = (app: App<Element>) => {
|
||||
export const setupDirectives = (app: App<Element>) => {
|
||||
// 获取 modules 包下所有的 index.ts 文件
|
||||
const directiveRawModules: Record<string, DirectiveModules> =
|
||||
import.meta.glob('./modules/**/index.ts', {
|
||||
@ -39,7 +39,7 @@ export const setupDirective = (app: App<Element>) => {
|
||||
const dname = key.match(reg)?.[0]
|
||||
|
||||
if (isValueType<string>(dname, 'String')) {
|
||||
app.directive(dname, value)
|
||||
app.directive(dname, value?.())
|
||||
} else {
|
||||
throw new Error(
|
||||
'directiveName is not string, please check your directive file name',
|
||||
|
@ -16,39 +16,40 @@
|
||||
|
||||
import ClipboardJS from 'clipboard'
|
||||
|
||||
import type { Directive } from 'vue'
|
||||
import type { CopyElement } from './type'
|
||||
import type { CustomDirectiveFC } from '@/directives/type'
|
||||
|
||||
let clipboard: ClipboardJS | null
|
||||
const copyDirective: CustomDirectiveFC<CopyElement, string> = () => {
|
||||
let clipboard: ClipboardJS | null
|
||||
|
||||
const copyDirective: Directive<CopyElement, string> = {
|
||||
mounted: (el, binding) => {
|
||||
const value = binding.value
|
||||
return {
|
||||
mounted: (el, binding) => {
|
||||
const value = binding.value
|
||||
|
||||
clipboard = new ClipboardJS(el, {
|
||||
text: () => String(value),
|
||||
})
|
||||
clipboard = new ClipboardJS(el, {
|
||||
text: () => String(value),
|
||||
})
|
||||
|
||||
clipboard?.on('success', () => {
|
||||
window.$message.success('复制成功')
|
||||
})
|
||||
clipboard?.on('error', () => {
|
||||
window.$message.error('复制失败')
|
||||
})
|
||||
},
|
||||
updated: (el, binding) => {
|
||||
/** 其实这块代码写的挺蠢的, 但是我目前不知道怎么去优化, 阿巴阿巴阿巴 */
|
||||
const value = binding.value
|
||||
clipboard?.on('success', () => {
|
||||
window.$message.success('复制成功')
|
||||
})
|
||||
clipboard?.on('error', () => {
|
||||
window.$message.error('复制失败')
|
||||
})
|
||||
},
|
||||
updated: (el, binding) => {
|
||||
/** 其实这块代码写的挺蠢的, 但是我目前不知道怎么去优化, 阿巴阿巴阿巴 */
|
||||
const value = binding.value
|
||||
|
||||
clipboard = new ClipboardJS(el, {
|
||||
text: () => String(value),
|
||||
})
|
||||
},
|
||||
beforeUnmount: () => {
|
||||
clipboard?.destroy()
|
||||
clipboard = new ClipboardJS(el, {
|
||||
text: () => String(value),
|
||||
})
|
||||
},
|
||||
beforeUnmount: () => {
|
||||
clipboard?.destroy()
|
||||
|
||||
clipboard = null
|
||||
},
|
||||
clipboard = null
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default copyDirective
|
||||
|
@ -21,31 +21,34 @@ import type { Directive } from 'vue'
|
||||
import type { DebounceBindingOptions } from './type'
|
||||
import type { AnyFunc } from '@/types/modules/utils'
|
||||
import type { DebouncedFunc } from 'lodash-es'
|
||||
import type { CustomDirectiveFC } from '@/directives/type'
|
||||
|
||||
let debounceFunction: DebouncedFunc<AnyFunc> | null
|
||||
const debounceDirective: CustomDirectiveFC<
|
||||
HTMLElement,
|
||||
DebounceBindingOptions
|
||||
> = () => {
|
||||
let debounceFunction: DebouncedFunc<AnyFunc> | null
|
||||
|
||||
const debounceDirective: Directive<HTMLElement, DebounceBindingOptions> = {
|
||||
beforeMount: (el, binding) => {
|
||||
const { func, trigger = 'click', wait = 500, options } = binding.value
|
||||
return {
|
||||
beforeMount: (el, binding) => {
|
||||
const { func, trigger = 'click', wait = 500, options } = binding.value
|
||||
if (typeof func !== 'function') {
|
||||
throw new Error('debounce directive value must be a function')
|
||||
}
|
||||
debounceFunction = debounce(func, wait, Object.assign({}, {}, options))
|
||||
on(el, trigger, debounceFunction)
|
||||
},
|
||||
beforeUnmount: (el, binding) => {
|
||||
const { trigger = 'click' } = binding.value
|
||||
|
||||
if (typeof func !== 'function') {
|
||||
throw new Error('debounce directive value must be a function')
|
||||
}
|
||||
if (debounceFunction) {
|
||||
debounceFunction.cancel()
|
||||
off(el, trigger, debounceFunction)
|
||||
}
|
||||
|
||||
debounceFunction = debounce(func, wait, Object.assign({}, {}, options))
|
||||
|
||||
on(el, trigger, debounceFunction)
|
||||
},
|
||||
beforeUnmount: (el, binding) => {
|
||||
const { trigger = 'click' } = binding.value
|
||||
|
||||
if (debounceFunction) {
|
||||
debounceFunction.cancel()
|
||||
off(el, trigger, debounceFunction)
|
||||
}
|
||||
|
||||
debounceFunction = null
|
||||
},
|
||||
debounceFunction = null
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default debounceDirective
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { addClass, removeClass } from '@/utils/element'
|
||||
|
||||
import type { Directive } from 'vue'
|
||||
import type { CustomDirectiveFC } from '@/directives/type'
|
||||
|
||||
const updateElementDisabledType = (el: HTMLElement, value: boolean) => {
|
||||
if (el) {
|
||||
@ -27,17 +28,18 @@ const updateElementDisabledType = (el: HTMLElement, value: boolean) => {
|
||||
}
|
||||
}
|
||||
|
||||
const disabledDirective: Directive<HTMLElement, boolean> = {
|
||||
mounted: (el, binding) => {
|
||||
const value = binding.value
|
||||
const disabledDirective: CustomDirectiveFC<HTMLElement, boolean> = () => {
|
||||
return {
|
||||
mounted: (el, binding) => {
|
||||
const value = binding.value
|
||||
|
||||
updateElementDisabledType(el, value)
|
||||
},
|
||||
updated: (el, binding) => {
|
||||
const value = binding.value
|
||||
updateElementDisabledType(el, value)
|
||||
},
|
||||
updated: (el, binding) => {
|
||||
const value = binding.value
|
||||
|
||||
updateElementDisabledType(el, value)
|
||||
},
|
||||
updateElementDisabledType(el, value)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default disabledDirective
|
||||
|
@ -21,31 +21,37 @@ import type { Directive } from 'vue'
|
||||
import type { ThrottleBindingOptions } from './type'
|
||||
import type { AnyFunc } from '@/types/modules/utils'
|
||||
import type { DebouncedFunc } from 'lodash-es'
|
||||
import type { CustomDirectiveFC } from '@/directives/type'
|
||||
|
||||
let throttleFunction: DebouncedFunc<AnyFunc> | null
|
||||
const throttleDirective: CustomDirectiveFC<
|
||||
HTMLElement,
|
||||
ThrottleBindingOptions
|
||||
> = () => {
|
||||
let throttleFunction: DebouncedFunc<AnyFunc> | null
|
||||
|
||||
const throttleDirective: Directive<HTMLElement, ThrottleBindingOptions> = {
|
||||
beforeMount: (el, binding) => {
|
||||
const { func, trigger = 'click', wait = 500, options } = binding.value
|
||||
return {
|
||||
beforeMount: (el, binding) => {
|
||||
const { func, trigger = 'click', wait = 500, options } = binding.value
|
||||
|
||||
if (typeof func !== 'function') {
|
||||
throw new Error('throttle directive value must be a function')
|
||||
}
|
||||
if (typeof func !== 'function') {
|
||||
throw new Error('throttle directive value must be a function')
|
||||
}
|
||||
|
||||
throttleFunction = throttle(func, wait, Object.assign({}, {}, options))
|
||||
throttleFunction = throttle(func, wait, Object.assign({}, {}, options))
|
||||
|
||||
on(el, trigger, throttleFunction)
|
||||
},
|
||||
beforeUnmount: (el, binding) => {
|
||||
const { trigger = 'click' } = binding.value
|
||||
on(el, trigger, throttleFunction)
|
||||
},
|
||||
beforeUnmount: (el, binding) => {
|
||||
const { trigger = 'click' } = binding.value
|
||||
|
||||
if (throttleFunction) {
|
||||
throttleFunction.cancel()
|
||||
off(el, trigger, throttleFunction)
|
||||
}
|
||||
if (throttleFunction) {
|
||||
throttleFunction.cancel()
|
||||
off(el, trigger, throttleFunction)
|
||||
}
|
||||
|
||||
throttleFunction = null
|
||||
},
|
||||
throttleFunction = null
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default throttleDirective
|
||||
|
@ -1,5 +1,10 @@
|
||||
import type { Directive } from 'vue'
|
||||
import type { App } from 'vue'
|
||||
|
||||
export type CustomDirectiveFC<T, K> = () => Directive<T, K>
|
||||
|
||||
export interface DirectiveModules extends Object {
|
||||
default: Directive
|
||||
default: CustomDirectiveFC<unknown, unknown>
|
||||
}
|
||||
|
||||
export type AppType = App<Element>
|
||||
|
33
src/main.ts
33
src/main.ts
@ -2,16 +2,31 @@ import App from './App'
|
||||
|
||||
import '@/styles/base.scss'
|
||||
|
||||
import 'virtual:svg-icons-register' // `vite-plugin-svg-icons` 脚本, 如果不使用此插件注释即可
|
||||
import 'virtual:svg-icons-register' // `vite-plugin-svg-icons` 脚本
|
||||
|
||||
import { setupRouter } from './router/index'
|
||||
import { setupStore } from './store/index'
|
||||
import { setupI18n } from './locales/index'
|
||||
import { setupDayjs } from './dayjs/index'
|
||||
import { setupDirective } from './directives/index'
|
||||
import { setupDirectives } from './directives/index'
|
||||
|
||||
import type { App as AppType } from 'vue'
|
||||
|
||||
/**
|
||||
*
|
||||
* @param inst vue instance
|
||||
*
|
||||
* 该方法注册所有模板插件
|
||||
* 注册时应该注意每个插件的加载顺序
|
||||
*/
|
||||
const setupPlugins = async (inst: AppType<Element>) => {
|
||||
await setupI18n(inst)
|
||||
await setupStore(inst)
|
||||
setupRouter(inst)
|
||||
setupDayjs()
|
||||
setupDirectives(inst)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* 普通应用注册方法
|
||||
@ -19,12 +34,7 @@ import type { App as AppType } from 'vue'
|
||||
const setupTemplate = async () => {
|
||||
const app = createApp(App)
|
||||
|
||||
await setupI18n(app)
|
||||
await setupStore(app)
|
||||
setupRouter(app)
|
||||
setupDayjs()
|
||||
setupDirective(app)
|
||||
|
||||
await setupPlugins(app)
|
||||
app.mount('#app')
|
||||
}
|
||||
|
||||
@ -39,11 +49,7 @@ const setupWujieTemplate = async () => {
|
||||
window.__WUJIE_MOUNT = async () => {
|
||||
instance = createApp(App)
|
||||
|
||||
await setupI18n(instance)
|
||||
await setupStore(instance)
|
||||
setupRouter(instance)
|
||||
setupDayjs()
|
||||
|
||||
await setupPlugins(instance)
|
||||
instance.mount('#app')
|
||||
}
|
||||
|
||||
@ -59,6 +65,7 @@ const setupWujieTemplate = async () => {
|
||||
* 如果此处需要作为微服务主应用使用, 则只需要执行 `setupTemplate` 方法即可
|
||||
* 如果项目启用无界微服务, 会自动识别并且启动以无界微服务方法启动该项目
|
||||
*
|
||||
* @example
|
||||
* 作为主应用
|
||||
* ----------------------------------------------------------------
|
||||
* # 示例
|
||||
|
@ -35,6 +35,7 @@
|
||||
"ignoreDeprecations": "5.0"
|
||||
},
|
||||
"include": [
|
||||
"./src/types/global.d.ts",
|
||||
"vite.config.ts",
|
||||
"vite-plugin/index.ts",
|
||||
"vite-plugin/type.ts",
|
||||
@ -44,6 +45,6 @@
|
||||
"components.d.ts",
|
||||
"auto-imports.d.ts",
|
||||
"src/**/*",
|
||||
"./src/types/global.d.ts"
|
||||
"./src/types/app.d.ts"
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user