项目重构,从零开始搭建一套新的后台管理系统
背景
应公司发展需求,我决定重构公司的后台管理系统,从提出需求建议到现在的实施,期间花了将近半个月的时间,决定把这些都记录下来。
之前的后台管理系统实在是为了实现功能而实现的,没有考虑到后期的扩展性,也没有考虑到后期的维护性,所以我下定决心,向领导提出了重构的建议,经过领导的同意,我开始了重构的工作。
项目前身
之前的后台管理系统是基于ant design pro for vue
搭建的,我在开发的过程中,遇到了很多问题,比如:
1.项目功能模块没有统一规划。
2.项目的代码风格不统一,代码杂乱无章。
3.各种第三方库的依赖,有重复的,有无用的。
4.项目的目录结构不合理。
5.项目API接口没有统一规划。
6.项目的权限管理不明确,几乎无用。
7.等等等…
当我接手这个项目的时候,我开发了两个大的功能模块,讲道理我这两个功能模块应该是强关联之前的某些功能的;
但是因为这个项目就是为了满足当前的需求,根本就不给你扩展的机会,所以我开发的两个功能模块都是独立的,没有任何关联,造成了相当多的重复工作,但是又不得不重复。
这就导致了后期的维护成本很高,因为我要维护的东西太多了,而且这些东西都是没有关联的,所以我决定重构这个项目。
项目重构
重构是一件很大的事情,当我提出重构的建议时,是确定了我手头上的工作已经完结,后续没有多少工作,所以不要有想法就提,要考虑到后续的工作量以及工作的优先级。
项目规划
当我决定重构这个项目的时候,我就开始了项目的规划,在开始之前我向领导提出了我的想法;
领导肯定不会轻易的同意我的想法,所以我就开始整理项目当中的问题,写文档,画流程图,多次和领导沟通,最终领导同意了我的想法。
我在争取领导的意见做了下面的准备:
1.老项目的整体流程我走了一遍,找我我觉得不合理的地方,以及可以优化的地方。
2.整理项目的功能模块,以及功能模块之间的关系。
3.整理我心中对这个项目的优化建议以及后续的规划。
4.画出我心中优化后的项目功能模块的流程图。
5.写出我优化项目需要时间的估算。
6.制订项目的开发计划,以及开发的功能模块优先级。
上面的准备工作也是修修改改,大会小会开了很多次,最终的结果是领导同意了我的想法,我开始了项目的重构。
技术选型
在领导同意了我的想法之后,我就开始了项目重构前的准备,包括技术选型,项目的目录结构,以及项目的开发计划。
技术选型沿用了之前的技术栈,但是会对一些技术进行升级迭代;
1.脚手架由vue-cli
修改为vite
。
2.前端框架由vue2
修改为vue3
。
3.UI框架由ant-design-vue
修改为element-plus
。
4.状态管理由vuex
修改为pinia
。
5.路由由vue-router
修改为vue-router-next
。
除了上述这些技术的升级迭代之外,还会规划一些代码规范,以及项目的目录结构。
项目目录结构
项目的目录结构以及文件名的命名规范是非常重要的,因为这些都是团队协作的基础,当然我也不会去弄一个很复杂的目录结构或者特立独行的文件名命名规范,我会根据团队或者业界的一些规范来进行规划。
目录结构:
├── public
│ └──favicon.ico
├── src
│ ├── api # 接口请求
│ │ ├── index.js
│ │ └── user.js
│ ├── assets# 静态资源
│ │ └── logo.png
│ ├── components# 公共组件
│ │ └── Table # 表格组件
│ │ └── index.vue
│ ├── layout# 布局组件
| | ├── components
│ │ └── index.vue
│ ├── pages # 页面
│ │ ├── index
│ │ │ └── index.vue
│ │ └── login
│ │ └── index.vue
│ ├── router# 路由
│ │ ├── index.js
│ │ └── routes.js
│ ├── store # 状态管理
│ │ ├── index.js
│ │ └── modules
│ │ └── user.js
│ ├── styles# 样式
│ │ └── index.scss
│ ├── utils # 工具函数
│ │ ├── index.ts
│ │ └── request.ts
│ ├── App.vue# 入口组件
│ └── main.js# 入口文件
├── .editorconfig# 编辑器配置
├── .env.development # 开发环境变量
├── .env.production# 生产环境变量
├── .eslintrc.json # eslint配置
├── .gitignore # git忽略文件
|── index.html # 入口html文件
├── package.json # 依赖包
├── README.md# 项目说明
└── vite.config.js # vite配置
文件名命名规范:
1.文件名全部小写,多个单词用_
连接,如:user_info.js
。
2.组件命名大驼峰,如TableComponent
。
3.一个功能模块一个文件夹,文件夹名全部小写,入口文件为index.vue
。
4.公共组件放在components
文件夹下,页面组件放在对应的页面文件夹下。
5.公共样式放在styles
文件夹下,页面样式放在对应的页面文件夹下。
6.公共工具函数放在utils
文件夹下,页面工具函数放在对应的页面文件夹下。
7.所有的请求接口放在api
文件夹下,每个模块一个文件,入口文件为index.js
。
差不多久这么多吧,不需要那么严格,但是项目结构一定要整洁,不然后期维护起来会很麻烦。
项目实战
直接实战环节吧,不多说废话了。
因为我的项目已经都配置好了,后面的讲解可能跨度比较大,所以就不按照流程一步一步的来,这次直接一步到位。
首先附上我的package.json
文件,
{"name": "my-vue-app","private": true,"version": "0.0.0","type": "module","scripts": {"dev": "vite --mode development","build": "vite build --mode production","preview": "vite preview"},"dependencies": {"@vueuse/core": "^9.5.0","axios": "^1.1.3","element-plus": "^2.2.22","pinia": "^2.0.24","vue": "^3.2.41","vue-router": "^4.1.6"},"devDependencies": {"@babel/eslint-parser": "^7.19.1","@vitejs/plugin-legacy": "^2.3.1","@vitejs/plugin-vue": "^3.2.0","@vitejs/plugin-vue-jsx": "^2.1.1","consola": "^2.15.3","eslint": "^8.28.0","eslint-config-airbnb-base": "^15.0.0","eslint-plugin-import": "^2.26.0","eslint-plugin-vue": "^9.7.0","less": "^4.1.3","unplugin-vue-components": "^0.22.9","unplugin-vue-define-options": "^0.12.8","vite": "^3.2.3","vite-plugin-eslint": "^1.8.1","vite-plugin-style-import": "^2.0.0"}
}
项目初始化
我们使用vite
来初始化项目,根据官网的提示,不同版本的npm
安装命令不一样,直接上命令:
# npm 6.x
npm create vite@latest my-vue-app --template vue# npm 7+, extra double-dash is needed:
npm create vite@latest my-vue-app -- --template vue
安装完成后,进入项目目录,安装依赖,项目前期安装的并不用很多,就是vue
全家桶:
cd my-vue-appnpm install vue vue-router@4 pinia axios element-plus -S
安装完成之后,我们需要在main.js
中引入对应的依赖:
import {createApp} from "vue"; // 引入vue
import "./styles/index.less"; // 引入全局样式
import App from "./App.vue"; // 引入入口组件
import store from "./store"; // 引入状态管理
import router from "./router"; // 引入路由import ElementPlus from "element-plus"; // 引入element-plus
import "element-plus/dist/index.css"; // 引入element-plus样式
import * as ElementPlusIconsVue from '@element-plus/icons-vue' // 引入element-plus图标// 创建vue实例
const app = createApp(App); // 注册状态管理
app.use(store); // 注册路由
app.use(router); // 注册element-plus
app.use(ElementPlus);// 注册element-plus图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)
}// 挂载vue实例
app.mount("#app");
main.js
中的代码比较多,我们一个一个的实现。
引入全局样式
上面的
main.js
中,已经是全的了,所以后面讲的东西,都是在main.js
中的,就不会讲引入了。
我们在src
目录下新建一个styles
目录,然后在styles
目录下新建一个index.less
文件,这个就是全局样式文件,里面写入:
html, body {margin: 0;padding: 0;
}
引入状态管理
我们在src
目录下新建一个store
目录,然后在store
目录下新建一个index.js
文件,这个文件就是状态管理文件,里面写入:
import {createPinia} from "pinia";const pinia = createPinia();export default pinia;
引入路由
我们在src
目录下新建一个router
目录,然后在router
目录下新建一个index.js
文件,这个文件就是路由文件,里面写入:
import {createRouter, createWebHashHistory} from "vue-router";
import routes from "./routes";const router = createRouter({history: createWebHashHistory(),routes,
});export default router;
然后我们在router
目录下新建一个routes.js
文件,这个文件就是路由配置文件,里面写入:
import Layout from "@/layout/index.vue";const routes = [{path: "/",redirect: "/index",component: Layout,meta: {title: "首页",},children: [{path: "/index",name: "Index",component: () => import("@/pages/index/index.vue"),meta: {title: "首页",},}]},{path: "/login",name: "Login",meta: {title: "登录",keepAlive: true,requireAuth: false},component: () => import("@/pages/login/index.vue")},
];export default routes;
引入入口组件
这个在创建项目的时候,已经创建好了,所以不用再创建了。
我们在src
目录下的App.vue
文件,这个文件就是入口组件,里面写入:
<template><router-view/>
</template><script>
export default {name: "App",
};
</script><style lang="less" scoped>
</style>
布局组件
我们在src
目录下新建一个layout
目录,然后在layout
目录下新建一个Layout.vue
文件,这个文件就是布局组件,里面写入:
<template><el-container><el-aside width="260px"><right-panel/></el-aside><el-container><el-header height="64px"><header-panel/></el-header><el-main><router-view/></el-main></el-container></el-container>
</template><script>
import RightPanel from "@/components/RightPanel/index.vue";
import HeaderPanel from "@/components/HeaderPanel/index.vue";
export default {name: "Layout",components: {RightPanel,HeaderPanel}
};
</script><style lang="less" scoped>
</style>
右侧面板组件
我们在src
目录下新建一个components
目录,然后在components
目录下新建一个RightPanel
目录,然后在RightPanel
目录下新建一个index.vue
文件,这个文件就是右侧面板组件,里面写入:
<template><div class="right-panel-container"><el-menustyle="border: none;"background-color="#2a5eff"class="el-menu-vertical-demo"default-active="2"text-color="#fff"router><menu-item v-for="route in routes" :route="route" :key="route.path"/></el-menu></div>
</template><script setup>
import { defineComponent, computed } from "vue";
import MenuItem from "@/components/RightPanel/MenuItem.vue";
import routes from "@/router/routes.js";
defineComponent({components: {MenuItem}
});computed({routes: routes
});</script><style lang="less" scoped>.right-panel-container {width: 100%;height: 100vh;background-color: #2a5eff;color: #fff;overflow-y: auto;:deep(.el-menu .el-sub-menu.is-active .el-sub-menu__title),:deep(.el-menu .el-menu-item.is-active) {background-color: var(--el-menu-hover-bg-color);color: #52cca3;}:deep(.el-menu .el-menu-item.is-active) {border-left: 3px solid #52cca3;}:deep(.el-sub-menu .el-menu) {background-color: darken(#224bcc, 10%);}}.right-logo-container {display: flex;justify-content: center;align-items: center;height: 64px;.right-logo {height: 48px;display: flex;justify-content: center;align-items: center;margin: 0 8px;img {height: 48px;}}
}</style>
菜单组件
在RightPanel
目录下新建一个MenuItem.vue
文件,这个文件就是菜单组件,里面写入:
<template><el-sub-menu v-if="route.children && route.children.length > 0" :index="route.path"><template #title><span>{{ (route.meta || {title: route.path}).title }}</span></template><menu-itemv-for="item in route.children":route="item":key="item.path"/></el-sub-menu><el-menu-item :index="route.path" v-else><template #title><span>{{ (route.meta || {title: route.path}).title }}</span></template></el-menu-item>
</template><script setup>
import { defineProps } from "vue";defineProps({route: {type: Object,default: () => ({})},
});
</script><style scoped></style>
头部面板组件
在components
目录下新建一个HeaderPanel
目录,然后在HeaderPanel
目录下新建一个index.vue
文件,这个文件就是头部面板组件,里面写入:
<template>
<div class="header-panel-container"><div class="header-breadcrumb"><el-breadcrumb><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item><el-breadcrumb-item>活动管理</el-breadcrumb-item><el-breadcrumb-item>活动列表</el-breadcrumb-item><el-breadcrumb-item>活动详情</el-breadcrumb-item></el-breadcrumb></div><div class="header-operate"><el-icon><Bell /></el-icon><el-dropdown><span class="user-info"><el-avatar size="small" src="avatar.png"></el-avatar><span>admin</span><i class="el-icon-arrow-down el-icon--right"></i></span><template #dropdown><el-dropdown-menu><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item>切换账号</el-dropdown-item><el-dropdown-item>退出登录</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div>
</div>
</template><script>
export default {name: "HeaderPanel"
};
</script><style lang="less" scoped>
.header-panel-container {width: 100%;height: 100%;background-color: #fff;color: #333;display: flex;align-items: center;justify-content: space-between;padding: 0 20px;box-sizing: border-box;border-bottom: 1px solid #ebeef5;.header-operate {display: flex;align-items: center;justify-content: center;:deep(.el-icon) {font-size: 20px;color: #333;cursor: pointer;padding: 10px;}}.user-info {display: flex;align-items: center;justify-content: space-between;margin-left: 10px;cursor: pointer;span {margin-left: 10px;}}
}</style>
到此整个项目的基本框架就搭建完成了,以上是极简主义,没有多余的东西,只是一个最基本的框架,后面会慢慢完善。
vite 配置
上面的准备只是项目结构的搭建,还需要配置一下vite
,在项目根目录下新建一个vite.config.js
文件,里面写入:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import * as path from 'path';
import {createStyleImportPlugin,ElementPlusResolve,
} from 'vite-plugin-style-import'
import eslintPlugin from 'vite-plugin-eslint'
import vueJsx from '@vitejs/plugin-vue-jsx'
import legacy from '@vitejs/plugin-legacy'
import DefineOptions from 'unplugin-vue-define-options/vite'// https://vitejs.dev/config/
export default defineConfig({resolve: {//设置别名alias: {'@': path.resolve(__dirname, 'src')}},build: {target: 'es2015', // 默认 "modules"},plugins: [vue(),vueJsx({}),createStyleImportPlugin({resolves:[ElementPlusResolve()],libs: [// 如果没有你需要的resolve,可以在lib内直接写,也可以给我们提供PR{libraryName: 'element-plus',esModule: true,resolveStyle: (name) => {return `element-plus/lib/theme-chalk/${name}.css`},ensureStyleFile: true // 忽略文件是否存在, 导入不存在的CSS文件时防止错误。},],}),eslintPlugin({include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue']}),legacy({targets: ['defaults', 'not IE 11'],}),DefineOptions(),],server: {port: 8080, //启动端口hmr: {host: '127.0.0.1',port: 8080},// 设置 https 代理proxy: {'/api': {target: 'your https address',changeOrigin: true,rewrite: (path) => path.replace(/^/api/, '')}}}
});
别名配置
在resolve
中配置别名,这样在引入文件的时候就可以使用@
代替src
,比如:
export default defineConfig({resolve: {//设置别名alias: {'@': path.resolve(__dirname, 'src')}}
});
这样在引入文件的时候就可以使用@
代替src
,比如:
import HeaderPanel from '@/components/HeaderPanel.vue';
vue 插件
在plugins
中配置vue
插件,这样就可以在vue
文件中使用jsx
语法了,比如:
export default defineConfig({plugins: [vue(),vueJsx({}),]
});
依赖:@vitejs/plugin-vue
、@vitejs/plugin-vue-jsx
element-plus
在plugins
中配置element-plus
,这样就可以在vue
文件中使用element-plus
了,比如:
export default defineConfig({plugins: [createStyleImportPlugin({resolves:[ElementPlusResolve()],libs: [// 如果没有你需要的resolve,可以在lib内直接写,也可以给我们提供PR{libraryName: 'element-plus',esModule: true,resolveStyle: (name) => {return `element-plus/lib/theme-chalk/${name}.css`},ensureStyleFile: true // 忽略文件是否存在, 导入不存在的CSS文件时防止错误。},],}),]
});
依赖:element-plus
、vite-plugin-style-import
eslint
eslint
先需要初始化,执行npx eslint -init
,然后根据提示选择配置,最后在plugins
中配置eslint
,这样就可以在vue
文件中使用eslint
了,比如:
然后在plugins
中配置eslint
,这样就可以在vue
文件中使用eslint
了,比如:
export default defineConfig({plugins: [eslintPlugin({include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue']}),]
});
eslint
还需要配置eslintConfig
,在第一步的时候你应该已经自己选择好了,这里就不再赘述了,我的项目中是选择生成.eslintrc.js
文件,所以在项目根目录下会生成.eslintrc.json
文件。
依赖:vite-plugin-eslint
兼容性
在plugins
中配置legacy
,这样就可以在vue
文件中使用es6
语法了,比如:
export default defineConfig({plugins: [legacy({targets: ['defaults', 'not IE 11'],}),]
});
依赖:@vitejs/plugin-legacy
环境变量
环境变量不需要配置,直接在根目录下创建.env
文件,然后在vue
文件中使用process.env
就可以了,比如:
VTIE_APP_BASE_URL=http://localhost:8080
console.log(import.meta.env.VTIE_APP_BASE_URL);
注意:VITE_
是固定的,后面的APP_BASE_URL
是自定义的,可以随意命名,必须得带VITE_
前缀,否则会被忽略。
代理配置
在server
中配置代理,这样在开发环境中就可以使用代理,比如:
export default defineConfig({server: {port: 8080, //启动端口hmr: {host: '127.0.0.1',port: 8080},// 设置 https 代理proxy: {'/api': {target: 'your https address',changeOrigin: true,rewrite: (path) => path.replace(/^/api/, '')}}}
});
这样在开发环境中就可以使用代理。
打包配置
在build
中配置打包,这样在打包时就可以使用打包配置,比如:
export default defineConfig({build: {target: 'es2015', // 默认 "modules"},
});
这里指示vite
打包时使用es2015
语法,而不是es6
语法。
自此整个项目的配置就完成了,接下来就可以按照自己的需求进行开发了。
总结
根据实际情况来进行技术选型以及架构的搭建,这样才能更好的满足业务需求,提高开发效率。
我上面并没有上什么高级或者特别的技术,没有上TypeScript
,没有上prettier
,也没有规范提交的commitizen
;
如果是自己的项目,我随便玩我会考虑上,但是团队项目终究是要考虑团队的,它不是最好的,但是它是最合适的。
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享
相关文章:

项目重构,从零开始搭建一套新的后台管理系统
背景 应公司发展需求,我决定重构公司的后台管理系统,从提出需求建议到现在的实施,期间花了将近半个月的时间,决定把这些都记录下来。 之前的后台管理系统实在是为了实现功能而实现的,没有考虑到后期的扩展性…...

day20_Map
今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、比较器排序 三、Collections 四、Map 五、HashMap 六、TreeMap 零、 复习昨日 HashSet 不允许重复元素,无序 HashSet去重原理: 先比较hashco…...

localStorage和sessionStorage
目录 一、localStorage和SessionStorage在哪里,是什么 二、localStorage和sessionStorage区别 三、localStorage常用方法 四、sessionStorage常用方法 一、localStorage和SessionStorage在哪里,是什么 【1】在浏览器开发者工具的Application栏目里&…...

IP地址,子网掩码,网段 概念详解
文章目录1. 子网掩码1.1 子网掩码的概念及作用1.2 子网掩码的组成1.3 子网掩码的表示方法1.4 为什么要使用子网掩码?1.5 子网掩码的分类2. 子网掩码和IP地址的关系2.1 根据掩码确定网段IP地址是以 网络号和 主机号来标示网络上的主机的,我们把网络号相同…...

数影周报:动视暴雪疑似数据泄露,数据出境安全评估申报最新进展
本周看点:动视暴雪疑似员工敏感信息及游戏数据泄露;谷歌云计算部门:两名员工合用一个工位;数据出境安全评估申报最新进展;TikTok Shop东南亚商城在泰国和菲律宾公布;智己汽车获九大金融机构50亿元贷款签约.…...

Web安全最详细学习路线指南,从入门到入职(含书籍、工具包)
在这个圈子技术门类中,工作岗位主要有以下三个方向: 安全研发 安全研究:二进制方向 安全研究:网络渗透方向 下面逐一说明一下. 第一个方向:安全研发 你可以把网络安全理解成电商行业、教育行业等其他行业一样&#x…...

ChatGPT?听说Biying把它下架了
ChatGPT被玩疯了,开始放飞自我 ChatGPT版微软必应上线不到10天…就被网友玩坏了 先说这个词,放飞自我,什么东西才会放飞自我? 人放飞自我,人?你确定是人? 所以让我们来把上面的句子改写一下。…...

中电金信:金融数字化转型路在何方?这里有答案
近期,媒体大数网整合了业内10份研究报告,详解金融数字化转型的思路、方法与路径。其中「中国电子金融级数字底座“源启”白皮书」也被收录其中。让我们一同阅读文章,探究金融数字化转型相关问题的答案吧。 当前,金融科技正在回归…...

【Leedcode】数据结构中链表必备的面试题(第五期)
【Leedcode】数据结构中链表必备的面试题(第五期) 文章目录【Leedcode】数据结构中链表必备的面试题(第五期)1.题目2.思路图解(1)第一步:复制每一个结点,插入到原结点和下一个结点之…...

ECDH secp256k1 集成
在Android 原生api是不支持secp256k1算法的,所以要先集成以下库:implementation com.madgag.spongycastle:core:1.58.0.0compile com.madgag.spongycastle:prov:1.54.0.0compile com.madgag.spongycastle:pkix:1.54.0.0compile com.madgag.spongycastle:…...

工单模型的理解与应用
工单(任务单)模型的定义 工单模型是一种分派任务的方法,可以用来跟踪、评估和报告任务的完成情况。它通常用于针对特定目标的重复性任务或项目,以确保任务能够按时完成并符合期望的标准。 工单模型的基本流程为:提…...

Python年利率计算器【N日年化收益率】
现在有闲钱的人,按照聪明等级从低到高排序应该是钱买股票,一年利率约为-20%钱放银行活期,年利率约为0.3%钱放银行定期,一年利率约为1.5%钱放余额宝(支付宝)或零钱通(微信)࿰…...

3年测试拿8K,被校招来的实习生反超薪资,其实你在假装努力
最近朋友给我分享了一个他公司发生的事 大概的内容呢:公司一位工作3年的测试工资还没有新人高,对此怨气不小,她来公司辛辛苦苦三年,三年内迟到次数都不超过5次,每天都是按时上下班,工作也按量完成…...

因子分析计算权重
因子分析两类权重计算方法总结 案例背景 疫情爆发以来,越来越多的人为了避免线下与人接触,选择了线上购买生活必需品。网购虽然方便快捷,但是随着订单压力的增加,物流问题也随之出现,近期有很多卖家收到物流投诉的问题…...

国家调控油价预测案例+源码
项目git地址:https://github.com/Boris-2021/Oil-price-control-forecast 使用已知的历史数据:日期、汇率、布伦特、WTI、阿曼原油价格,预测下一个调价周期中的汽油、柴油零售限价的调价价格。 一. 需求 1.1 需求说明 使用已知的历史数据&a…...

Gephi快速入门
Gephi快速入门1. 导入文件(Import file)2. 布局(Layout)3. 排序(Ranking)4. 指标(Metrics)5. 标签(Label)6. 社区发现(Community detection&#…...

GitHub
什么是 Github?GitHub是一个面向开源及私有软件项目的托管平台,因为只支持Git作为唯一的版本库格式进行托管,故名GitHub。一、常用词Watch:观察。如果watch了一个项目,之后这个项目有更新,你会在第一时间收到该项目更…...

QT基础入门【调试篇】QT远程部署与调试嵌入式ARM开发板
目录 一、环境配置 1、根据开发板完成交叉编译链以及GDB的配置(因开发板而异)...

可观测性最佳实践|阿里云事件总线 EventBridge 最佳实践
本文介绍如何把阿里云事件总线 EventBridge 的内容接入观测云平台,通过观测云强大的统一汇聚能力轻松获取阿里云事件,实时追踪最新的数据信息。 背景信息 事件总线 EventBridge 是阿里云提供的一款无服务器事件总线服务,支持阿里云服务、自定…...

设计模式-行为型
设计模式-行为型 行为型设计模式主要用于软件运行时复杂的流程控制。包含:模板方法模式、策略模式、命令模式、职责链模式、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式和解释器模式 模板方法模式 在软件设计时,很多时候系…...

Salesforce大揭秘!SaaS鼻祖不为人知的那些事!
Salesforce的世界无疑是广阔的。自从创始人Marc Benioff于1999年创立公司以来,Salesforce一直在打破CRM领域的界限,改变销售、营销和技术的格局。 作为全球领先的B2B科技公司之一,Salesforce和硅谷里的其他企业一样,缔造着一个关…...

Oracle——物化视图
文章目录含义物化视图的语法物化视图的创建1、自动刷新的物化事务 ON COMMIT2、非自动刷新的物化视图 ON demand关于手动刷新物化视图的删除资料参考含义 什么是物化视图? 物化视图,通俗点说就是物理化的视图。 什么叫物理化? 将视图以表结构…...

ur3+robotiq 2f 140配置moveit
ur3robotiq 2f 140配置moveit 参考链接1 参考链接2 官方配置movit教程 搭建环境: ubuntu: 20.04 ros: Nonetic sensor: robotiq_ft300 gripper: robotiq_2f_140_gripper UR: UR3 reasense: D435i 通过下面几篇博客配置好了ur3、力传感器、robotiq夹爪…...

LDO 芯片烫手,问题出在哪里?
设计失误的一个电路,该电路是数字电路的电源,为图方便对12V直接通过线性电源芯片降压到5V: 图1:线性电源降压12V转5V 几块电路板打样好后,测试均发现AMS1117-5.0芯片烫手,负载电流100mA多,也满…...

零日漏洞发展格局及防御策略
在过去的一年半中, 在野利用的零日漏洞数量持续飙升 ,这些软件制造商尚不知晓的漏洞正在被国家行为体黑客组织和勒索软件团伙滥用。 今年上半年,Google Project Zero统计了近20个零日漏洞,其中 大部分针对微软、苹果和谷歌构建的…...

RabbitMQ 可用磁盘空间报警
概要当磁盘可用空间低于设定的值(默认50M),将触发警报,并阻塞所有生产者。这目标是为了避免填满整个磁盘,这将导致所有节点上的写入操作失败,并可能导致RabbitMQ停止服务。如何工作为了减少磁盘被填满的风险…...

Web前端学习:二
二一:文字font-size样式 font-size:**px 控制文字大小,可精准控制大小 默认样式medium,中等的 large,大一号 x-large,再大一号 xx-large,再大一号 small,小一号 <!DOCTYPE html…...

【第一章 计算机网络体系结构,标准化工作相关组织,性能指标,分层结构,OSI参考模型】
第一章 计算机网络体系结构,标准化工作相关组织,性能指标,分层结构,OSI参考模型 1.计算机网络: (1)概念: ①计算机网络是将一个分散的、具有独立功能的计算机系统,通过通…...

SpringIOC源码解析
Spring深度学习(一)——IOC的设计理念Spring的核心思想——IOCSpring流程图DEMO编写Spring IoC容器的加载过程实例化化容器:AnnotationConfigApplicationContext实例化建BeanDefinition读取器: AnnotatedBeanDefinitionReaderBean…...

【Jupyter Notebook的简单入门使用】
【Jupyter Notebook的简单入门使用】简单介绍安装与配置简单使用Markdown关闭简单介绍 Jupyter官网 Jupyter Notebook 介绍 简单来讲,它是一个网页应用,可以进行文档编写,甚至运行 py 代码等功能 安装与配置 下载合适版本的 python &#…...