【VUE】RuoYi-Vue3项目结构的分析
【VUE】RuoYi-Vue3项目结构的分析
- 1. 项目地址
- 2. RuoYi-Vue3项目结构
- 2.1 整体结构
- 2.2 package.json
- 2.2.1 🧾 基本信息
- 2.2.2 🔧 脚本命令(scripts)
- 2.2.3 🌍 仓库信息
- 2.2.4 📦 项目依赖(dependencies)
- 2.2.5 开发依赖(devDependencies)
- 2.2.6 🔧 scripts 字段详解
- 2.2.6.1 🚀 dev: 开发模式启动
- 🔧 示例:
- 本质上是运行:
- 2.2.6.2 🏗️ build:prod: 构建生产环境
- 🔧 示例:
- 2.2.6.3 build:stage: 构建预发布环境
- 🔧 示例:
- 2.2.6.4 👀 preview: 本地预览构建结果
- 🔧 步骤:
- 🧩 补充:环境变量文件示例
- 2.2.7 ✅ 总结
- 2.3 env文件
- 2.3.1🔹 VITE_APP_TITLE
- 2.3.2 🔹 VITE_APP_ENV
- 2.3.3 🔹 VITE_APP_BASE_API
- 2.4 index.html
- 2.4.1 🧱 基本结构
- 2.4.2 🔧 `<head>` 区域说明
- 2.4.3 🎨 加载动画样式说明
- 2.4.4 🚀 Vue 应用入口加载
- 📝 总结功能
- 2.5 vite.config.js
- 2.5.1 🔧 文件头部
- 📌 自定义 mode 怎么办?
- 2.5.2 🧩 主体配置(defineConfig)
- 2.5.3 📌 base 配置
- 2.5.3 🔌 plugins 插件配置
- 2.5.4 🧭 resolve 路径配置
- 2.5.5 🌐 server 开发服务器配置
- 2.5.6 🎨 css 配置(PostCSS 处理)
- 2.5.7 ✅ 总结一下
- 2.6 main.js
- 2.6.1 📝 代码结构解析:
- 2.6.1.1 创建 Vue 应用
- 2.6.1.2 引入第三方库和插件
- 2.6.1.3 引入全局样式
- 2.6.1.4 引入应用所需的功能模块
- 2.6.1.5 引入全局组件
- 2.6.1.6 全局方法挂载
- 2.6.1.7 全局组件注册
- 2.6.1.8 路由、状态管理、插件注册
- 2.6.1.9 注册自定义指令
- 2.6.1.10 ElementPlus 配置
- 2.6.1.11 挂载应用
- 2.6.1.12 📚 小结
- 2.7 settings.js
- 2.8 App.vue
- 2.8.1 模板部分` (<template>)`
- 2.8.2 脚本部分 `(<script setup>)`
- 2.8.3 整体结构与功能
- 2.9 permission.js
- 3. RuoYi-Vue3 api文件夹下的内容
1. 项目地址
见官方文档 https://doc.ruoyi.vip/ruoyi-vue/document/xmkz.html
2. RuoYi-Vue3项目结构
2.1 整体结构
2.2 package.json
{"name": "ruoyi","version": "3.8.9","description": "若依管理系统","author": "若依","license": "MIT","type": "module","scripts": {"dev": "vite","build:prod": "vite build","build:stage": "vite build --mode staging","preview": "vite preview"},"repository": {"type": "git","url": "https://gitee.com/y_project/RuoYi-Vue.git"},"dependencies": {"@element-plus/icons-vue": "2.3.1","@vueup/vue-quill": "1.2.0","@vueuse/core": "10.11.0","axios": "0.28.1","clipboard": "2.0.11","echarts": "5.5.1","element-plus": "2.7.6","file-saver": "2.0.5","fuse.js": "6.6.2","js-beautify": "1.14.11","js-cookie": "3.0.5","jsencrypt": "3.3.2","nprogress": "0.2.0","pinia": "2.1.7","splitpanes": "3.1.5","vue": "3.4.31","vue-cropper": "1.1.1","vue-router": "4.4.0","vuedraggable": "4.1.0"},"devDependencies": {"@vitejs/plugin-vue": "5.0.5","sass": "1.77.5","unplugin-auto-import": "0.17.6","unplugin-vue-setup-extend-plus": "1.0.1","vite": "5.3.2","vite-plugin-compression": "0.5.1","vite-plugin-svg-icons": "2.0.1"}
}
2.2.1 🧾 基本信息
"name": "ruoyi","version": "3.8.9","description": "若依管理系统","author": "若依","license": "MIT","type": "module",
2.2.2 🔧 脚本命令(scripts)
"scripts": {"dev": "vite","build:prod": "vite build","build:stage": "vite build --mode staging","preview": "vite preview"
}
2.2.3 🌍 仓库信息
"repository": {"type": "git","url": "https://gitee.com/y_project/RuoYi-Vue.git"
}
指向源码托管的 Git 仓库(Gitee 上的 RuoYi-Vue 项目)。
2.2.4 📦 项目依赖(dependencies)
这些是运行时依赖,项目运行时需要用到的库:
2.2.5 开发依赖(devDependencies)
这些是开发时用的工具和插件:
2.2.6 🔧 scripts 字段详解
"scripts": {"dev": "vite","build:prod": "vite build","build:stage": "vite build --mode staging","preview": "vite preview"
}
这些命令你可以通过终端运行,比如:
npm run dev
# 或者
yarn dev
2.2.6.1 🚀 dev: 开发模式启动
"dev": "vite"
- 启动开发服务器
- 默认监听 http://localhost:5173(可配置)
- 实时热更新(HMR)
- 使用 .env.development 配置文件(如果存在)
🔧 示例:
npm run dev
本质上是运行:
vite
2.2.6.2 🏗️ build:prod: 构建生产环境
"build:prod": "vite build"
-
打包生成生产环境的静态文件
-
输出目录:默认是 dist/
-
使用 .env.production 配置文件
-
会自动做:
-
Tree Shaking(移除无用代码)
-
压缩(JS/CSS/html)
-
资源版本化(加 hash)
🔧 示例:
npm run build:prod
📁 构建完成后,你可以部署 dist/ 到 Nginx、Apache、Node 服务器等。
2.2.6.3 build:stage: 构建预发布环境
"build:stage": "vite build --mode staging"
- 用于 预发布环境 构建
- 使用 .env.staging 环境变量文件
- 可以用于连接测试服务器或 UAT 环境
🔧 示例:
npm run build:stage
注意:Vite 会根据 --mode 参数加载对应.env.[mode]
配置文件,例如:
.env.staging
.env.production
2.2.6.4 👀 preview: 本地预览构建结果
"preview": "vite preview"
- 用来本地 预览打包后的项目
- 启动一个本地静态服务器,访问打包结果
- 不再是开发服务器!是查看最终构建效果。
🔧 步骤:
npm run build:prod
npm run preview
默认访问地址:http://localhost:4173
🧩 补充:环境变量文件示例
你可以在根目录创建多个 .env 文件来支持不同环境:
.env.development # 开发环境
.env.staging # 预发布环境
.env.production # 生产环境
这些文件里可以定义变量,比如:
VITE_APP_TITLE=RuoYi 管理后台
VITE_BASE_API=https://api.example.com
在代码中这样访问:
import.meta.env.VITE_APP_TITLE
2.2.7 ✅ 总结
这个 package.json 是 Vue 3 企业后台管理系统(若依前端)的核心配置文件,结合了:
- Vue 3 + Vite 的现代构建架构;
- Element Plus 提供强大的 UI 组件;
- Pinia 管理状态;
- 多种工具库(图表、剪贴板、富文本、拖拽等)提升开发效率;
- Vite 插件自动化构建优化。
2.3 env文件
.env.development
# 页面标题
VITE_APP_TITLE = 若依管理系统# 开发环境配置
VITE_APP_ENV = 'development'# 若依管理系统/开发环境
VITE_APP_BASE_API = '/dev-api'
2.3.1🔹 VITE_APP_TITLE
VITE_APP_TITLE = 若依管理系统
- 用于设置项目标题
- 可在
index.html
或 Vue 页面中使用,比如动态修改<title>
在 HTML 中使用(通过 Vite 的 HTML 插值语法):
<title><%= VITE_APP_TITLE %></title>
或者在 JS 中使用:
document.title = import.meta.env.VITE_APP_TITLE;
2.3.2 🔹 VITE_APP_ENV
VITE_APP_ENV = 'development'
- 表示当前运行的环境(开发、测试、生产等)
- 通常用于代码中进行环境判断:
if (import.meta.env.VITE_APP_ENV === 'development') {console.log('当前是开发环境');
}
⚠️ 注意:值中用的引号 ‘development’ 会被作为字符串一部分保留。更推荐写法是不加引号:
VITE_APP_ENV=development
2.3.3 🔹 VITE_APP_BASE_API
VITE_APP_BASE_API = '/dev-api'
- 设置请求 API 的基础路径
- 会用于 axios 或 fetch 等接口请求中
假设你这样配置 axios:
const service = axios.create({baseURL: import.meta.env.VITE_APP_BASE_API,
});
那么访问 /api/user/list
,实际发送的请求就是:
http://localhost:5173/dev-api/user/list
这通常结合 Vite 的代理配置 实现跨域转发,比如在 vite.config.js
中:
server: {proxy: {'/dev-api': {target: 'http://localhost:8080',changeOrigin: true,rewrite: path => path.replace(/^\/dev-api/, '')}}
}
这样前端写 /dev-api/user/list
,Vite 会自动代理请求到后端 /user/list
接口。
2.4 index.html
<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="renderer" content="webkit"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"><link rel="icon" href="/favicon.ico"><title>若依管理系统</title><!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]--><style>html,body,#app {height: 100%;margin: 0px;padding: 0px;}.chromeframe {margin: 0.2em 0;background: #ccc;color: #000;padding: 0.2em 0;}#loader-wrapper {position: fixed;top: 0;left: 0;width: 100%;height: 100%;z-index: 999999;}#loader {display: block;position: relative;left: 50%;top: 50%;width: 150px;height: 150px;margin: -75px 0 0 -75px;border-radius: 50%;border: 3px solid transparent;border-top-color: #FFF;-webkit-animation: spin 2s linear infinite;-ms-animation: spin 2s linear infinite;-moz-animation: spin 2s linear infinite;-o-animation: spin 2s linear infinite;animation: spin 2s linear infinite;z-index: 1001;}#loader:before {content: "";position: absolute;top: 5px;left: 5px;right: 5px;bottom: 5px;border-radius: 50%;border: 3px solid transparent;border-top-color: #FFF;-webkit-animation: spin 3s linear infinite;-moz-animation: spin 3s linear infinite;-o-animation: spin 3s linear infinite;-ms-animation: spin 3s linear infinite;animation: spin 3s linear infinite;}#loader:after {content: "";position: absolute;top: 15px;left: 15px;right: 15px;bottom: 15px;border-radius: 50%;border: 3px solid transparent;border-top-color: #FFF;-moz-animation: spin 1.5s linear infinite;-o-animation: spin 1.5s linear infinite;-ms-animation: spin 1.5s linear infinite;-webkit-animation: spin 1.5s linear infinite;animation: spin 1.5s linear infinite;}@-webkit-keyframes spin {0% {-webkit-transform: rotate(0deg);-ms-transform: rotate(0deg);transform: rotate(0deg);}100% {-webkit-transform: rotate(360deg);-ms-transform: rotate(360deg);transform: rotate(360deg);}}@keyframes spin {0% {-webkit-transform: rotate(0deg);-ms-transform: rotate(0deg);transform: rotate(0deg);}100% {-webkit-transform: rotate(360deg);-ms-transform: rotate(360deg);transform: rotate(360deg);}}#loader-wrapper .loader-section {position: fixed;top: 0;width: 51%;height: 100%;background: #7171C6;z-index: 1000;-webkit-transform: translateX(0);-ms-transform: translateX(0);transform: translateX(0);}#loader-wrapper .loader-section.section-left {left: 0;}#loader-wrapper .loader-section.section-right {right: 0;}.loaded #loader-wrapper .loader-section.section-left {-webkit-transform: translateX(-100%);-ms-transform: translateX(-100%);transform: translateX(-100%);-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);}.loaded #loader-wrapper .loader-section.section-right {-webkit-transform: translateX(100%);-ms-transform: translateX(100%);transform: translateX(100%);-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);}.loaded #loader {opacity: 0;-webkit-transition: all 0.3s ease-out;transition: all 0.3s ease-out;}.loaded #loader-wrapper {visibility: hidden;-webkit-transform: translateY(-100%);-ms-transform: translateY(-100%);transform: translateY(-100%);-webkit-transition: all 0.3s 1s ease-out;transition: all 0.3s 1s ease-out;}.no-js #loader-wrapper {display: none;}.no-js h1 {color: #222222;}#loader-wrapper .load_title {font-family: 'Open Sans';color: #FFF;font-size: 19px;width: 100%;text-align: center;z-index: 9999999999999;position: absolute;top: 60%;opacity: 1;line-height: 30px;}#loader-wrapper .load_title span {font-weight: normal;font-style: italic;font-size: 13px;color: #FFF;opacity: 0.5;}</style>
</head><body><div id="app"><div id="loader-wrapper"><div id="loader"></div><div class="loader-section section-left"></div><div class="loader-section section-right"></div><div class="load_title">正在加载系统资源,请耐心等待</div></div></div><script type="module" src="/src/main.js"></script>
</body></html>
index.html 是 Vue3 + Vite 项目的入口 HTML 文件,用于 定义页面结构、加载样式、初始化页面,并最终挂载 Vue 应用。 它是 Vite 应用的基础模板,加载完毕后会将 #app
替换为渲染好的 Vue 内容。
2.4.1 🧱 基本结构
<!DOCTYPE html>
<html>
<head> ... </head>
<body><div id="app"> ... </div><script type="module" src="/src/main.js"></script>
</body>
</html>
<!DOCTYPE html>
:声明文档类型为 HTML5。<div id="app">
:Vue 应用的挂载点,对应 main.js 中的createApp(App).mount('#app')
。<script type="module">
:使用 ES Module 加载入口文件src/main.js
。
2.4.2 🔧 <head>
区域说明
✅ 页面设置相关
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="/favicon.ico">
<title>若依管理系统</title>
- 设置页面字符编码、兼容性、渲染方式。
<meta viewport>
用于移动端响应式适配。<title>
设置网页标题(可以用环境变量动态设置)。favicon.ico
设置浏览器 tab 图标。
2.4.3 🎨 加载动画样式说明
整个 <style>
块实现了一个 加载中的页面动画效果,在 Vue 内容加载前提供视觉反馈。
<div id="loader-wrapper"><div id="loader"></div><div class="loader-section section-left"></div><div class="loader-section section-right"></div><div class="load_title">正在加载系统资源,请耐心等待</div>
</div>
这些元素组合在一起构成了一个炫酷的加载动画,包括:
样式细节
#loader
是核心旋转圈,通过多个:before、:after
层实现三层圈圈动画。.loaded
类会触发消失动画,表示 Vue 应用加载完成。.no-js
是备用样式:如果 JS 不可用,隐藏 loading。
2.4.4 🚀 Vue 应用入口加载
<script type="module" src="/src/main.js"></script>
- 启动 Vue 应用的入口文件。
- 一般内容类似于:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'createApp(App).use(router).use(store).mount('#app')
加载完成后,会替换掉 <div id="app">
内容,把整个 Vue 项目渲染进去。
📝 总结功能
2.5 vite.config.js
import { defineConfig, loadEnv } from 'vite'
import path from 'path'
import createVitePlugins from './vite/plugins'// https://vitejs.dev/config/
export default defineConfig(({ mode, command }) => {const env = loadEnv(mode, process.cwd())const { VITE_APP_ENV } = envreturn {// 部署生产环境和开发环境下的URL。// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。base: VITE_APP_ENV === 'production' ? '/' : '/',plugins: createVitePlugins(env, command === 'build'),resolve: {// https://cn.vitejs.dev/config/#resolve-aliasalias: {// 设置路径'~': path.resolve(__dirname, './'),// 设置别名'@': path.resolve(__dirname, './src')},// https://cn.vitejs.dev/config/#resolve-extensionsextensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']},// vite 相关配置server: {port: 80,host: true,open: true,proxy: {// https://cn.vitejs.dev/config/#server-proxy'/dev-api': {target: 'http://localhost:8080',changeOrigin: true,rewrite: (p) => p.replace(/^\/dev-api/, '')}}},//fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the filecss: {postcss: {plugins: [{postcssPlugin: 'internal:charset-removal',AtRule: {charset: (atRule) => {if (atRule.name === 'charset') {atRule.remove();}}}}]}}}
})
这份 vite.config.js
是 Vite 项目的核心配置文件,它配置了构建、开发服务器、路径别名、插件、代理、CSS处理等行为。 这个文件是 若依管理系统 Vue3 + Vite 版本 中的重要组成部分。
2.5.1 🔧 文件头部
import { defineConfig, loadEnv } from 'vite'
import path from 'path'
import createVitePlugins from './vite/plugins'
- defineConfig:Vite 提供的辅助函数,可以获得类型提示。
- loadEnv(mode, root):根据当前模式加载
.env.[mode]
文件内容。 loadEnv 是 Vite 官方提供的函数,不是你自己写的,也不是第三方包,它来自于 vite 包本身。执行npm run dev
那么mode === ‘development’
vite 命令(开发模式) ⇒ mode = ‘development’
vite build 命令(生产构建) ⇒ mode = ‘production’ - path:Node.js 内置模块,用于路径拼接。
- createVitePlugins:引入封装好的插件函数(如 AutoImport、SVG 图标、压缩等)。
📌 自定义 mode 怎么办?
如果你想用别的环境变量文件,比如 .env.staging
,你可以这样写:
vite --mode staging
或者:
"scripts": {"build:stage": "vite build --mode staging"
}对应的执行命令就是
npm run build:stage
2.5.2 🧩 主体配置(defineConfig)
export default defineConfig(({ mode, command }) => {const env = loadEnv(mode, process.cwd()) // 加载环境变量const { VITE_APP_ENV } = env
- mode:当前环境(如 development、production)。
- command:当前操作(如 serve 或 build)。
- 使用 loadEnv() 加载
.env.*
文件内容并解构出VITE_APP_ENV
。
2.5.3 📌 base 配置
base: VITE_APP_ENV === 'production' ? '/' : '/',
- 设置打包后资源的 公共路径
- 如果部署在子目录下,这里应该设置成 /子目录名/
- 若依项目默认设置为根路径 /
2.5.3 🔌 plugins 插件配置
plugins: createVitePlugins(env, command === 'build'),
- 使用封装好的插件加载器,传入环境变量和是否是构建命令
- 常见插件可能包括:
unplugin-auto-import 自动导入
vite-plugin-svg-icons SVG 图标支持
vite-plugin-compression gzip 压缩等
2.5.4 🧭 resolve 路径配置
resolve: {alias: {'~': path.resolve(__dirname, './'),'@': path.resolve(__dirname, './src')},extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
}
设置路径别名:
~
代表根路径@ 代表 src/ 目录
,方便引用文件- extensions:导入文件时可省略的后缀名(默认已经包含大部分常用的)
2.5.5 🌐 server 开发服务器配置
server: {port: 80,host: true,open: true,proxy: {'/dev-api': {target: 'http://localhost:8080',changeOrigin: true,rewrite: (p) => p.replace(/^\/dev-api/, '')}}
}
- port: 80:开发服务器端口,设置为 80
- host: true:支持使用 IP 访问(0.0.0.0)
- open: true:自动打开浏览器
- proxy:配置代理,解决开发环境跨域问题
- 请求 /dev-api/xxx 会被代理到 http://localhost:8080/xxx
2.5.6 🎨 css 配置(PostCSS 处理)
css: {postcss: {plugins: [{postcssPlugin: 'internal:charset-removal',AtRule: {charset: (atRule) => {if (atRule.name === 'charset') {atRule.remove()}}}}]}
}
- 作用:去除 CSS 中多余的
@charset
规则,避免构建时出现警告或错误:
warning: "@charset" must be the first rule in the file
- 些插件(比如 element-plus 的样式)可能导致这个问题,所以主动清理。
2.5.7 ✅ 总结一下
2.6 main.js
import { createApp } from 'vue'import Cookies from 'js-cookie'import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/dark/css-vars.css'
import locale from 'element-plus/es/locale/lang/zh-cn'import '@/assets/styles/index.scss' // global cssimport App from './App'
import store from './store'
import router from './router'
import directive from './directive' // directive// 注册指令
import plugins from './plugins' // plugins
import { download } from '@/utils/request'// svg图标
import 'virtual:svg-icons-register'
import SvgIcon from '@/components/SvgIcon'
import elementIcons from '@/components/SvgIcon/svgicon'import './permission' // permission controlimport { useDict } from '@/utils/dict'
import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi'// 分页组件
import Pagination from '@/components/Pagination'
// 自定义表格工具组件
import RightToolbar from '@/components/RightToolbar'
// 富文本组件
import Editor from "@/components/Editor"
// 文件上传组件
import FileUpload from "@/components/FileUpload"
// 图片上传组件
import ImageUpload from "@/components/ImageUpload"
// 图片预览组件
import ImagePreview from "@/components/ImagePreview"
// 字典标签组件
import DictTag from '@/components/DictTag'const app = createApp(App)// 全局方法挂载
app.config.globalProperties.useDict = useDict
app.config.globalProperties.download = download
app.config.globalProperties.parseTime = parseTime
app.config.globalProperties.resetForm = resetForm
app.config.globalProperties.handleTree = handleTree
app.config.globalProperties.addDateRange = addDateRange
app.config.globalProperties.selectDictLabel = selectDictLabel
app.config.globalProperties.selectDictLabels = selectDictLabels// 全局组件挂载
app.component('DictTag', DictTag)
app.component('Pagination', Pagination)
app.component('FileUpload', FileUpload)
app.component('ImageUpload', ImageUpload)
app.component('ImagePreview', ImagePreview)
app.component('RightToolbar', RightToolbar)
app.component('Editor', Editor)app.use(router)
app.use(store)
app.use(plugins)
app.use(elementIcons)
app.component('svg-icon', SvgIcon)directive(app)// 使用element-plus 并且设置全局的大小
app.use(ElementPlus, {locale: locale,// 支持 large、default、smallsize: Cookies.get('size') || 'default'
})app.mount('#app')
2.6.1 📝 代码结构解析:
2.6.1.1 创建 Vue 应用
import { createApp } from 'vue'
const app = createApp(App)
- createApp 是 Vue3 中用来创建应用实例的函数。
- App 是根组件,通常是 src/App.vue,它是整个应用的起始点。
2.6.1.2 引入第三方库和插件
import Cookies from 'js-cookie'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/dark/css-vars.css'
import locale from 'element-plus/es/locale/lang/zh-cn'
- Cookies:用于管理 cookies,例如获取当前主题、界面大小等。
- ElementPlus:UI 组件库,提供丰富的组件和样式,支持主题、国际化等功能。
- 通过 import 加载了 ElementPlus 的样式以及中文语言包。
2.6.1.3 引入全局样式
import '@/assets/styles/index.scss' // global css
- 这行代码引入了全局的样式文件,通常是用来定义应用级别的样式。
2.6.1.4 引入应用所需的功能模块
import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'
import './permission' // permission control
- store:Vuex 的状态管理(假设应用中使用了 Vuex)。
- router:Vue Router 路由配置。
- directive:自定义指令。
- plugins:应用的插件,如全局功能的注册(如事件总线等)。
- download:可能是封装好的下载方法,用于下载文件等。
2.6.1.5 引入全局组件
import SvgIcon from '@/components/SvgIcon'
import Pagination from '@/components/Pagination'
import RightToolbar from '@/components/RightToolbar'
import Editor from "@/components/Editor"
import FileUpload from "@/components/FileUpload"
import ImageUpload from "@/components/ImageUpload"
import ImagePreview from "@/components/ImagePreview"
import DictTag from '@/components/DictTag'
- 引入了一些自定义的全局组件,例如分页、富文本、文件上传、图片上传、字典标签等组件。
2.6.1.6 全局方法挂载
app.config.globalProperties.useDict = useDict
app.config.globalProperties.download = download
app.config.globalProperties.parseTime = parseTime
app.config.globalProperties.resetForm = resetForm
app.config.globalProperties.handleTree = handleTree
app.config.globalProperties.addDateRange = addDateRange
app.config.globalProperties.selectDictLabel = selectDictLabel
app.config.globalProperties.selectDictLabels = selectDictLabels
- 将一些工具函数挂载到 Vue 应用的全局属性上,方便在任何组件中访问。例如,useDict 是处理字典标签的方法,download 是下载方法等。
2.6.1.7 全局组件注册
app.component('DictTag', DictTag)
app.component('Pagination', Pagination)
app.component('FileUpload', FileUpload)
app.component('ImageUpload', ImageUpload)
app.component('ImagePreview', ImagePreview)
app.component('RightToolbar', RightToolbar)
app.component('Editor', Editor)
- 通过 app.component 注册全局组件,这样在整个应用中可以直接使用这些组件,而无需在每个单独的组件中引入。
2.6.1.8 路由、状态管理、插件注册
app.use(router)
app.use(store)
app.use(plugins)
app.use(elementIcons)
app.component('svg-icon', SvgIcon)
- app.use(router):注册路由,所有页面的导航和路由逻辑都通过 Vue Router 进行。
- app.use(store):注册 Vuex 状态管理,管理整个应用的状态。
- app.use(plugins):注册自定义插件(如应用的全局功能、插件等)。
- app.component(‘svg-icon’, SvgIcon):注册 SvgIcon 作为全局组件,以便在任何地方使用。
2.6.1.9 注册自定义指令
directive(app)
- directive 函数用于注册应用中的自定义指令。这些指令可以在整个项目中复用。
2.6.1.10 ElementPlus 配置
app.use(ElementPlus, {locale: locale,size: Cookies.get('size') || 'default'
})
- 通过 app.use(ElementPlus) 安装 ElementPlus UI 组件库,并配置语言和大小。
- 默认的界面大小是从 Cookies 中获取的,如果没有设置则使用 ‘default’。
2.6.1.11 挂载应用
- 最后,应用会被挂载到 HTML 中的 #app 元素上,表示 Vue 实例已经成功启动并渲染。
2.6.1.12 📚 小结
- main.js 主要是 Vue 3 应用的初始化文件,涉及到全局插件、组件、方法的注册和配置。
- 核心流程是:创建 Vue 应用 → 挂载全局资源(如路由、状态管理、UI 组件等) → 启动应用。
2.7 settings.js
settings.js
是一个配置文件,通常用于 Vue.js 或其他前端应用中, 集中管理一些全局的应用设置,如主题、显示的组件、错误日志等。 它的目的是使应用的配置更加灵活和易于管理。
export default {/*** 网页标题*/title: import.meta.env.VITE_APP_TITLE,/*** 侧边栏主题 深色主题theme-dark,浅色主题theme-light*/sideTheme: 'theme-dark',/*** 是否系统布局配置*/showSettings: true,/*** 是否显示顶部导航*/topNav: false,/*** 是否显示 tagsView*/tagsView: true,/*** 是否固定头部*/fixedHeader: false,/*** 是否显示logo*/sidebarLogo: true,/*** 是否显示动态标题*/dynamicTitle: false,/*** @type {string | array} 'production' | ['production', 'development']* @description Need show err logs component.* The default is only used in the production env* If you want to also use it in dev, you can pass ['production', 'development']*/errorLog: 'production'
}
2.8 App.vue
App.vue 是 Vue 3 应用的根组件,通常作为整个应用的入口。这个文件负责渲染主要的视图和组件,同时处理一些全局设置,如主题、布局等。
<template><router-view />
</template><script setup>
import useSettingsStore from '@/store/modules/settings'
import { handleThemeStyle } from '@/utils/theme'onMounted(() => {nextTick(() => {// 初始化主题样式handleThemeStyle(useSettingsStore().theme)})
})
</script>
2.8.1 模板部分 (<template>)
<template><router-view />
</template>
<router-view />
是 Vue Router 提供的一个占位符组件,它会渲染与当前路由匹配的组件。在单页面应用(SPA)中,router-view 就是路由展示的地方。每当路由变化时,router-view 会根据新的路径自动加载相应的组件。- 例如,假设路由是
/home
,当你导航到这个路径时,router-view
就会显示与/home
路径相关联的组件。
2.8.2 脚本部分 (<script setup>)
<script setup>
import useSettingsStore from '@/store/modules/settings'
import { handleThemeStyle } from '@/utils/theme'onMounted(() => {nextTick(() => {// 初始化主题样式handleThemeStyle(useSettingsStore().theme)})
})
</script>
-
import useSettingsStore from '@/store/modules/settings':
- 这里导入了一个自定义的 Vuex store 模块 settings,通过它来获取应用的设置,比如主题(theme)。
-
import { handleThemeStyle } from '@/utils/theme':
- 导入了一个工具函数 handleThemeStyle,它负责处理主题样式(如深色或浅色主题)。该函数会应用选定的主题样式。
-
onMounted():
onMounted
是 Vue 3 中的生命周期钩子,表示组件挂载到 DOM 后会执行这个回调函数。在这个函数中,使用了 nextTick 来确保 DOM 更新完成后再执行初始化操作。
-
nextTick():
- nextTick 是 Vue 提供的一个方法,用来在下次 DOM 更新循环结束后执行延迟回调。在这里,它确保在组件挂载完成并且 DOM 已经更新后,才去初始化主题样式。
-
handleThemeStyle(useSettingsStore().theme):
- 这行代码获取
settings store
中的 theme 值,并通过handleThemeStyle
函数来设置页面的主题样式。这是应用的主题初始化逻辑,确保页面在加载时使用正确的样式(如深色或浅色模式)。
- 这行代码获取
2.8.3 整体结构与功能
-
根组件:App.vue 是整个应用的根组件,它通过
<router-view />
加载并显示与当前路由匹配的组件。路由配置和组件内容的切换都由 Vue Router 来管理。 -
主题初始化:在 onMounted 钩子中,应用会读取 Vuex store 中的主题设置,并通过 handleThemeStyle 函数动态加载和应用相应的主题样式。这个过程确保了用户在使用应用时能够体验到一致的界面风格。
2.9 permission.js
import router from './router'
import { ElMessage } from 'element-plus'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import { isHttp, isPathMatch } from '@/utils/validate'
import { isRelogin } from '@/utils/request'
import useUserStore from '@/store/modules/user'
import useSettingsStore from '@/store/modules/settings'
import usePermissionStore from '@/store/modules/permission'NProgress.configure({ showSpinner: false })const whiteList = ['/login', '/register']const isWhiteList = (path) => {return whiteList.some(pattern => isPathMatch(pattern, path))
}router.beforeEach((to, from, next) => {NProgress.start()if (getToken()) {to.meta.title && useSettingsStore().setTitle(to.meta.title)/* has token*/if (to.path === '/login') {next({ path: '/' })NProgress.done()} else if (isWhiteList(to.path)) {next()} else {if (useUserStore().roles.length === 0) {isRelogin.show = true// 判断当前用户是否已拉取完user_info信息useUserStore().getInfo().then(() => {isRelogin.show = falseusePermissionStore().generateRoutes().then(accessRoutes => {// 根据roles权限生成可访问的路由表accessRoutes.forEach(route => {if (!isHttp(route.path)) {router.addRoute(route) // 动态添加可访问路由表}})next({ ...to, replace: true }) // hack方法 确保addRoutes已完成})}).catch(err => {useUserStore().logOut().then(() => {ElMessage.error(err)next({ path: '/' })})})} else {next()}}} else {// 没有tokenif (isWhiteList(to.path)) {// 在免登录白名单,直接进入next()} else {next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页NProgress.done()}}
})router.afterEach(() => {NProgress.done()
})
这个 permission.js 文件的主要作用是处理应用的路由权限控制。它确保:
- 未登录用户只能访问白名单中的路由。
- 已登录用户可以根据角色动态生成可访问的路由。
- 如果用户的角色信息尚未加载,会先拉取用户信息并根据角色生成动态路由。
- 页面加载时展示进度条,增强用户体验。
工作流:
- 有 Token:检查路由权限并动态加载角色相关的路由。
- 无 Token:引导用户进入登录页面,并在登录后重定向回原本访问的路径。
3. RuoYi-Vue3 api文件夹下的内容
api文件夹下都是访问后端服务的文件。比如
import request from '@/utils/request'// 查询缓存详细
export function getCache() {return request({url: '/monitor/cache',method: 'get'})
}// 查询缓存名称列表
export function listCacheName() {return request({url: '/monitor/cache/getNames',method: 'get'})
}// 查询缓存键名列表
export function listCacheKey(cacheName) {return request({url: '/monitor/cache/getKeys/' + cacheName,method: 'get'})
}// 查询缓存内容
export function getCacheValue(cacheName, cacheKey) {return request({url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey,method: 'get'})
}// 清理指定名称缓存
export function clearCacheName(cacheName) {return request({url: '/monitor/cache/clearCacheName/' + cacheName,method: 'delete'})
}// 清理指定键名缓存
export function clearCacheKey(cacheKey) {return request({url: '/monitor/cache/clearCacheKey/' + cacheKey,method: 'delete'})
}// 清理全部缓存
export function clearCacheAll() {return request({url: '/monitor/cache/clearCacheAll',method: 'delete'})
}
这个代码片段是使用 request 模块来进行缓存管理操作的 API 请求方法。它通过 HTTP 请求与后端服务器进行交互,以便对缓存数据进行查询和清理。下面是每个方法的解释:
- getCache:通过 GET 请求获取缓存的详细信息,访问 /monitor/cache 路径。
- listCacheName:通过 GET 请求获取缓存名称列表,访问 /monitor/cache/getNames 路径。
- listCacheKey:通过 GET 请求获取指定缓存名称下的键名列表。cacheName 是动态参数,传递给 URL 中,路径是 /monitor/cache/getKeys/{cacheName}。
- getCacheValue:通过 GET 请求获取指定缓存名称和缓存键名的内容。cacheName 和 cacheKey 是动态参数,路径是 /monitor/cache/getValue/{cacheName}/{cacheKey}。
- clearCacheName:通过 DELETE 请求清理指定缓存名称的缓存。cacheName 是动态参数,路径是 /monitor/cache/clearCacheName/{cacheName}。
- clearCacheKey:通过 DELETE 请求清理指定缓存键名的缓存。cacheKey 是动态参数,路径是 /monitor/cache/clearCacheKey/{cacheKey}。
- clearCacheAll:通过 DELETE 请求清理所有缓存,访问 /monitor/cache/clearCacheAll 路径。
- 这些方法为应用程序提供了对缓存的基本管理功能,包括查询缓存内容和清理缓存。
相关文章:
【VUE】RuoYi-Vue3项目结构的分析
【VUE】RuoYi-Vue3项目结构的分析 1. 项目地址2. RuoYi-Vue3项目结构2.1 整体结构2.2 package.json2.2.1 🧾 基本信息2.2.2 🔧 脚本命令(scripts)2.2.3 🌍 仓库信息2.2.4 📦 项目依赖(dependenc…...
libreoffice-help-common` 的版本(`24.8.5`)与官方源要求的版本(`24.2.7`)不一致
出现此错误的原因主要是软件包依赖冲突,具体分析如下: ### 主要原因 1. **软件源版本不匹配(国内和官方服务器版本有差距) 系统中可能启用了第三方软件源(如 PPA 或 backports 源),导致 lib…...
5.数据手册解读——共模电感
目录 1 共模电感的工作原理 2 核心参数解读 2.1 电气参数 2.2 阻抗特性 共模电感(Common mode Choke),也叫共模扼流圈,是在一个闭合磁环上对称绕制方向相反、匝数相同的线圈。理想的共模扼流圈对L(或N)与E之间的共模干扰具有抑…...
easy-poi 一对多导出
1. 需求: 某一列上下两行单元格A,B值一样且这两个单元格, 前面所有列对应单元格值一样的话, 就对A,B 两个单元格进行纵向合并单元格 1. 核心思路: 先对数据集的国家,省份,城市...... id 身份证进行排序…...
用C语言控制键盘上的方向键
各位同学,大家好!相信大家在学习C语言的过程中,都和我一样,经常使用scanf函数来接受字符,数字,这些标准输入信息,来实现自己设计的程序效果。 而我突然有一天(对就是今天)…...
第3课:状态管理与事件处理
第3课:状态管理与事件处理 学习目标 掌握useState Hook的使用理解组件事件处理机制实现表单输入与状态绑定完成任务添加功能原型 一、useState基础 1. 创建第一个状态 新建src/Counter.js: import { useState } from react;function Counter() {co…...
硬件工程师面试问题(五):蓝牙面试问题与详解
蓝牙技术作为物联网与智能设备的核心无线协议,其硬件设计能力直接影响产品连接稳定性、功耗及兼容性。面试是评估候选人射频电路设计、天线优化、协议栈调试等综合技能的关键环节,尤其在BLE低功耗设计、共存抗干扰等场景中,硬件工程师的实践经…...
leetcode4.寻找两个正序数组中的中位数
思路源于 LeetCode004-两个有序数组的中位数-最优算法代码讲解 基本思路是将两个数组看成一个数组,然后划分为两个部分,若为奇数左边部分个数多1,若为偶数左边部分等于右边部分个数。i表示数组1划分位置(i为4是索引4也表示i的左半…...
20250405在荣品的PRO-RK3566开发板使用Rockchip原厂的buildroot系统来适配gmac1
【暂时还没有解决让PRO-RK3566的eth0/gmac1开机就启动】 PRO-RK3566作为iperf服务器: rootrk3566-buildroot:/# ifconfig rootrk3566-buildroot:/# ifconfig -a rootrk3566-buildroot:/# ifconfig eth0 up rootrk3566-buildroot:/# ifconfig rootrk3566-buildroot:/…...
7. 记忆(Memory)机制:让AI拥有“短期记忆”与“长期记忆”
引言:当AI学会"记住你" 2025年某银行智能客服因无法记住用户身份,每次对话都要求重复验证,引发大量投诉。引入LangChain 记忆系统后,客户满意度提升62%。本文将基于MemorySaver与FAISS本地存储,教你构建符合…...
Chapter07_图像压缩编码
文章目录 图像压缩编码图像压缩编码基础图像压缩的基本概念信息相关信息冗余信源编码及其分类 图像编码模型信源编码器模型信源解码器模型 数字图像的信息熵信源符号码字平均长度信息熵信息量 变长编码费诺码霍夫曼编码 位平面编码格雷码 图像压缩编码 数字图像的压缩是指在满…...
网络安全之前端学习(css终章)
如大家所见,今天的文章就是css的最后一篇文章。那么话不多说,我们开始吧。本章内容比较杂,就是补充之前几章没讲到的。 关系选择器 之前我们讲到了很多选择器,这里补充一个关系选择器。 1.1后代选择器 后代选择器,…...
多线程代码案例 - 2
阻塞队列 阻塞队列,我们熟悉的概念是队列,即一种先进先出的数据结构。阻塞队列,就是基于普通队列做出的扩展。 特点 1. 线程安全的 2. 具有阻塞特性 (a)如果针对一个已经满了的队列进行入队列,此时入队操…...
Qt实现鼠标右键弹出弹窗退出
Qt鼠标右键弹出弹窗退出 1、鼠标右键实现1.1 重写鼠标点击事件1.2 添加头文件1.3 添加定义2、添加菜单2.1添加菜单头文件2.2创建菜单对象2.3 显示菜单 3、添加动作3.1添加动作资源文件3.2 添加头文件3.3 创建退出动作对象3.4菜单添加动作对象 4、在当前鼠标位置显示菜单4.1当前…...
AI绘画中的LoRa是什么?
Lora是一个多义词,根据不同的上下文可以指代多种事物。以下将详细介绍几种主要的含义: LoRa技术 LoRa(Long Range Radio)是一种低功耗广域网(LPWAN)无线通信技术,以其远距离、低功耗和低成本的特…...
LaTeX、KaTeX、Markdown 的用法
文章目录 1. LaTeX 用法概述1.1 LaTeX简介1.2 优点与应用场景2. LaTeX 基础语法2.1 文档结构2.2 文本格式化2.3 数学公式3. KaTeX 用法3.1 KaTeX简介3.2 基本使用方法3.2.1 引入KaTeX3.2.2 渲染数学公式3.2.3 自定义配置3.3 与LaTeX的兼容性4. Markdown 用法4.1 Markdown简介4.…...
Python 如何高效实现 PDF 内容差异对比
Python 如何高效实现 PDF 内容差异对比 1. 安装 PyMuPDF 库2. 获取 PDF 内容通过文件路径获取通过 URL 获取 3. 提取 PDF 每页信息4. 内容对比metadata 差异文本对比可视化对比 5. 提升对比效率通过哈希值快速判断页面是否相同早停机制多进程机制 6. 其他 最近有接触到 PDF 内容…...
JJJ:generic netlink例程分析
接嵌入式毕设、课设辅导、技术咨询,欢迎私信 完整代码:github代码仓链接 若想要和指定的generic netlink family通信,如: 994 static struct genl_family genl_ctrl __ro_after_init { // generic netlink子协议995 .module THIS_MODU…...
3D图像重建中Bundle Adjustment的推导与实现
介绍 捆集调整(Bundle Adjustment),也称为光束平差法,是一种利用来自多台相机的图像数据同时优化相机位置和姿态以及 3D 点位置的技术。该技术历史相当悠久,于 1958 年由 DC Brown1 首次提出。 最初这是美国空军正在进行的从航拍照片中恢复环境的研究,随着视觉SLAM和Sf…...
【代码模板】C语言如何修改文件权限?读写执行权限对应值是多少?(chmod(“./a.out“, 0741);bit 2 1 0表示 读 写 执行)
#include "stdio.h" #include "unistd.h"int main(int argc, char *argv[]) {if (chmod("./a.out", 0741) ! 0) {perror("Failed to set exec permission");return -1;}return 1; }0741中0是8进制,7是 0111, 4是…...
新版pycharm如何实现debug调试需要参数的python文件
在最顶上有这个选项 把鼠标移上去 点击号 选择python 具体长这样 名字随便取 script选择你要调试的python文件 脚本形参填入参数,如:--arg1 value1 --arg2 value2 点击应用确定 最后给文件打上断点,再点击调试按键,就可以调试了…...
赚钱模拟器-百宝库v0.1.1
#include<bits/stdc.h> #include<windows.h> using namespace std; int n,i,j; void welcome(); void zhuye(); void GAME(); int main(){welcome();zhuye();return 0; }void welcome(){cout<<"欢迎您使用更多资源-百宝库v0.1.1"<<endl;sys…...
实战打靶集锦-38-inclusiveness
文章目录 1. 主机发现2. 端口扫描&服务枚举3. 服务探查4.系统提权 靶机地址:https://download.vulnhub.com/inclusiveness/Inclusiveness.ova 1. 主机发现 目前只知道目标靶机在192.168.56.xx网段,通过如下的命令,看看这个网段上在线的主…...
01人工智能基础入门
一、AI应用场景和发展历程 1.1行业应用 1、deepdream图像生成、yolo目标检测 2、知识图谱、画风迁移 3、语音识别、计算机视觉 4、用户画像 5、百度人工智能布局 1.2发展历程 人工智能的发展经历了 3 个阶段: 1980年代是正式成形期,尚不具备影响力。 …...
SortedSet结构之用户积分实时榜单实战
Redis 中的SortedSet结构非常适合用于实现实时榜单的场景,它根据成员的分数自动进行排序,支持高效的添加、更新和查询操作。 SortedSet实时榜单的一些典型应用场景: 游戏中的玩家排行榜:在多人在线游戏中,使用 Sorte…...
C++_类和对象(上)
【本节目标】 面向过程和面向对象初步认识类的引入类的定义类的访问限定符及封装类的作用域.类的实例化类的对象大小的计算类成员函数的this指针 1. 面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过…...
vllm作为服务启动,无需额外编写sh文件,一步到位【Ubuntu】
看到网上有的vllm写法,需要额外建立一个.sh文件,还是不够简捷。这里提供一种直接编写service文件一步到位的写法: vi /etc/systemd/system/vllm.service [Unit] DescriptionvLLM Service Afternetwork.target[Service] Typesimple Userroot…...
Mathematics | Branch
注:本文为“遇见数学”翻译的 “数学分支概览” 两篇文章合辑。 数学世界的版图:主要分支概览(上) 原创 遇见数学 2025 年 04 月 03 日 12:02 河南 数学的分支(Areas of Mathematics) 在文艺复兴之前&am…...
8.5/Q1,Charls最新文章解读
文章题目:Associations of estimated glucose disposal rate with frailty progression: results from two prospective cohorts DOI:10.1186/s12933-025-02650-7 中文标题:估计葡萄糖处理率与虚弱进展的关系:两个前瞻性队列的结果…...
PCL学习(5)随机采样一致性算法RANSAC
一、RANSAC概念及作用 1.1 基本概念 RANSAC是一种鲁棒的参数估计方法,用于从包含大量异常值的数据中拟合数学模型。其核心思想是通过随机采样和迭代验证,找到最优的模型参数,避免异常值的干扰。 1.2 核心思想 随机采样:每次从数…...
app逆向专题一:如何下载app
app逆向专题一:如何下载app 一、打开豌豆荚官网 一、打开豌豆荚官网 打开豌豆荚官网豌豆荚,在右上角搜索框中输入要下载的app名称 依次点击搜索–查看–普通下载,即可将apk文件下载到本地电脑上。...
将 DataFrame 中某一列的列表拆分成多个独立的列的方式
要将 DataFrame 中某一列的列表拆分成多个独立的列,可以使用以下方法,具体取决于数据结构和需求: 场景示例 假设 DataFrame 中 genres 列存储的是列表(如 [drama, action]),目标是将每个列表元素拆分成多列…...
VUE+SPRINGBOOT+语音技术实现智能语音歌曲管理系统
语音控制歌曲的播放、暂停、增删改查 <template><div class"Music-container"><div style"margin: 10px 0"><!--检索部分--><el-input style"width: 200px;" placeholder"请输入歌曲名称"v-model"sen…...
安卓开发工程师-自定义 View
1. 如何创建一个简单的自定义 View? 创建自定义 View 的基本步骤如下: 继承 View 或其子类:自定义 View 可以继承自 View 或其他更具体的视图类(如 ImageView、Button 等)。重写构造方法:通常需要重写三个…...
Vue中权限控制的方案
文章目录 源码:一、页面级1.1、路由守卫1.2、动态路由 二、按钮级别2.1、通过v-if来判断2.2、通过组件包裹的方式来判断2.3、通过自定义指令的方式 三、接口级别 源码: https://gitee.com/liu-qiang-yyds/sysPermission 一、页面级 1.1、路由守卫 前端…...
磁盘分析工具合集:告别C盘焦虑!
今天李师傅带大家盘点五款硬盘空间分析利器,帮你精准定位那些"吃空间"的元凶,让C盘告别臃肿烦恼! 一、WizTree 这款NTFS磁盘的"透视眼"堪称效率典范。它通过直接读取硬盘主文件表(MFT)实现秒级扫描,1TB机械…...
硬件学习之器件篇-蜂鸣器
根据工作原理的不同,可以分为电磁式蜂鸣器和压电式蜂鸣器。 1、电磁式蜂鸣器 电磁式蜂鸣器根据内部是否有震荡源,又可以分为有源电磁式蜂鸣器和无源电磁式蜂鸣器。 1.1 外观区别 有源电磁式蜂鸣器从底部看是,是黑胶密封的。 无源电磁式蜂…...
紫檀博物馆一游与软件开发
今天去逛了中国紫檀博物馆,里边很多层展品,也有一些清代的古物,檀木,黄花梨木家具和各种摆件,馆主陈丽华女士也是发心复原、保留和弘扬中国的传统文化,和西游记唐僧扮演者迟成瑞先生一家。 每一件展品都精…...
Cribl 新建Datatype
Cribl 数据dataset 有个很重要的就是datatype, 下面来新建一下: 先看一下原来的datatype : 再点击Add Datatype: Rule...
开源 LLM 应用开发平台 Dify 全栈部署指南(Docker Compose 方案)
开源 LLM 应用开发平台 Dify 全栈部署指南(Docker Compose 方案) 一、部署环境要求与前置检查 1.1 硬件最低配置 组件要求CPU双核及以上内存4GB 及以上磁盘空间20GB 可用空间 1.2 系统兼容性验证 ✅ 官方支持系统: Ubuntu 20.04/22.04 L…...
医药档案区块链系统
1. 医生用户模块 目标用户:医护人员 核心功能: 检索档案:通过关键词或筛选条件快速定位患者健康档案。请求授权:向个人用户发起档案访问权限申请,需经对方确认。查看档案…...
Redis常见命令
(一)常见命令① 一、数据结构 二、通用命令 ①KEYS查询语句 pattern代表模板,有点像匹配表达式(不是正则),是redis的一种内置表达式,可以在里面使用通配符 底层存在一种模糊查询机制,效率并不高。当redis的数据量达到一定规模时(数百万上千万甚至更多),使用这种模糊查询机制会…...
Qt的window注册表读写以及删除
Qt的window注册表读写以及删除 1. 使用 QSettings(Qt推荐方式)基本操作关键点限制 2. 调用Windows原生API示例:创建/读取键值常用API注意事项 3. 高级场景(1) 递归删除键(2) 注册表权限修改 4. 安全性建议总结其他QT文章推荐 在Qt中操作Windo…...
纯css实现环形进度条
需要在中实现一个定制化的环形进度条,最终效果如图: 使用代码 <divclass"circular-progress":style"{--progress: nextProgress,--color: endSliderColor,--size: isFull ? 60rpx : 90rpx,}"><div class"inner-conte…...
20250405周赛-S
链接 A. 日历 我的: #include<bits/stdc.h> using namespace std; int n,d[105],ans; bool check(int x,int y){if(x<10){if(y<10){return xy;}else{return xy%10&&xy/10;}}else{if(y<10){return yx%10&&yx/10;}else{return y/10…...
某碰瓷国赛美赛,号称第三赛事的数模竞赛
首先我非常不能理解的就是怎么好意思自称第三赛事的呢?下面我们进行一个简单讨论,当然这里不对国赛和美赛进行讨论。首先我们来明确一点,比赛的含金量由什么来定?这个可能大家的评价指标可能不唯一,我通过DeepSeek选取…...
希象传屏下载
2025年4月5日,11~22℃ 免费软件,功能:手机、个人笔记本和智慧黑板可以双向控制。要求在同一网络下或者同一WiFi下。 目的:自己下载的时候比较方便。 1、希沃易官网 2、如何下载? 被投屏:接收端࿱…...
解决 PDF 难题:批量处理、文档清理与自由拆分合并
软件介绍 在日常办公与学习中,处理 PDF 文件常常让人头疼不已,不过别担心,今天有一款堪称神器的国产老牌 PDF 工具要分享给大家。它就是 PDF 补丁丁,凭借其强大功能,为大家排忧解难。 界面体验 初次打开 PDF 补丁丁&…...
SQL Server 2022 数据同步到 Elasticsearch 思考
公司的老项目了,采用的是sqlserver 2022作为数据卡做的,但是产品对接客户,发现对搜索的要求很高,尤其是全文检索,考虑到ES采用倒排所以效率上的优势和整体开发的成本,大佬们商量之后,果断的采用…...
基于Spark的哔哩哔哩舆情数据分析系统
【Spark】基于Spark的哔哩哔哩舆情数据分析系统 (完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 本项目基于Python和Django框架进行开发,为了便于广大用户针对舆情进行个性化分析处…...