Vue项目整合与优化

前几篇文章,我们讲述了 Vue 项目构建的整体流程,从无到有的实现了单页和多页应用的功能配置,但在实现的过程中不乏一些可以整合的功能点及可行性的优化方案,就像大楼造完需要进行最后的项目验收改进一样,有待我们进一步的去完善。

使用 alias 简化路径

使用 webpack 构建过 Vue 项目的读者应该知道 alias 的作用,我们可以使用它将复杂的文件路径定义成一个变量来访问。在不使用 alias 的项目中,我们引入文件的时候通常会去计算被引入文件对于引入它的文件的相对路径,比如像这样:

import HelloWorld from '../../../../HelloWorld.vue'

一旦相对层次结构较深,我们就很难去定位所引入文件的具体位置,其实这并不是我们应该操心的地方,完全可以交给 webpack 来进行处理。在原生的 webpack 配置中我们可以定义 alias 来解决这一问题:

const path = require('path');// 解析路径的函数
const resolve = dir => {return path.join(__dirname, dir); // 将当前目录与给定目录连接
}module.exports = {// 其他配置...resolve: {alias: {'@': resolve('src'), // 将 '@' 映射到 'src' 目录_lib: resolve('src/common'), // 将 '_lib' 映射到 'src/common' 目录_com: resolve('src/components'), // 将 '_com' 映射到 'src/components' 目录_img: resolve('src/images'), // 将 '_img' 映射到 'src/images' 目录_ser: resolve('src/services'), // 将 '_ser' 映射到 'src/services' 目录}},// 其他配置...
}

上方我们在 webpack resolve(解析)对象下配置 alias 对象的值,将常用的一些路径赋值给了我们自定义的变量,这样在配置了别名之后,可以在代码中使用这些别名来导入模块。:

import HelloWorld from '_com/HelloWorld.vue'

alias 对象:定义了一系列别名,这样在你的 JavaScript 或 Vue 文件中,你可以用简短的别名来引用相关目录,而不必使用相对路径

而在 CLI 3.x 中我们无法直接操作 webpack 的配置文件,我们需要通过 chainWebpack (在“Webpack在Vue CLI中的应用”中有较详细的解释)来进行间接修改,代码如下:

/* vue.config.js */
module.exports = {...chainWebpack: config => {config.resolve.alias.set('@', resolve('src')).set('_lib', resolve('src/common')).set('_com', resolve('src/components')).set('_img', resolve('src/images')).set('_ser', resolve('src/services'))},...
}

如果使用 VSCode,可以在 jsconfig.json tsconfig.json 中定义路径,以便编辑器能够识别这些别名:

{"compilerOptions": {"baseUrl": ".","paths": {"@/*": ["src/*"],"_lib/*": ["src/common/*"],"_com/*": ["src/components/*"],"_img/*": ["src/images/*"],"_ser/*": ["src/services/*"]}}

这样我们修改 webpack alias 来简化路径的优化就实现了。但是需要注意的是对于在样式及 html 模板中引用路径的简写时,前面需要加上 符,否则路径解析会失败,如:

.img {background: url('~_img/home.png'); /* 使用 ~ 表示从别名中导入 */
}

拓展1

1.resolve 函数的作用

resolve 函数是一个常用的工具函数,通常用于将相对路径转换为绝对路径。这个函数通过 path.join 方法,将当前文件的目录(由 __dirname 提供)与给定的目录名连接,从而生成一个绝对路径。

在上文的代码中:

const path = require('path');const resolve = dir => {return path.join(__dirname, dir); // 将当前目录与给定目录连接
};

dir:

  • 这是函数的参数,代表您希望连接的目录名。它可以是一个相对路径,相对于当前文件的目录

结合起来:

假设项目结构如下:

/my-project├── src│     ├── components│     └── services

可以在 config.js 中使用 resolve 函数来设置别名,如下所示:

const path = require('path');const resolve = dir => {return path.join(__dirname, dir);
};module.exports = {chainWebpack: config => {config.resolve.alias.set('@', resolve('src')) // 将 '@' 映射到 'src' 目录.set('_com', resolve('src/components')) // 将 '_com' 映射到 'src/components' 目录.set('_ser', resolve('src/services')); // 将 '_ser' 映射到 'src/services' 目录}
};

一旦设置了别名,就可以在项目中使用这些别名来导入模块,例如:

// 引入组件
import MyComponent from '_com/MyComponent.vue';// 引入服务
import MyService from '_ser/MyService';

2.使用 ~前缀的原因

当在样式表或 HTML 模板中引入资源时,如果希望使用 Webpack 的模块解析特性,需要在路径前加上 ~ 符号。这样做的目的有几个:

  1. 模块解析: ~ 符号告诉 Webpack 从 node_modules 或配置的别名目录中解析路径。这使得开发者可以方便地引用模块或资源,而不必使用相对路径。

  2. 避免路径错误: 当使用相对路径时,可能会因为文件位置的变化导致路径失效。而使用 ~ 前缀能够确保路径正确,即使文件位置发生变化。

这里简单的举个例子

在 CSS 文件中

.img {background: url('~_img/home.png'); /* 正确:使用 ~ 前缀 */
}

在 HTML 模板中

如果使用 Vue、React 或其他框架的模板文件,也需要使用 ~ 符号来引入样式或资源:

<template><div class="img" style="background-image: url('~_img/home.png');"></div>
</template>

webpack.config.js

const path = require('path');module.exports = {resolve: {alias: {'_img': path.resolve(__dirname, 'src/images'), // 示例别名配置}}
};
  • 没有 ~ 的情况: 如果在路径前面不加 ~,Webpack 将会尝试从当前文件位置的相对路径进行解析,这可能会导致找不到文件的错误。

整合功能模块

在多页应用的构建中,由于存在多个入口文件,因此会出现重复书写相同入口配置的情况,这样对于后期的修改和维护都不是特别友好,需要修改所有入口文件的相同配置,比如在 index 单页的入口中我们引用了 VConsole 及 performance 的配置,同时在 Vue 实例上还添加了 $openRouter 方法:

import Vue from 'vue'
import App from './index.vue'
import router from './router'
import store from '@/store/'
import { Navigator } from '../../common'// 如果是非线上环境,不加载 VConsole
if (process.env.NODE_ENV !== 'production') {var VConsole = require('vconsole/dist/vconsole.min.js');var vConsole = new VConsole();//启用 Vue.js 的性能监控功能,可以在 Chrome 开发者工具中查看组件渲染的性能分析Vue.config.performance = true;
}//将 Navigator.openRouter 方法挂载到 Vue 原型上
Vue.$openRouter = Vue.prototype.$openRouter = Navigator.openRouter;new Vue({router,store,render: h => h(App)
}).$mount('#app')

 而在 page1 和 page2 的入口文件中也同样进行了上述配置,那我们该如何整合这些重复代码,使其能够实现一次修改多处生效的功能呢?最简单的方法便是封装成一个共用方法来进行调用,这里我们可以在 common 文件夹下新建 entryConfig 文件夹用于放置入口文件中公共配置的封装,封装代码如下:

import { Navigator } from '../index'export default (Vue) => {// 如果是非线上环境,不加载 VConsoleif (process.env.NODE_ENV !== 'production') {var VConsole = require('vconsole/dist/vconsole.min.js');var vConsole = new VConsole();Vue.config.performance = true;}Vue.$openRouter = Vue.prototype.$openRouter = Navigator.openRouter;
}

上述代码我们向外暴露了一个函数,在调用它的入口文件中传入 Vue 实例作为参数即可实现内部功能的共用,我们可以将原本的入口文件简化为:

import Vue from 'vue'
import App from './index.vue'
import router from './router'
import store from '@/store/'
import entryConfig from '_lib/entryConfig/'// 调用公共方法加载配置
entryConfig(Vue)new Vue({router,store,render: h => h(App)// 使用 render 函数渲染 App 组件
}).$mount('#app')     // 将根实例挂载到 id 为 app 的 DOM 元素上

h createElement 的别名。render函数的这个用法是反应式的,并且它的结构相对简洁。

这样我们便完成了入口文件配置的整合,当然你还可以给该函数传入 router 实例及自定义参数用于其他共用配置的封装。

拓展2

1.VConsole的作用

VConsole 是一个轻量级的移动端调试工具,主要用于在移动设备上调试 JavaScript 应用。它提供了一个可视化的控制台,让开发者能够轻松查看日志、网络请求、错误信息和其他调试信息,类似于浏览器开发者工具的控制台功能。

主要特性

  1. 日志记录: 您可以在 VConsole 中查看 console.log, console.error, console.warn, 和 console.info 等输出的日志信息。

  2. 网络请求监控: VConsole 能够捕获和显示应用发出的网络请求,包括请求的 URL、方法、状态码和响应时间等信息。

  3. 原生错误捕获: 捕获 JavaScript 运行时错误并在控制台中显示错误信息,方便调试。

  4. 元素查看: 可以查看和操作 DOM 元素的状态(在某些情况下)。

  5. 支持自定义功能: 开发者可以扩展 VConsole 的功能,添加自定义的面板和功能。

下面介绍它的基础用法

安装

要在项目中使用 vconsole,首先需要安装它。可以通过 npm 或 yarn 安装:

npm install vconsole && yarn add vconsole

然后,在应用中引入并实例化它:

import VConsole from 'vconsole';// 仅在开发环境中启用 VConsole
if (process.env.NODE_ENV !== 'production') {const vConsole = new VConsole();
}

简单的 VConsole 使用示例

import VConsole from 'vconsole';if (process.env.NODE_ENV !== 'production') {const vConsole = new VConsole(); // 实例化 VConsole
}// 示例日志
console.log('Hello, VConsole!');
console.error('This is an error message!');

2.render函数的详细介绍

1. render 函数的基本概念

在 Vue.js 中,render 函数是一种编程方式来描述组件如何生成虚拟 DOM。每当 Vue 组件的状态变化时,render 函数会被重新调用,生成新的虚拟 DOM,并与之前的虚拟 DOM 进行比较以实现高效的更新。

2. render 函数的结构

render 函数通常在 Vue 组件的定义中使用,基本的形式如下:

export default {render(createElement) {// 生成虚拟 DOMreturn createElement('div', 'Hello, World!');}
}
  • createElement: 是一个函数,用于创建虚拟节点(VNode)。该函数是 Vue 内部实现的一部分。
3. 创建虚拟节点(VNode)

虚拟节点是 Vue 用来描述底层 DOM 的数据结构。通过 createElement,可以创建不同类型的节点:

3.1. 创建 HTML 元素

render(createElement) {return createElement('h1', 'Hello, World!');
}

3.2. 创建组件

import MyComponent from './MyComponent.vue';render(createElement) {return createElement(MyComponent);
}

3.3. 传递属性

可以传递属性和事件监听器给创建的元素或组件。属性可以通过一个对象传递,包含 attrspropson 等字段:

render(createElement) {return createElement('button', {attrs: {type: 'button',},on: {click: this.handleClick}}, 'Click Me');
}

3.4. 嵌套子元素

可以通过传递一个虚拟节点数组来创建嵌套的结构:

render(createElement) {return createElement('div', [createElement('h1', 'Title'),createElement('p', 'This is a paragraph.'),]);
}
4. 与模板语法的比较

虽然模板语法更常用,且更简洁,但 render 函数提供了更大的灵活性。

4.1. 逻辑复杂性

当需要在渲染过程中进行复杂的逻辑判断时,render 函数可以更容易地进行条件判断:

render(createElement) {return this.isLoggedIn? createElement('h1', 'Welcome back!'): createElement('h1', 'Please log in.');
}

4.2. 动态生成结构

在某些情况下,可能需要动态生成组件或元素,render 函数能够更好地处理这种情况:

javascript
render(createElement) {return this.items.map(item => createElement('li', item));
}
5. 支持 JSX

如果项目配置支持 JSX,可以使用 JSX 语法来编写 render 函数,使代码更简洁和可读:

render() {return (<div><h1>Hello, JSX!</h1><MyComponent /></div>);
}
6. 高级用法

6.1. 使用 Slots

如果组件支持插槽,可以在 render 函数中使用 this.$slots 来访问插槽内容:

javascript
render(createElement) {return createElement('div', this.$slots.default);
}

6.2. 具名插槽

具名插槽可以通过传递一个 vnode 数组来实现:

render(createElement) {return createElement('div', [createElement('header', this.$slots.header),createElement('main', this.$slots.default),createElement('footer', this.$slots.footer),]);
}

6.3. 动态组件

可以通过 is 属性来动态渲染不同的组件:

render(createElement) {return createElement('component', {props: { is: this.currentComponent }});
}
7. 性能优化
  • 函数式组件: 如果组件不需要维护状态,可以考虑使用函数式组件,这样可以减少开销。函数式组件的 render 函数无需 this,并且可以更高效地渲染。
export default {functional: true,render(createElement, context) {return createElement('div', context.children);}
}

开启 Gzip 压缩

在《webpack 在 CLI 3 中的应用》章节,我们介绍了 CLI 为我们内置的 webpack plugins,使用这些内置插件基本已经能够满足我们大多数项目的构建和优化,当然你仍然可以为项目添加自己想要的插件来实现一些差异化的功能,比如使用 compression-webpack-plugin 来开启 Gzip 压缩。在 vue.config.js 配置文件中,我们通过 configureWebpack 中返回一个对象来实现 plugins 的合并:

/* vue.config.js */
const isPro = process.env.NODE_ENV === 'production'module.exports = {...//使用configureWebpack 直接修改 Webpack 的配置。configureWebpack: config => {if (isPro) {return {plugins: [new CompressionWebpackPlugin({// 定义生成的压缩文件的名称。[path]表示原始文件的路径和 [query]是查询字符串。如果原始文件是 app.js,压缩后文件名将是 app.js.gzfilename: '[path].gz[query]',// 使用 gzip 压缩算法algorithm: 'gzip', // 正则表达式匹配需要被压缩的文件类型test: new RegExp('\\.(js|css)$'),// 只处理大于此大小的文件threshold: 10240,// 最小压缩比达到 0.8 时才会被压缩minRatio: 0.8,})]}}}...
}

上方我们通过在生产环境中增加 Gzip 压缩配置实现了打包后输出增加对应的 .gz 为后缀的文件,而由于我们配置项中配置的是只压缩大小超过 10240B(10kB)的 JS 及 CSS,因此不满足条件的文件不会进行 Gzip 压缩。

Gzip 压缩能在普通压缩的基础上再进行 50% 以上 的压缩,我们可以直接来看下控制台的输出对比图:

很明显,Gzip 压缩后的文件体积得到了很大程度的减小,这对于浏览器资源加载速度的提升起到了非常有效的帮助。但是需要注意的是访问 Gzip 压缩的文件需要服务端进行相应配置,以下是 Nginx Gzip 压缩的流程:

Nginx 开启 Gzip 压缩配置后,其会根据配置情况对指定的类型文件进行压缩,主要针对 JS 与 CSS 。如果文件路径中存在与原文件同名(加了个 .gz),Nginx 会获取 gz 文件,如果找不到,会主动进行 Gzip 压缩。

拓展3

除了本文中介绍的项目优化方法,还有哪些常见的优化手段?如何通过 Vue CLI 3 配置实现?

以下为我总结的一些常见的优化方法以及如何通过 Vue CLI 3 进行配置的示例:

1. 代码分割(Code Splitting)

目的:通过将应用程序的代码分成较小的块(chunk),实现按需加载,从而减少初始加载时间。

实现方法

  • Vue CLI 默认使用 Webpack,支持基于路由的代码分割。通过动态导入组件实现代码分割。

示例:

const Home = () => import('./views/Home.vue');
const About = () => import('./views/About.vue');
2. 懒加载(Lazy Loading)

目的:只在需要时加载某些组件或库,可以减少首次加载的内容

实现方法

  • 使用 Vue Router 的懒加载特性来实现路由组件的懒加载

示例:

javascript
const routes = [{path: '/home',component: () => import('./views/Home.vue')},{path: '/about',component: () => import('./views/About.vue')}
];
3. 生产模式下的性能优化

目的:确保在生产环境中应用最佳性能优化

实现方法

  • 确保在生产环境下构建时启用 Vue 的生产提示

vue.config.js 中:

module.exports = {productionSourceMap: false, // 不生成 source mapsconfigureWebpack: {optimization: {splitChunks: {chunks: 'all', // 对所有模块进行代码分割}}}
};
4. 图片优化

目的:减小图片的体积以加快页面加载

实现方法

  • 使用图像压缩工具(如 imagemin)在构建过程中优化图像

示例:


npm install imagemin-webpack-plugin --save-dev

vue.config.js 中:

const ImageminPlugin = require('imagemin-webpack-plugin').default;module.exports = {configureWebpack: {plugins: [new ImageminPlugin({test: /\.(jpe?g|png|gif|svg)$/i,pngquant: {quality: '95-100'}})]}
};
5. 使用 PWA(渐进式 Web 应用)

目的:通过增强用户体验,提供离线支持、快速加载速度等

实现方法

  • 使用 Vue CLI 的 PWA 插件

安装 PWA 插件:

vue add pwa

这将自动配置 vue.config.js 和其他必要的文件

6. HTTP/2 支持

目的:利用 HTTP/2 的多路复用特性,提高文件传输速度

实现方法

  • 确保你的服务器支持 HTTP/2,并配置相应的 SSL/TLS
7. 使用 CDN

目的:将静态资源托管在 CDN 上,加快加载速度

实现方法

  • 在 vue.config.js 中配置公共路径
module.exports = {publicPath: process.env.NODE_ENV === 'production' ? 'https://cdn.example.com/' : '/'
};
8. 监控性能

目的:通过监控应用性能,找出瓶颈并进行优化

实现方法

  • 使用工具如 Google Lighthouse、Webpack Bundle Analyzer 等

安装 webpack-bundle-analyzer

npm install --save-dev webpack-bundle-analyzer

vue.config.js 中配置:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = {configureWebpack: {plugins: [new BundleAnalyzerPlugin()]}
};
9. 使用 Tree Shaking

目的:去除未使用的代码以减小最终打包体积

实现方法

  • 确保在项目中使用 ES6 的模块导入语法,Webpack 会自动对未使用的代码进行剔除
10. 预加载和预获取

目的:提高资源的获取速度

实现方法

vue.config.js 中配置 html-webpack-plugin

const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {configureWebpack: {plugins: [new HtmlWebpackPlugin({// 其他选项preload: ['app.js'], // 预加载prefetch: ['vendor.js'] // 预获取})]}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python、R用深度学习神经网络组合预测优化能源消费总量时间序列预测及ARIMA、xgboost对比...

全文链接&#xff1a;https://tecdat.cn/?p38726 分析师&#xff1a;Qingxia Wang 在能源领域&#xff0c;精准预测能源消费总量对制定合理能源战略至关重要。当前&#xff0c;能源消费预测分析主要运用单一模型&#xff08;如灰色预测法、时间序列分析法等&#xff09;和组合…

STM32使用UART发送字符串与printf输出重定向

首先我们先看STM32F103C8T6的电路图 由图可知&#xff0c;其PA9和PA10引脚分别为UART的TX和RX(注意&#xff1a;这个电路图是错误的&#xff0c;应该是PA9是X而PA9是RX&#xff0c;我们看下图的官方文件可以看出)&#xff0c;那么接下来我们应该找到该引脚的定义是什么&#xf…

Kotlin在医疗大健康域的应用实例探究与编程剖析(下)

四、Kotlin医疗编程实例分析 4.1 移动医疗应用实例 4.1.1 患者健康监测应用 在当今数字化医疗时代,患者健康监测应用为人们提供了便捷的健康管理方式。利用Kotlin开发的患者健康监测应用,能够实时采集患者的各类生理数据,如心率、血压、血氧饱和度等,并通过直观的可视化…

探索数据之美,Plotly引领可视化新风尚

在数据如潮的今天&#xff0c;如何精准捕捉信息的脉搏&#xff0c;让数据说话&#xff1f;Plotly&#xff0c;这款强大的数据可视化工具&#xff0c;正以其卓越的性能和丰富的功能&#xff0c;成为数据分析师、科学家及工程师们的得力助手。 Plotly不仅仅是一个绘图库&#xf…

Redis 5设计与源码分析读书笔记

目录 引言Redis 5.0的新特性Redis源码概述Redis安装与调试 简单动态字符串数据结构基本操作创建字符串释放字符串拼接字符串扩容策略 其余API 本章小结兼容C语言字符串、保证二进制安全sdshdr5的特殊之处是什么SDS是如何扩容的 跳跃表简介跳跃表节点与结构跳跃表节点跳跃表结构…

Golang学习历程【第五篇 复合数据类型:数组切片】

Golang学习历程【第五篇 复合数据类型&#xff1a;数组&切片】 1. 数组&#xff08;Array&#xff09;1.1 数组的定义1.2 初始化数组1.3 数据的循环遍历1.4 多维数组 2. 切片&#xff08;Slice&#xff09;2.1 切片声明、初始化2.2 基于数组创建切片2.2 切片的长度(len)和容…

【Unity】 HTFramework框架(五十七)通过Tag、Layer批量搜索物体

更新日期&#xff1a;2024年12月30日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 问题再现通过Tag搜索物体&#xff08;SearchByTag&#xff09;打开SearchByTag窗口搜索标记指定Tag的所有物体批量修改Tag搜索Undefined状态的所有物体 …

基于feapder爬虫与flask前后端框架的天气数据可视化大屏

# 最近又到期末了&#xff0c;有需要的同学可以借鉴。 一、feapder爬虫 feapder是国产开发的新型爬虫框架&#xff0c;具有轻量且数据库操作方便、异常提醒等优秀特性。本次设计看来利用feapder进行爬虫操作&#xff0c;可以加快爬虫的速率&#xff0c;并且简化数据入库等操作…

PCL点云库入门——PCL库点云滤波算法之统计滤波(StatisticalOutlierRemoval)

1、算法原理 统计滤波算法是一种利用统计学原理对点云数据进行处理的方法。它主要通过计算点云中每个点的统计特性&#xff0c;如均值、方差等&#xff0c;来决定是否保留该点。算法首先会设定一个统计阈值&#xff0c;然后对点云中的每个点进行分析。如果一个点的统计特性与周…

CentOS7 解决ping:www.baidu.com 未知的名称或服务

CentOS7 解决ping&#xff1a;www.baidu.com“未知的名称或服务 在VM查看网络配置 查看虚拟网络编辑器 编辑网络配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33注意&#xff1a;不同机器的配置文件名可能不相同&#xff0c;通过 ip addr 命令查看 将 ONBOOT 从 no 改…

aws(学习笔记第二十一课) 开发lambda应用程序

aws(学习笔记第二十一课) 开发lambda应用程序 学习内容&#xff1a; lambda的整体概念开发lambda应用程序 1. lambda的整体概念 借助AWS Lambda&#xff0c;无需预置或管理服务器即可运行代码。只需为使用的计算时间付费。借助 Lambda&#xff0c;可以为几乎任何类型的应用进…

【Leetcode】3280. 将日期转换为二进制表示

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个字符串 date&#xff0c;它的格式为 yyyy-mm-dd&#xff0c;表示一个公历日期。 date 可以重写为二进制表示&#xff0c;只需要将年、月、日分别转换为对应的二进制表示&a…

docker compose部署kafka集群

先部署zookeeper集群&#xff0c;启动 参考&#xff1a;docker compose部署zookeeper集群-CSDN博客 再部署kafka集群 networks: net: external: true services: kafka1: restart: always image: wurstmeister/kafka:2.13_2.8.1 container_name: kafka1 …

拆解 | 公募REITs:发售上市流程及细节

Hi,围炉喝茶聊产品的新老朋友好,在国庆假期写了两篇有关公募REITs的文章,先简单回顾下,以达到温故知新的效果。 第一篇:一起探索:公募REITs,它从本质、背景、概念等维度较系统介绍了公募REITs,如:明明是“不动产基金”,为什么叫REITs?说到底,投资REITs的实质是什么…

作业:C高级:Day4

第一题 思维导图 第二题 test的指令(整数判断、字符串判断、文件判断) 结果 第三题 题目 终端输入一个C源文件名&#xff08;.c结尾&#xff09;判断文件是否有内容&#xff0c;如果没有内容删除文件&#xff0c;如果有内容编译并执行改文件。 代码 三种情形的结果&#xff1…

(推荐)【通用业务分发架构】1.业务分发 2.rpc调用 3.Event事件系统

一.Reflections和SpringUtil完成扫描包的(反射缓存) 二.id与class的映射泛型上下文(玩家是否登录&#xff0c;rpc调用SeqId&#xff0c;class类名)反射调用 1.netty层的 AccountMsgParam // 登录前 OnlineMsgParam // 登录后 SceneMsgParam // 发到场景层的 2.跨进程rpc调用的…

FristiLeaks_1.3靶场渗透

目录 环境搭建 开始渗透 扫一下存活&#xff08;也就是扫描一下靶机IP&#xff09; ​编辑 扫描端口 扫描服务 查看80端口 扫描一下目录 查看robots 再看一下images,没啥用 回头看主页面&#xff0c;说多喝点FRISTI&#xff0c;我们试试看 尝试admin和万能密码 查看源…

OpenCV的TickMeter计时类

OpenCV的TickMeter计时类 1. TickMeter是一个计时的类1.1 计算耗时1.2 计算循环的平均耗时和FPS1.3 function 2. 案例 1. TickMeter是一个计时的类 https://docs.opencv.org/4.x/d9/d6f/classcv_1_1TickMeter.html#details 1.1 计算耗时 TickMeter tm;tm.start();// do some…

logback之pattern详解以及源码分析

目录 &#xff08;一&#xff09;pattern关键字介绍 &#xff08;二&#xff09;源码分析 &#xff08;一&#xff09;pattern关键字介绍 %d或%date&#xff1a;表示日期&#xff0c;可配置格式化%d{yyyy-MM-dd HH:mm:ss} %r或%relative&#xff1a;也是日期&#xff0c;不过…

【专题】2024年出口跨境电商促销趋势白皮书报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p38722 在当今全球化加速演进、数字经济蓬勃发展的大背景下&#xff0c;跨境电商行业正以前所未有的态势重塑国际贸易格局&#xff0c;成为各方瞩目的焦点领域。 根据亚马逊发布的《2024年出口跨境电商促销趋势白皮书》&#xff0c;…