mirror of
				https://github.com/soybeanjs/soybean-admin.git
				synced 2025-11-04 15:53:43 +08:00 
			
		
		
		
	feat(projects): 初始化加载效果:应用主题颜色
This commit is contained in:
		@@ -11,5 +11,4 @@ lib
 | 
			
		||||
/docs
 | 
			
		||||
.vscode
 | 
			
		||||
.local
 | 
			
		||||
index.html
 | 
			
		||||
!.env-config.ts
 | 
			
		||||
 
 | 
			
		||||
@@ -135,6 +135,7 @@ module.exports = {
 | 
			
		||||
    'no-shadow': 0,
 | 
			
		||||
    'no-unused-vars': 'off',
 | 
			
		||||
    'no-use-before-define': 'off',
 | 
			
		||||
    'vue/comment-directive': 0,
 | 
			
		||||
    'vue/multi-word-component-names': 0,
 | 
			
		||||
    '@typescript-eslint/ban-types': 'off',
 | 
			
		||||
    '@typescript-eslint/ban-ts-ignore': 'off',
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -23,3 +23,5 @@ dist-ssr
 | 
			
		||||
*.njsproj
 | 
			
		||||
*.sln
 | 
			
		||||
*.sw?
 | 
			
		||||
 | 
			
		||||
stats.html
 | 
			
		||||
 
 | 
			
		||||
@@ -15,5 +15,13 @@ module.exports = {
 | 
			
		||||
  requireConfig: false, // Require a 'prettierconfig' to format prettier
 | 
			
		||||
  stylelintIntegration: false, //不让prettier使用stylelint的代码格式进行校验
 | 
			
		||||
  trailingComma: 'none', // 在对象或数组最后一个元素后面是否加逗号(在ES5中加尾逗号)
 | 
			
		||||
  tslintIntegration: false // 不让prettier使用tslint的代码格式进行校验
 | 
			
		||||
}
 | 
			
		||||
  tslintIntegration: false, // 不让prettier使用tslint的代码格式进行校验
 | 
			
		||||
  overrides: [
 | 
			
		||||
    {
 | 
			
		||||
      files: '*.html',
 | 
			
		||||
      options: {
 | 
			
		||||
        parser: 'html'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								index.html
									
									
									
									
									
								
							@@ -4,10 +4,24 @@
 | 
			
		||||
    <meta charset="UTF-8" />
 | 
			
		||||
    <link rel="icon" href="/favicon.ico" />
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 | 
			
		||||
    <title>Vite App</title>
 | 
			
		||||
    <title><%= appName %></title>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="app"></div>
 | 
			
		||||
    <div id="appProvider" style="display: none"></div>
 | 
			
		||||
    <div id="app">
 | 
			
		||||
      <div class="fixed-center flex-col">
 | 
			
		||||
        <div id="loadingLogo" class="w-128px h-128px text-primary"></div>
 | 
			
		||||
        <div class="w-56px h-56px my-36px">
 | 
			
		||||
          <div class="relative h-full animate-spin">
 | 
			
		||||
            <div class="absolute-lt init-loading-spin"></div>
 | 
			
		||||
            <div class="absolute-lb init-loading-spin animate-delay-500"></div>
 | 
			
		||||
            <div class="absolute-rt init-loading-spin animate-delay-1000"></div>
 | 
			
		||||
            <div class="absolute-rb init-loading-spin animate-delay-1500"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <h2 class="text-28px font-medium text-[#646464]"><%= appTitle %></h2>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <script type="module" src="/src/main.ts"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 17 KiB  | 
							
								
								
									
										15
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/App.vue
									
									
									
									
									
								
							@@ -1,19 +1,10 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <n-config-provider :theme-overrides="theme.naiveThemeOverrides">
 | 
			
		||||
  <app-provider>
 | 
			
		||||
    <router-view />
 | 
			
		||||
  </n-config-provider>
 | 
			
		||||
  </app-provider>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { onMounted } from 'vue';
 | 
			
		||||
import { NConfigProvider } from 'naive-ui';
 | 
			
		||||
import { useThemeStore } from '@/store';
 | 
			
		||||
 | 
			
		||||
const theme = useThemeStore();
 | 
			
		||||
const { addThemeCssVarsToRoot } = useThemeStore();
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  addThemeCssVarsToRoot();
 | 
			
		||||
});
 | 
			
		||||
import AppProvider from './AppProvider.vue';
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped></style>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								src/AppProvider.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/AppProvider.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <n-config-provider :theme-overrides="theme.naiveThemeOverrides">
 | 
			
		||||
    <slot></slot>
 | 
			
		||||
  </n-config-provider>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { NConfigProvider } from 'naive-ui';
 | 
			
		||||
import { useThemeStore } from '@/store';
 | 
			
		||||
 | 
			
		||||
const theme = useThemeStore();
 | 
			
		||||
</script>
 | 
			
		||||
<style scoped></style>
 | 
			
		||||
							
								
								
									
										19
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/main.ts
									
									
									
									
									
								
							@@ -1,22 +1,29 @@
 | 
			
		||||
import { createApp } from 'vue';
 | 
			
		||||
import { setupAssets } from '@/plugins';
 | 
			
		||||
import { setupAssets, setupInitSvgLogo } from '@/plugins';
 | 
			
		||||
import { setupRouter } from '@/router';
 | 
			
		||||
import { setupStore } from '@/store';
 | 
			
		||||
import AppProvider from './AppProvider.vue';
 | 
			
		||||
import App from './App.vue';
 | 
			
		||||
 | 
			
		||||
async function setupApp() {
 | 
			
		||||
  const app = createApp(App);
 | 
			
		||||
  setupAssets();
 | 
			
		||||
 | 
			
		||||
  // 挂载全局状态
 | 
			
		||||
  // 挂载 appProvider 解决路由守卫,Axios中可使用,LoadingBar,Dialog,Message 等之类组件
 | 
			
		||||
  const appProvider = createApp(AppProvider);
 | 
			
		||||
  setupStore(appProvider);
 | 
			
		||||
  appProvider.mount('#appProvider');
 | 
			
		||||
 | 
			
		||||
  // 初始化加载的svg logo
 | 
			
		||||
  setupInitSvgLogo('#loadingLogo');
 | 
			
		||||
 | 
			
		||||
  const app = createApp(App);
 | 
			
		||||
  setupStore(app);
 | 
			
		||||
 | 
			
		||||
  // 挂载路由
 | 
			
		||||
  await setupRouter(app);
 | 
			
		||||
 | 
			
		||||
  // 路由准备就绪后挂载APP实例
 | 
			
		||||
  // 路由准备就绪后挂载 App
 | 
			
		||||
  app.mount('#app');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
setupAssets();
 | 
			
		||||
 | 
			
		||||
setupApp();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
import setupAssets from './assets';
 | 
			
		||||
import setupInitSvgLogo from './logo';
 | 
			
		||||
 | 
			
		||||
export { setupAssets };
 | 
			
		||||
export { setupAssets, setupInitSvgLogo };
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								src/plugins/logo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/plugins/logo.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
/** 初始化加载效果的svg格式logo */
 | 
			
		||||
export default function setupInitSvgLogo(id: string) {
 | 
			
		||||
  const svgStr = `<svg width="128px" height="128px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
 | 
			
		||||
	y="0px" viewBox="0 0 158.9 158.9" style="enable-background:new 0 0 158.9 158.9;" xml:space="preserve">
 | 
			
		||||
	<path style="fill:none" d="M0,158.9C0,106.3,0,53.7,0,1.1C0,0.2,0.2,0,1.1,0c52.2,0,104.5,0,156.7,0c0.9,0,1.1,0.2,1.1,1.1
 | 
			
		||||
	c0,52.2,0,104.5,0,156.7c0,0.9-0.2,1.1-1.1,1.1C105.2,158.8,52.6,158.8,0,158.9z" />
 | 
			
		||||
	<path style="fill:currentColor" d="M81.3,55.9c-0.1-11.7-2.9-22.5-9.4-32.4c-1-1.5-2.1-2.9-2.5-4.7c-0.7-3.4,0.9-6.9,4-8.6c3-1.7,6.8-1.2,9.3,1.2
 | 
			
		||||
	c2.4,2.6,4.4,5.6,5.9,8.8c4.7,8.9,7.6,18.6,8.4,28.6c1,12.5-0.7,25-5.2,36.7c-0.9,2.5-1.9,4.9-3,7.3c-0.3,0.4-0.3,1,0,1.4
 | 
			
		||||
	c9.6,13.3,21.8,23,37.8,27.2c6.4,1.7,13.1,2.3,19.7,1.6c4.2-0.4,7.9,2.7,8.4,6.9c0.7,4.3-2.3,8.3-6.6,9c0,0,0,0-0.1,0
 | 
			
		||||
	c-7.7,0.9-15.5,0.5-23-1.3c-13.9-3.1-26.7-10-36.9-19.9c-4.4-4.2-8.4-8.8-11.9-13.7c-0.5-0.8-1.4-1.2-2.3-1.1
 | 
			
		||||
	c-9.5,0.7-18.8,3.3-27.4,7.6c-11.6,6-20.7,14.6-26.4,26.4c-0.7,1.9-2,3.5-3.7,4.7c-2.9,1.7-6.6,1.5-9.2-0.7c-2.8-2.2-3.8-6-2.4-9.3
 | 
			
		||||
	c2.2-5.2,5.1-10.1,8.7-14.5c12.2-15.4,28.2-24.6,47.3-28.6c4-0.8,8.1-1.4,12.2-1.6c0.5,0,1-0.3,1.2-0.8c3.3-7.1,5.5-14.6,6.5-22.3
 | 
			
		||||
	C81.1,61.2,81.3,58.6,81.3,55.9z" />
 | 
			
		||||
	<path style="fill:currentColor" d="M136.3,108.3c-3.8-0.5-7.6-1.4-11.1-2.9c-7.7-2.8-14.4-7.5-19.7-13.8c-2.9-3.3-2.5-8.4,0.8-11.3
 | 
			
		||||
	c1.4-1.2,3.1-1.9,4.9-1.9c2.5-0.1,5,1,6.5,2.9c4.9,5.6,11.6,9.4,18.9,10.8c1.5,0.2,3.1,0.6,4.5,1.2c3.2,1.8,4.8,5.6,3.8,9.2
 | 
			
		||||
	C144,106.1,140.8,108.4,136.3,108.3z" />
 | 
			
		||||
	<path style="fill:currentColor" d="M55.7,33.3c3,0.2,5.6,2.2,6.6,5c2.2,5.4,3.4,11.2,3.6,17c0.3,5.9-0.6,11.7-2.5,17.3c-2,5.8-8.2,7.8-12.9,4.2
 | 
			
		||||
	c-2.6-2.2-3.6-5.8-2.4-9c1.4-4,1.9-8.2,1.7-12.4c-0.2-3.8-1-7.5-2.4-11C45.3,38.9,49.2,33.3,55.7,33.3z" />
 | 
			
		||||
	<path style="fill:currentColor" d="M77.9,126.6c0,3.9-2.8,7.2-6.7,7.9c-7.8,1.5-14.8,5.9-19.7,12.2c-2.7,3.5-7.6,4.2-11.2,1.6
 | 
			
		||||
	c-3.6-2.6-4.3-7.6-1.7-11.2c0.1-0.1,0.2-0.3,0.3-0.4c4.1-5.2,9.3-9.6,15.1-12.8c4.4-2.5,9.1-4.2,14-5.1
 | 
			
		||||
	C73.3,117.7,77.9,121.3,77.9,126.6z" />
 | 
			
		||||
</svg>
 | 
			
		||||
`;
 | 
			
		||||
  const appEl = document.querySelector(id);
 | 
			
		||||
  const div = document.createElement('div');
 | 
			
		||||
  div.innerHTML = svgStr;
 | 
			
		||||
  appEl?.appendChild(div);
 | 
			
		||||
}
 | 
			
		||||
@@ -25,8 +25,6 @@ interface ThemeStore {
 | 
			
		||||
  otherColor: ComputedRef<OtherColor>;
 | 
			
		||||
  /** naiveUI的主题配置 */
 | 
			
		||||
  naiveThemeOverrides: ComputedRef<GlobalThemeOverrides>;
 | 
			
		||||
  /** 添加css vars至html */
 | 
			
		||||
  addThemeCssVarsToRoot(): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ThemeVarsKeys = keyof Exclude<GlobalThemeOverrides['common'], undefined>;
 | 
			
		||||
@@ -64,23 +62,30 @@ export const useThemeStore = defineStore('theme-store', () => {
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  function addThemeCssVarsToRoot() {
 | 
			
		||||
    const updatedThemeVars = { ...themeVars.value };
 | 
			
		||||
    Object.assign(updatedThemeVars, naiveThemeOverrides.value.common);
 | 
			
		||||
  /** 添加css vars至html */
 | 
			
		||||
  function addThemeCssVarsToHtml() {
 | 
			
		||||
    if (document.documentElement.style.cssText) return;
 | 
			
		||||
 | 
			
		||||
    const updatedThemeVars = { ...themeVars.value, ...naiveThemeOverrides.value.common };
 | 
			
		||||
    const keys = Object.keys(updatedThemeVars) as ThemeVarsKeys[];
 | 
			
		||||
    const style: string[] = [];
 | 
			
		||||
    keys.forEach(key => {
 | 
			
		||||
      style.push(`--${kebabCase(key)}: ${updatedThemeVars[key]}`);
 | 
			
		||||
    });
 | 
			
		||||
    const styleStr = style.join(';');
 | 
			
		||||
    document.documentElement.style.cssText += styleStr;
 | 
			
		||||
    document.documentElement.style.cssText = styleStr;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function init() {
 | 
			
		||||
    addThemeCssVarsToHtml();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  init();
 | 
			
		||||
 | 
			
		||||
  const themeStore: ThemeStore = {
 | 
			
		||||
    themeColor,
 | 
			
		||||
    otherColor,
 | 
			
		||||
    naiveThemeOverrides,
 | 
			
		||||
    addThemeCssVarsToRoot
 | 
			
		||||
    naiveThemeOverrides
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return themeStore;
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,10 @@ export default defineConfig(configEnv => {
 | 
			
		||||
      host: '0.0.0.0',
 | 
			
		||||
      port: 3200,
 | 
			
		||||
      open: true
 | 
			
		||||
    },
 | 
			
		||||
    build: {
 | 
			
		||||
      brotliSize: false,
 | 
			
		||||
      sourcemap: false
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,8 @@ export default defineConfig({
 | 
			
		||||
    'fixed-br': 'fixed-rb',
 | 
			
		||||
    'fixed-center': 'fixed left-0 top-0 flex-center wh-full',
 | 
			
		||||
    'nowrap-hidden': 'whitespace-nowrap overflow-hidden',
 | 
			
		||||
    'ellipsis-text': 'nowrap-hidden overflow-ellipsis'
 | 
			
		||||
    'ellipsis-text': 'nowrap-hidden overflow-ellipsis',
 | 
			
		||||
    'init-loading-spin': 'w-16px h-16px bg-primary rounded-8px animate-pulse'
 | 
			
		||||
  },
 | 
			
		||||
  theme: {
 | 
			
		||||
    extend: {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user