Vue项目整合与优化

news2025/4/19 21:44:10

前几篇文章,我们讲述了 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) => {

    // 如果是非线上环境,不加载 VConsole
    if (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) {
    // 生成虚拟 DOM
    return 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.gz
                        filename: '[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 maps
    configureWebpack: {
        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.coloradmin.cn/o/2270092.html

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

相关文章

面向机器学习的Java库与平台

学习Java语言中与机器学习相关的各种库与平台&#xff0c;了解每个库的功能&#xff0c;以及可以用它 们解决的问题。  实现机器学习应用时需要具备的Java环境  Weka&#xff1a;一个通用的机器学习平台  Java机器学习库&#xff1a;一系列机器学习算法  Apache Mah…

SAP SD学习笔记24 - 赠品的两种形式 - 内增Bonus数量、外增Bonus数量

上一章讲了无偿出荷的内容。 SAP SD学习笔记23 - 无偿出荷&#xff08;免费交货&#xff09;与继续无偿出荷&#xff08;继续免费交货&#xff09;-CSDN博客 本章继续将SAP中赠品的两种形式&#xff1a; - 内增Bonus数量&#xff1a;Bonus数量包含在总数量当中&#xff0c;比…

Python跨年烟花

目录 系列文章 写在前面 技术需求 完整代码 下载代码 代码分析 1. 程序初始化与显示设置 2. 烟花类 (Firework) 3. 粒子类 (Particle) 4. 痕迹类 (Trail) 5. 烟花更新与显示 6. 主函数 (fire) 7. 游戏循环 8. 总结 注意事项 写在后面 系列文章 序号直达链接爱…

深入理解MemCache

随着互联网应用的飞速发展&#xff0c;动态Web应用的性能问题逐渐成为开发者关注的焦点。其中&#xff0c;数据库作为系统性能的关键瓶颈&#xff0c;在用户请求量急剧增加的情况下&#xff0c;往往难以快速响应用户需求。为了解决这一问题&#xff0c;缓存技术应运而生。MemCa…

webrtc 源码阅读 make_ref_counted模板函数用法

目录 1. 模板参数解析 1.1 typename T 1.2 typename... Args 1.3 typename std::enable_if::value, T>::type* nullptr 2. scoped_refptr 3. new RefCountedObject(std::forward(args)...); 4. 综合说明 5.在webrtc中的用法 5.1 peerConnectionFactory对象的构建过…

【MySQL】数据操作

数据操作 一、INSERT1、介绍2、语法3、语法介绍4、注意事项5、示例 二、插入否则更新1、介绍2、语法3、语法介绍4、示例 三、ROW_COUNT1、介绍2、示例 四、REPLACE1、介绍2、语法3、示例 五、UPDATE1、介绍2、语法3、示例 六、DELETE1、介绍2、语法3、语法介绍 七、TRUNCATE1、…

表单元素(标签)有哪些?

HTML 中的表单元素&#xff08;标签&#xff09;用于收集用户输入的数据&#xff0c;常见的有以下几种&#xff1a; 文本输入框 <input type"text">&#xff1a;用于单行文本输入&#xff0c;如用户名、密码等。可以通过设置maxlength属性限制输入字符数&…

基于W2605C语音识别合成芯片的智能语音交互闹钟方案-AI对话享受智能生活

随着科技的飞速发展&#xff0c;智能家居产品正逐步渗透到我们的日常生活中&#xff0c;其中智能闹钟作为时间管理的得力助手&#xff0c;也在不断进化。基于W2605C语音识别与语音合成芯片的智能语音交互闹钟&#xff0c;凭借其强大的联网能力、自动校时功能、实时天气获取、以…

机器学习中回归预测模型中常用四个评价指标MBE、MAE、RMSE、R2解释

在机器学习中&#xff0c;评估模型性能时常用的四个指标包括平均绝对误差&#xff08;Mean Absolute Error, MAE&#xff09;、均方误差&#xff08;Mean Squared Error, MSE&#xff09;、均方根误差&#xff08;Root Mean Squared Error, RMSE&#xff09;和决定系数&#xf…

Visual Studio 玩转 IntelliCode AI辅助开发

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…

超详细!一文搞定PID!嵌入式STM32-PID位置环和速度环

本文目录 一、知识点1. PID是什么&#xff1f;2. 积分限幅--用于限制无限累加的积分项3. 输出值限幅--用于任何pid的输出4. PID工程 二、各类PID1. 位置式PID&#xff08;用于位置环&#xff09;&#xff08;1&#xff09;公式&#xff08;2&#xff09;代码使用代码 2. 增量式…

直观解读 JuiceFS 的数据和元数据设计(一)

大家读完觉得有意义和帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 JuiceFS 高层架构与组件2 搭建极简 JuiceFS 集群 2.1 搭建元数据集群2.2 搭建对象存储&#xff08;MinIO&#xff09; 2.2.1 启动 MinIO server2.2.2 创建 bucket2.3 下载 juicefs 客户端2.4 创…

数据结构漫游记:静态双向链表

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…

【Web安全】文件写入漏洞 ASP 网页病毒模拟(文件写入漏洞+FilesystemObject)

【Web安全】文件写入漏洞 ASP 网页病毒模拟&#xff08;文件写入漏洞FilesystemObject&#xff09; 原理 文件写入漏洞 文件写入漏洞是指攻击者通过某种方式在服务器上创建或修改文件的漏洞。攻击者可以利用此漏洞在服务器上写入恶意代码或文件&#xff0c;从而实现进一步的…

【Unity3d】C#浮点数丢失精度问题

一、float、double浮点数丢失精度问题 Unity3D研究院之被坑了的浮点数的精度&#xff08;一百零三&#xff09; | 雨松MOMO程序研究院 https://segmentfault.com/a/1190000041768195?sortnewest 浮点数丢失精度问题是由于大部分浮点数在IEEE754规范下就是无法准确以二进制…

Browser Use:AI智能体自动化操作浏览器的开源工具

Browser Use:AI智能体自动化操作浏览器的开源工具 Browser Use 简介1. 安装所需依赖2. 生成openai密钥3. 编写代码4. 运行代码5. 部署与优化5.1 部署AI代理5.2 优化与扩展总结Browser Use 简介 browser-use是一个Python库,它能够帮助我们将AI代理与浏览器自动化操作结合起来;…

tcpdump指南(1)

大家读完觉得有意义记得关注和点赞&#xff01;&#xff01;&#xff01; tcpdump是一种在网络上转储流量的网络工具。 这篇文章服务器作为一些常用命令的指南。如需完整指南&#xff0c; 请参阅手册页&#xff0c;或在 Linux 计算机上。man tcpdump 1 基本选项 帮助摘要&#…

14. 日常算法

1. 面试题 02.04. 分割链表 题目来源 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。 class Solution { public:ListNo…

termux-boot安卓开机自动启动应用

termux安装 github 蓝奏云 v119.1 termux-boot安装 github 蓝奏云 v0.8.1 安装 给权限运行加锁后台 am启动应用命令 am start -n 包名/启动项获取包名和启动入口&#xff08;图中app为爱玩机工具箱&#xff09; 例 简黑时钟蓝奏云 包名com.hm.jhclock 桌面启动项com.hm.jh…

自从学会Git,感觉打开了一扇新大门

“同事让我用 Git 提交代码&#xff0c;我居然直接把项目文件压缩发过去了……”相信很多初学者都经历过类似的窘境。而当你真正掌握 Git 时&#xff0c;才会发现它就像一本魔法书&#xff0c;轻松解决代码管理的种种难题。 为什么 Git 能成为程序员的标配工具&#xff1f;它究…