细说前端模块化开发

article/2025/10/22 9:57:35

一、模块化概述

  • 模块化开发是当下最重要的前端开发范式之一。
  • 随着前端应用的日益复杂,我们的项目代码已经逐渐膨胀到了不得不花大量时间去管理的程度了。
  • 模块化就是一种最主流的代码组织方式,它通过把我们的复杂代码按照功能的不同,划分为不同的模块单独维护的这种方式,去提高我们的开发效率,降低维护成本。
  • 模块化只是思想,不包含具体实现。

二、模块化演变过程

Stage1 - 文件划分方式

具体做法:
将每个功能以及它相关的一些状态数据,单独存放到不同的文件当中,我们去约定每一个文件就是一个独立的模块。我们去使用这个模块,就是将这个模块引入到页面当中,然后直接调用模块中的成员(变量 / 函数)。一个script标签就对应一个模块,所有模块都在全局范围内工作。
在这里插入图片描述
缺点:

  • 污染全局作用域
  • 命名冲突问题
  • 无法管理模块依赖关系

早期模块化完全依靠约定。

Stage2 - 命名空间方式

具体做法:
我们约定每个模块只暴露一个全局的对象,我们所有的模块成员都挂载到这个全局对象下面。
在第一阶段的基础上,通过将每个模块「包裹」为一个全局对象的形式实现,有点类似于为模块内的成员添加了「命名空间」的感觉。
在这里插入图片描述
缺点:

  • 没有私有空间
  • 模块成员仍然可以在外部被访问/修改
  • 无法管理模块依赖关系

Stage3 - IIFE

具体做法:
使用立即执行函数的方式,去为我们的模块提供私有空间。将模块中每个成员都放在一个函数提供的私有作用域当中,对于需要暴露给外部的成员,我们可以通过挂载到全局对象上的这种方式去实现。确保了私有成员的安全。
有了私有成员的概念,私有成员只能在模块成员内通过闭包的形式访问。
在这里插入图片描述

Stage4 - 利用 IIFE 参数作为依赖声明使用

具体做法:
在第三阶段的基础上,利用立即执行函数的参数传递模块依赖项。
这使得每一个模块之间的关系变得更加明显。 在这里插入图片描述
以上四个阶段就是早期在没有工具和规范的情况下,通过约定的方式,对模块化的落地方式。

三、模块化规范

我们需要的是模块化标准+模块加载器。

CommonJS规范(nodeJS):

  • 一个文件就是一个模块
  • 每个模块都有单独的作用域
  • 通过module.exports导出成员
  • 通过require函数载入模块

CommonJS约定的是以同步模式加载模块,在浏览器端使用会导致效率低下。

AMD:(异步的模块定义规范)
Require.js实现了这个规范。
目前绝大多数的第三方库都支持AMD规范。

  • AMD使用起来相对复杂
  • 模块JS文件请求频繁

Sea.js+CMD
类似CommonJS规范,使用上跟Require.js差不多。

模块化标准规范

模块化的最佳实践:
在这里插入图片描述

ES Modules

通过给script添加type=module的属性,就可以以ES Module 的标准执行其中的JS代码。

 <script type="module">console.log('This is es module.');  //This is es module.</script>

ES Modules基本特性

  • ESM 自动采用严格模式,忽略 ‘use strict’
    <script>console.log(this);  //Window
    </script>
    <script type="module">console.log(this);  //undefined
    </script>
    
  • 每个 ES Module 都是运行在单独的私有作用域中
    <script type="module">var bar = 88console.log(bar);  //88
    </script>
    <script type="module">console.log(bar);  //Uncaught ReferenceError: bar is not defined
    </script>
    
  • ESM 是通过 CORS(服务端必须支持) 的方式请求外部 JS 模块的
    <script type="module" src="https://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <!-- Access to script at 'https://libs.baidu.com/jquery/2.0.0/jquery.min.js' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. -->
    <script type="module" src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
    <!-- 成功请求到 -->
    
  • ESM 的 script 标签会自动延迟执行脚本 (类似defer属性,等待网页渲染完成,再去执行脚本,这样不会阻塞页面元素的显示)
    <script type="module" src="demo.js"></script>
    <p>hello world</p>
    

ES Modules导入和导出

	//导出const bar = 'hello'export {bar}//导入import {foo} from './module.js'console.log(foo)

注意:

  • 导出的成员并不是一个字面量对象;导入的时候也不是解构,是固定语法
  • 导出时,并不是导出的成员的值,只是导出的成员的存放地址
  • 外部导入的成员是只读的,不可以修改

ES Modules导入的注意事项:

  • 导入模块路径(路径必须写完整,不能省略后缀名、相对路径/不可省略、可以使用绝对路径或者完整的URL)
    import { name, age } from './module.js'
    
  • 执行模块,并不提取其中的成员
    import {} form './module.js'
    import './module.js'  //简写法
    
  • 导入成员多
    import * as obj from './module.js'
    console.log(obj.name);
    
  • 动态导入模块
    import('./module.js').then(module => {console.log(module);
    })
    
  • 同时导入默认成员和命名成员
    //导出默认成员和命名成员
    export { name, age }
    export default 'default export'
    //导入默认成员和命名成员
    import { name, age, default as title } from './module.js'
    //简写
    import title, { name, age } from './module.js'
    

ES Modules导出导入成员:

// import { Button } from './button.js'
// import { Avatar } from './avatar.js'// export { Button, Avatar }//简化-导出导入成员方式
export { default as Button } from './button.js'
export { Avatar } from './avatar.js'

ES Modules浏览器环境Polyfill

<script nomodule src="https://unpkg.com/promise-polyfill@8.1.3/dist/polyfill.min.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/babel-browser-build.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js"></script>
<script type="module">import { foo } from './module.js'console.log(foo);
</script>

ES Modules in Node.js

import { foo, bar } from './module.mjs'
console.log(foo, bar);  //hello china//载入原生模块
import fs from 'fs'
fs.writeFileSync('./foo.txt', 'ES Module working')//系统内置模块兼容了 ESM 的提取成员方式
import { writeFileSync } from 'fs'
writeFileSync('./bar.txt', 'ES Module working')//载入第三方模块
import _ from 'lodash'
console.log(_.camelCase('ES Module'));  //esModule//不支持,因为第三方模块都是导出默认值
// import { camelCase } from 'lodash'
// console.log(camelCase('ES Module'));  //SyntaxError: The requested module 'lodash' does not provide an export named 'camelCase'//运行命令
// node --experimental-modules index.mjs

ES Modules in Node.js与CommonJS交互
注意事项:

  • ES Module中可以导入CommonJS模块
  • CommonJS中不能导入ES Module模块
  • CommonJS模块始终只会导出一个默认成员
  • 注意import不是解构导出对象

ES Modules in Node.js与CommonJS的差异
在这里插入图片描述

四、常用的模块化打包工具

引入模块化后,带来的新问题:

  • ES Modules存在环境兼容问题
  • 模块文件过多,网络请求频繁
  • 所有的前端资源都需要模块化

无容置疑,模块化是必要的。

预期的工具需要满足以下设想:

  • 新特性代码编译
    在这里插入图片描述
  • 模块化JavaScript打包
    在这里插入图片描述
  • 支持不同类型的资源模块在这里插入图片描述

模块打包工具-Webpack

打包工具解决的是前端整体的模块化,并不单指JavaScript模块化。

Webpack

  • 模块打包器
  • 模块加载器
  • 代码拆分
  • 资源模块

Webpack配置
Webpack 4 以后支持零配置方式直接启动打包,整个打包过程会按照约定将src/index.js作为打包的入口,最终打包结果会存放到dist/main.js中。
大多时候,我们需要自定义配置文件:在这里插入图片描述
Webpack资源模块加载
Webpack内部默认只会处理JavaScript文件,其他类型文件,我们需要去添加不同类型的loader。

const path = require('path')
module.exports = {mode: 'none',entry: './src/main.css',output: {filename: 'bundle.js',path: path.join(__dirname, 'dist')},module: {//其他类型文件加载器的规则配置rules: [{test: /.css$/,use: ['style-loader','css-loader']}]}
}

Loader是Webpack的核心特性,借助于Loader就可以加载任何类型的资源。

Webpack导入资源模块
Webpack建议我们在编写代码过程中,根据代码的需要动态导入资源,因为需要资源的不是应用,而是代码。在这里插入图片描述
JavaScript驱动了整个前端应用:

  • 逻辑合理,JS确实需要这些资源文件。
  • 确保上线资源不缺失,都是必要的。

Webpack文件资源加载器

用来加载图片、字体等资源文件。通过拷贝物理文件的形式去处理文件资源。
在这里插入图片描述

WebpackURL加载器
我们可以通过Data URLs形式去表示文件,如:
在这里插入图片描述
Data URLs是一种特殊的URL协议,可以用来直接去表示一个文件。传统URL要求服务器上有一个对应的文件,通过请求这个地址得到服务器上对应的这个文件。Data URLs是一种当前URL就可以直接去表示文件内容的方式,这种URL当中的文本就已经包含了文本的内容。使用这种URL时,就不会再去发送任何的HTTP请求。
在这里插入图片描述
在这里插入图片描述
加载器:url-loader

最佳实践:

  • 小文件使用Data URLs,减少请求次数
  • 大文件单独提取存放,提高加载速度

可配置:

rules:[{test: /.jpg$/,//use: 'url-loader'//'file-loader'use: {loader: 'url-loader',options: {limit: 10 * 1024 //10KB}}}
]
  • 超出10KB文件单独提取存放
  • 小于10KB文件转换为Data URLs嵌入代码中
  • 必须配合file-loader一起使用

Webpack常用加载器分类

  • 编译转换类 (如:css-loader)
  • 文件操作类 (如:file-loader)
  • 代码检查类 (如:eslint-loader)

Webpack处理ES2015
因为模块打包需要,所以Webpack默认就可以处理import和export,但是它并不能转换代码中其他的ES6特性。

  • Webpack只是打包工具
  • 加载器可以用来编译转换代码
rules: [{test: /.js$/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}}
]

Webpack加载资源的方式

  • 遵循ES Modules标准的import声明
  • 遵循CommonJS标准的require函数
  • 遵循AMD标准的define函数和require函数
  • *样式代码中的@import指令和url函数
  • *HTML代码中图片标签的src属性

Loader加载的非JavaScript也会触发资源加载,如样式中的@import指令和url函数,HTML代码中图片标签的src属性。

Webpack核心工作原理
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Loader机制是Webpack的核心。
Loader负责资源文件从输入到输出的转换。对于同一个资源可以依次使用多个Loader,管道概念。
Loader专注实现资源模块加载,Plugin解决其他自动化工作。
Webpack+Plugin,实现大多前端工程化工作。

Webpack插件

插件机制是Webpack当中另外一个核心特性,目标是增强Webpack自动化能力。
Loader专注实现资源模块加载,Plugin解决其他自动化工作。
相比Loader,Plugin拥有更宽的能力范围。
Plugin通过钩子机制实现,类似于web中的事件。
Webpack+Plugin,实现大多前端工程化工作。
Webpack

Webpack常用插件

  • clean-webpack-plugin: 自动清理输出目录
  • html-webpack-plugin: 自动生成HTML插件
  • copy-webpack-plugin:拷贝静态文件

Webpack开发一个插件
Webpack要求我们的插件必须是一个函数或者是一个包含apply方法的对象。

//移除Webpack注释的插件
class VioletPlugin {apply(compiler) {console.log('VioletPlugin 启动');compiler.hooks.emit.tap('VioletPlugin', compilation => {//compilation => 可以理解为此次打包的上下文for (const name in compilation.assets) {// console.log(name);// console.log(compilation.assets[name].source());if (name.endsWith('.js')) {const contents = compilation.assets[name].source()const withoutComments = contents.replace(/\/\*\*+\*\//g, '')compilation.assets[name] = {source: () => withoutComments,size: () => withoutComments.length}}}})}
}
//使用
plugins: [    new VioletPlugin()]

Webpack插件是通过在生命周期的钩子中挂载函数实现扩展。

Webpack开发体验
理想的开发环境:

  • 以HTTP Server运行
  • 自动编译+自动刷新
  • 提供Source Map支持

如何增强Webpack开发体验:

  • 实现自动编译(watch工作模式:监听文件变化,自动重新打包)
  • 实现自动刷新浏览器(希望编译规划自动刷新浏览器: BrowserSync。(操作上麻烦了,效率上降低了))
  • Webpack Dev Server:提供用于开发的HTTP Server,集成自动编译和自动刷新浏览器等功能。

Webpack Dev Server静态资源访问:Dev Server默认只会serve打包输出文件,只要是Webpack 输出的文件,都可以直接被访问,其他静态资源文件也需要serve。

Webpack配置Source Map
在webpack.config.js文件中添加devtool: ‘下表中的方式’。
在这里插入图片描述
devtool模式对比:

  • eval : 是否使用eval执行模块代码
  • cheap-source-map: 是否包含行信息
  • cheap-module-source-map: 是否能够得到Loader处理之前的源代码

Source Map会暴露源代码,建议生产模式选择none。

Webpack HMR体验

  • 实现页面不刷新的前提下,模块也可以及时更新。(模块热替换,热拔插)
  • 模块热替换:应用运行过程中实时替换某个模块,应用运行状态不受影响。
  • HMR是Webpack 中最强大的功能之一,极大程度的提高了开发者的工作效率。
  • HMR集成在webpack-dev-server中,运行方式:yarn webpack-dev-server --hot
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {mode: 'development',entry: './src/main.js',output: {filename: 'js/bundle.js'},devtool: 'source-map',devServer: {hot: true// hotOnly: true // 只使用 HMR,不会 fallback 到 live reloading},module: {rules: [{test: /\.css$/,use: ['style-loader','css-loader']},{test: /\.(png|jpe?g|gif)$/,use: 'file-loader'}]},plugins: [new HtmlWebpackPlugin({title: 'Webpack Tutorial',template: './src/index.html'}),new webpack.HotModuleReplacementPlugin()]
}
  • Webpack中的HMR并不可以开箱即用,需要手动处理模块热替换逻辑。
    (1.)JS模块热替换
import createEditor from './editor'
import background from './better.png'
import './global.css'const editor = createEditor()
document.body.appendChild(editor)const img = new Image()
img.src = background
document.body.appendChild(img)// ============ JS模块热替换 ============// console.log(createEditor)if (module.hot) {let lastEditor = editormodule.hot.accept('./editor', () => {// console.log('editor 模块更新了,需要这里手动处理热替换逻辑')// console.log(createEditor)const value = lastEditor.innerHTMLdocument.body.removeChild(lastEditor)const newEditor = createEditor()newEditor.innerHTML = valuedocument.body.appendChild(newEditor)lastEditor = newEditor})  
}

(2.)图片模块热替换

module.hot.accept('./better.png', () => {img.src = backgroundconsole.log(background)
})

Webpack 不同环境下的配置
生产环境注重运行效率,开发环境注重开发效率,webpack 4提供了mode属性。
创建 不同环境下的配置方式:

  • 配置文件根据环境不同导出不同配置(仅适用于中小型项目)
const webpack = require('webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')module.exports = (env, argv) => {const config = {mode: 'development',entry: './src/main.js',output: {filename: 'js/bundle.js'},devtool: 'cheap-eval-module-source-map',devServer: {hot: true,contentBase: 'public'},module: {rules: [{test: /\.css$/,use: ['style-loader','css-loader']},{test: /\.(png|jpe?g|gif)$/,use: {loader: 'file-loader',options: {outputPath: 'img',name: '[name].[ext]'}}}]},plugins: [new HtmlWebpackPlugin({title: 'Webpack Tutorial',template: './src/index.html'}),new webpack.HotModuleReplacementPlugin()]}if (env === 'production') {config.mode = 'production'config.devtool = falseconfig.plugins = [...config.plugins,new CleanWebpackPlugin(),new CopyWebpackPlugin(['public'])]}return config
}
  • 一个环境对应一个配置文件(适用于大型项目)
    运行:webpack --config webpack.prod.js
    在这里插入图片描述

Webpack DefinePlugin
为代码注入全局成员。process.env.NODE_ENV

const webpack = require('webpack')module.exports = {mode: 'none',entry: './src/main.js',output: {filename: 'bundle.js'},plugins: [new webpack.DefinePlugin({// 值要求的是一个代码片段API_BASE_URL: JSON.stringify('https://api.example.com')})]
}

Webpack Tree-shaking
[摇掉]代码中未引用部分。生产模式下会自动开启。
使用前提是必须是ES Modules,即由Webpack 打包的代码必须使用ESM。

module.exports = {mode: 'none',entry: './src/index.js',output: {filename: 'bundle.js'},optimization: {// 模块只导出被使用的成员,usedExports负责标记【枯树叶】usedExports: true,// 尽可能合并每一个模块到一个函数中concatenateModules: true,// 压缩输出结果,minimize负责【摇掉】【枯树叶】// minimize: true}
}

Webpack sideEffects
允许我们通过配置的方式去标识代码是否有副作用,从而为Tree-shaking提供更大的压缩空间。
副作用:模块执行时除了导出成员之外所作的事情。
sideEffects一般用于npm包标记是否有副作用。

module.exports = {mode: 'none',entry: './src/index.js',output: {filename: 'bundle.js'},module: {rules: [{test: /\.css$/,use: ['style-loader','css-loader']}]},optimization: {sideEffects: true}
}

Webpack 代码分割
所有代码最终都被打包到一起,bundle体积过大,应用使用时,并不是每个模块在启动时都是必要的,浪费流量和带宽,因此需要分包,按需加载。
Code Splitting:代码分包/代码分割
HTTP1.1本身缺陷:

  • 同域并行请求限制
  • 每次请求都会有一定的延迟
  • 请求的Header浪费带宽流量

目前,Webpack实现代码分割/分包的方式:

  • 多入口打包(一个页面对应一个打包入口,公共部分单独提取)在这里插入图片描述
  • 动态导入(按需加载:需要用到某个模块时,再加载这个模块。动态导入的模块会被自动分包)
    在这里插入图片描述

Webpack 输出文件名Hash
一般我们去部署前端的资源文件时,都会去启用服务器的静态资源缓存。
生产模式下,文件名使用Hash。

plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({title: 'Dynamic import',template: './src/index.html',filename: 'index.html'}),new MiniCssExtractPlugin({// filename: '[name]-[hash].bundle.css'  //项目级别Hashfilename: '[name]-[chunkhash].bundle.css'  //chunk级别// filename: '[name]-[contenthash:8].bundle.css'  //文件级别})]

模块打包工具-Rollup

Webpack大而全,Rollup小而美。
Rollup仅仅是一款ESM打包器,Rollup并不支持类似HMR这种高级特性。
Rollup初衷只是想提供一个充分利用ESM各项特性的高效打包器。

rollup和webpack的区别:

  • 特性:rollup 所有资源放同一个地方,一次性加载,利用 tree-shake特性来 剔除未使用的代码,减少冗余;webpack 拆分代码、按需加载 webpack2已经逐渐支持tree-shake
  • rollup:
    1.打包你的 js 文件的时候如果发现你的无用变量,会将其删掉。
    2.可以将你的 js 中的代码,编译成你想要的格式
  • webpack:
    1.代码拆分
    2.静态资源导入(如 js、css、图片、字体等)
    拥有如此强大的功能,所以 webpack 在进行资源打包的时候,就会产生很多冗余的代码。
  • 项目(特别是类库)只有 js,而没有其他的静态资源文件,使用 webpack 就有点大才小用了,因为 webpack bundle 文件的体积略大,运行略慢,可读性略低。这时候 rollup就是一种不错的解决方案
  • 对于应用使用 webpack,对于类库使用 Rollup

rollup基本用法
1.创建目录image.png
2.创建文件在这里插入图片描述
3.package.json配置项

{"name": "rollup_demo","version": "1.0.0","description": "","main": "rollup.config.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","rollup": "rollup -c rollup.config.js"},"keywords": [],"author": "","license": "ISC","devDependencies": {"babel-core": "^6.26.3","babel-plugin-external-helpers": "^6.22.0","babel-preset-env": "^1.7.0","babel-preset-latest": "^6.24.1","rollup": "^0.64.1","rollup-plugin-babel": "^3.0.7","rollup-plugin-node-resolve": "^3.3.0"}
}

4.rollup.config.js配置

import babel from 'rollup-plugin-babel'
import resolve from 'rollup-plugin-node-resolve'
import { format } from 'path';
export default{entry:'src/index.js', //入口format:'umd', //兼容 规范 script导入 amd commonjsplugins:[resolve(),babel({exclude:'node_modules/**'})],dest:'build/bundle.js'
}

5.运行 npm run rollup

Parcel

  • 完全零配置的前端应用打包器。
  • Parcel官方建议以html文件作为入口。
  • 它不仅会帮我们打包应用,还会帮忙打开一个开发服务器。
  • Parcel支持热替换、自动安装依赖、动态导入等特性。
  • Parcel给开发者的体验:你想要做什么就去做,其他额外的工作交给Parcel处理。
  • Parcel构建速度更快,因为它内部使用了多进程同步工作。
  • Webpack有更好的生态,Webpack越来越好用。

http://chatgpt.dhexx.cn/article/IdGfOngy.shtml

相关文章

模块化开发简述

模块化开发简述 都说模块化开发为前端发展带来了巨大的进步&#xff0c;然而不熟悉的人看着也是两眼一懵&#xff0c;那其实这到底是什么&#xff1f;好处在哪&#xff1f;我来说说自己的见解吧。 1. 模块化和传统开发的区别 实话讲&#xff0c;其实在我看来&#xff0c;两…

什么是模块化?模块化怎么实现?

什么是模块化&#xff1f;模块化怎么实现&#xff1f; 前言 &#xff1a; 增加印象&#xff0c;留下脚印 &#xff0c;忘记还可以翻一翻 奥利给。 1&#xff0c;什么是模块化 公司里一个项目是有很多程序员一起开发的&#xff0c;例如 “多人运动” 这个项目 有程序员a &…

vue 模块化开发

1、npm install webpack -g 全局安装 webpack 2、npm install -g vue/cli-init 全局安装 vue 脚手架 3、初始化 vue 项目&#xff1b; vue init webpack appname&#xff1a;vue 脚手架使用 webpack 模板初始化一个 appname 项目 4、启动 vue 项目&#xff1b; 项目的 p…

Android模块化开发

模块化开发项目搭建 1.为什么要模块化开发 随着APP版本不断的迭代&#xff0c;新功能的不断增加&#xff0c;业务也会变的越来越复杂&#xff0c;APP业务模块的数量有可能还会继续增加&#xff0c;而且每个模块的代码也变的越来越多&#xff0c;这样发展下去单一工程下的APP架…

vue模块化开发

1.前端代码化雏形和CommonJS JavaScript原始功能 在网页开发的早期&#xff0c;js制作作为一种脚本语言&#xff0c;做一些简单的表单验证或者动画实现&#xff0c;代码量比较少&#xff0c;只要写在script标签里面就可以了 随着ajax异步请求的出现&#xff0c;慢慢形成了前…

模块化编程

1.一般编程方式&#xff1a;所有函数放在“.c”文件里。 &#xff08;缺点&#xff1a;若使用的模块功能比较多&#xff0c; 则一个文件内会有很多的代码&#xff0c; 不…

一次跟你说清楚,什么是组件化开发?什么是模块化开发?

网上有许多讲组件化开发、模块化开发的文章&#xff0c;但大家一般都是将这两个概念混为一谈的&#xff0c;并没有加以区分。而且实际上许多人对于组件、模块的区别也不甚明了&#xff0c;甚至于许多博客文章专门解说这几个概念都有些谬误。 想分清这两个概念我觉得结合一下软件…

前端模块化开发

前端模块化开发 什么是模块化&#xff1f; 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说&#xff0c;模块是可组合、分解和更换的单元 编程领域中的模块化&#xff0c;就是遵守固定的规则&#xff0c;把一个大文件拆成…

模块化开发

模块化开发 1. 模块化开发最终的目的是将程序划分成 一个个小的结构 。 2. 这个结构中编写属于 自己的逻辑代码 &#xff0c;有 自己的作用域 &#xff0c;定义变量名词时不会影响到其他的结构。 3. 这个结构可以将自己希望暴露的 变量、函数、对象等导出 给其结构使用&#xf…

HttpClient CloseableHttpClient GetMethod PostMethod http

pom依赖 <!--HttpClient的依赖--><dependency><groupId>commons-httpclient</groupId><artifactId>commons-httpclient</artifactId><version>3.1</version></dependency><!--CloseableHttpClient的依赖--><de…

JAVA小工具-05-HttpClient/PostMethod上传文件(解决中文文件名乱码问题)

言于头:本节讨论的是在项目中利用HttpClient/PostMethod相关api进行上传文件操作时&#xff0c;会出现上传中文文件名乱码问题。为解决这个问题&#xff0c;下面是总结的一个HTTP工具类以及测试用例。 public class HttpUtils {public static final String UTF_8 "UTF-8&…

解决PostMethod的中文乱码

解决HttpClient的PostMethod的中文乱码问题 问题场景&#xff1a; 解决代码&#xff1a; 请求时设定编码格式&#xff1a; post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8"); 完整代码&#xff1a; /*** 封装请求参数&#xff0…

php 取整,PHP取整的方法有哪些

本篇文章主要给大家介绍PHP取整的四种方法。 PHP实现取整的问题&#xff0c;不仅在我们学习PHP过程中会遇到&#xff0c;在我们PHP面试过程中也是常见的考点之一。 下面我们结合简单的示例给大家总结介绍PHP取整的四种方法。 第一种方法&#xff1a;直接取整&#xff0c;舍弃小…

php 如何取整,解析php取整的几种方式

解析php取整的几种方式 floor 舍去法取整 语法格式:float floor ( float value )返回不大于value 的下一个整数&#xff0c;将value 的小数部分舍去取整。floor() 返回的类型仍然是float&#xff0c;因为float 值的范围通常比integer 要大。 echo floor(4.3); // 4 echo floo…

VUE 数据分页

只要涉及到数据查询&#xff0c;通常我们都会进行分页查询。 假设你的表中有上百万条记录&#xff0c;不分页的话&#xff0c;我们不可能一次性将所有数据全部都载入到前端吧&#xff0c;那前后端都早就崩溃了。 结合 Spring Spring 和 Vue 都提供了开箱即用的分页功能。 S…

前端Vue分页及后端PageHelper分页综合运用

分页显示数据对项目开发中尤为重要&#xff0c;同时能提升用户体验&#xff0c;下面的前端css、js是我引用这篇文章的《使用Vue开发一个分页插件》&#xff0c;我在这个的基础上结合了后端稍微完善了一下&#xff0c;修改了disable的样式&#xff0c;在里面加了pointer-events:…

antd design vue分页组件

我们在使用分页组件的时候可以有两种方法&#xff1a; 第一种是直接用表格()的自定义:pagination属性最方便&#xff1b;如下图所示&#xff1a; 第二种是分页组件 这里我总结的是第二种方法的使用&#xff0c;由于是 Ant Design Vue 的组件&#xff0c;所以必须安装Ant Desig…

Vue分页页码栏设计

Vue分页页码栏设计 效果展示HTML数据需要函数需要运用 效果展示 HTML <div class"page_bar no-select"><ul class"clearfix"><li class"iconfont":class"{vh : currentPage 1}"click"subCurrentPage">&…

超级详细:一个漂亮的Vue分页器组件的实现

整篇分两个部分&#xff1a; 思路部分&#xff1a;讲解怎么实现分页器组件【大把时间看-建议】 后面部分&#xff1a;按照步骤&#xff0c;直接引入组件【没有时间看-建议】 思路&#xff1a;基于连续页码进行判断 需要添加分页器的组件&#xff08;Search组件&#xff09;中…

vue实现分页vue分页查询怎么实现

效果图&#xff1a; 代码&#xff1a; 复制过去即可运行 <!DOCTYPE html> <html lang"en" xmlns:th"http://www.w3.org/1999/xhtml"> <head><meta charset"UTF-8"><title>Title</title><!-- <scrip…