当前位置: 首页 > news >正文

【从0-1实现一个前端脚手架】

目录

  • 介绍
    • 为什么需要脚手架?
    • 一个脚手架应该具备哪些功能?
  • 脚手架实现
    • 初始化项目
    • 相关依赖
    • 实现脚手架
  • 发布

介绍

为什么需要脚手架?

脚手架本质就是一个工具,作用是能够让使用者专注于写代码,它可以让我们只用一个命令就生成一个已经配置好的项目,而不用我们再花时间去配置和安装相关依赖,可以在很大程度上提升我们的开发效率。比如我们常用的create-vue和create-react-app就是脚手架,很多大厂也都有自己的脚手架。

一个脚手架应该具备哪些功能?

我们以vue官方的脚手架create-vue为例来分析下一个脚手架应该具备哪些功能?

  1. 运行命令创建项目:npm create vue@latest
  2. 用户根据自己需要选择一些配置项
    在这里插入图片描述
  3. 根据选择的配置项会生成一个模版项目
    在这里插入图片描述

通过分析create-vue,我们可以知道,一个脚手架如果想要创建一个项目,最少要有以下两点功能:

  1. 可以通过命令行和用户交互
  2. 根据交互的结果去生成对应的模版项目

脚手架实现

初始化项目

  1. 在电脑终端执行以下命令
mkdir kfc-vme50
cd kfc-vme50
npm init -y
  1. 在根目录下创建bin/index.js文件作为入口文件,并添加如下代码,第一行注解是为了告诉操作系统,本文件用node执行
#!/usr/bin/env node
console.log('肯德基疯狂星期四v我50')
  1. 在package.json中添加bin字段
"bin": "/bin/index.js"
  1. 在根目录下执行npm link将项目链接到本地环境,就可以实现kfc-vme50命令全局调用
  2. 运行kfc-vme50并查看控制台输出
    在这里插入图片描述

实际上,npm link将这个包装到了全局,我们在全局执行kfc-vme50系统会在package.json中找到bin声明,bin指定的文件会被获取到,然后用node执行这个文件

相关依赖

实现一个脚手架,通常会用到以下依赖包

  1. commander:命令行处理工具,安装:npm install commander
#!/usr/bin/env node// #! 是shebang的标识,告诉操作系统这是一个脚本文件。
// /usr/bin/env 是一个程序,用来查找环境变量中定义的程序路径。在这个例子中,它用来查找node的路径。
// node 是Node.js的可执行文件名,它是运行JavaScript代码的运行时环境。// 它用于处理命令行参数;
const { program } = require("commander");/***  .name 命令名称出现在帮助中,也用于定位独立的可执行子命令。*  .usage 通过这个选项可以修改帮助信息的首行提示,即修改usage提示*/program.name("kfc-vme50-cli").usage("<command> [option]");/*** 「选项」 定义选项* 使用.option()方法来定义选项,同时可以附加选项的简介。每个选项可以定义一个短选项名称(-后面接单个字符)*    一个长选项名称(--后面接一个或多个单词),使用逗号、空格或|分隔。*    有两种最常用的选项,一类是 boolean 型选项,选项无需配置参数,*    另一类选项则可以设置参数(使用尖括号声明在该选项后,如--expect <value>)。*    如果在命令行中不指定具体的选项及参数,则会被定义为undefined*/program.option("-d, --debug", "output extra debugging").option("-s, --small", "small pizza size").option("-p, --pizza-type <type>", "flavour of pizza");/*** 「命令」 通过.command()或.addCommand()可以配置命令,* .command()的第一个参数为命令名称。命令参数可以跟在名称后面,也可以用.argument()单独指定。* 参数可为必选的(尖括号表示)、可选的(方括号表示)或变长参数(点号表示,如果使用,只能是最后一个参数)。* ----------------------------------------------------------------* description 出现在命令的帮助中。* action 命令触发后的回调函数 [命令行的参数]*/program.command("clone <source> [destination]").description("clone a repository into a newly created directory").action((source, destination) => {console.log("clone command called");console.log(source, destination);});/** * 「parse」解析命令行参数* program.parse 它的作用是解析 process.argv 数组,将命令行参数转换为可操作的对象。* process.argv 是 Node.js 中的一个全局变量,它是一个数组,包含了命令行启动脚本时传递给 Node.js 进程的参数。数组的第一个元素 process.argv[0] 总是 node, 表示 Node.js 可执行文件的路径 (安装路径)接下来的元素是脚本文件的路径,即你正在运行的 JavaScript 文件的路径。之后的元素是传递给脚本的命令行参数process可以理解为node的环境变量,argv是用户在控制台输入的命令
*/
program.parse(process.argv);/*** 「opts」获取用户输入的![请添加图片描述](https://i-blog.csdnimg.cn/direct/b2cb8c1bd37a4dfb8909597ff262e39c.jpeg)
命令行参数* 解析后的选项可以通过Command对象上的.opts()方法获取,同时会被传递给命令处理函数。*/
const options = program.opts();
console.log(options);console.log("肯德基疯狂星期四v我500");

打印process.argv结果如下(注意,截图的指令为kfc-vme50-cli):
请添加图片描述
请添加图片描述
使用上面定义好的clone命令
请添加图片描述
并且执行kfc-vme50-cli --help可以看到我们刚才定义的命令
请添加图片描述

  1. chalk:命令行输出美化工具,安装:npm install chalk@4.0.0
#!/usr/bin/env node// 重要提示:Chalk 5 部分是 ESM。如果您想将 Chalk 与 TypeScript 或构建工具一起使用,您现在可能需要使用 Chalk 4/**
ESM 是 "ECMAScript Module" 的缩写,它指的是一种 JavaScript 模块的规范,允许开发者将代码分割成可重用的模块。
ESM 是现代 JavaScript 的一个特性,它支持静态模块的导入和导出,这意味着模块的依赖关系可以在编译时就确定下来,从而提高代码的加载和执行效率。
然而,ESM 也有它的限制,比如它不支持 CommonJS 模块中的 require() 函数,而是使用 import() 来动态加载模块。
此外,ESM 需要在支持 ESM 的环境中使用,比如现代浏览器或者使用 Babel 等工具转换的 Node.js 环境。*/const chalk = require("chalk");// 颜色
console.log(chalk.yellow("Welcome"));
// 加粗
console.log(chalk.red.bold("Welcome"));
// 背景色
console.log(chalk.yellow.bold.bgBlue("Welcome"));
  1. inquirer:命令行交互工具,安装:npm install inquirer@8.0.0
#!/usr/bin/env node
/*** !警告] Inquirer v9 及更高版本是 esm 模块,* 这意味着您不能再使用 commonjs 语法 require('inquirer') * 或者,如果您需要 commonjs 模块,则应该依赖旧版本,直到准备好升级环境*/
const inquirer = require("inquirer");/*** inquirer.prompt(questions, answers) -> promise* 启动提示界面(查询会话)*    questions (Array) 包含 Question 对象(使用反应式接口,还可以传递 Rx.Observable 实例)*    答案(对象)包含已回答问题的值。询问者将避免询问此处已提供的答案。默认值 {}。**「Question对象」 问题对象是包含问题相关值的哈希type  (字符串)提示的类型。【input, number, confirm, list, rawlist, expand, checkbox, password, editor】name:(字符串)将答案存储在答案哈希中时使用的名称。如果名称包含句点,它将在答案哈希中定义路径。message:(字符串|函数)要打印的问题。如果定义为函数,第一个参数将是当前询问者会话的答案。默认为 name 的值(后跟冒号)default:(字符串|数字|布尔值|数组|函数)未输入任何内容时使用的默认值,或返回默认值的函数。如果定义为函数,第一个参数将是当前询问者会话的答案**/inquirer.prompt([// 将你的问题放在这{type: "input",name: "food",message: "你吃啥",default: "披萨",},{type: "confirm",name: "hot",message: "吃不吃辣",default: false,},]).then((answers) => {//使用用户反馈。。。无论什么结果console.log(answers);}).catch((error) => {if (error.isTtyError) {// 无法在当前环境中呈现提示} else {//其他问题}});

就是用来定义询问用户操作的命令,使用如下:
请添加图片描述

  1. ora:终端loading美化工具,安装:npm install ora@5.0.0,更高版本是esm模块,不能使用require引入
#!/usr/bin/env node
const ora = require("ora");// 启动旋转器。返回实例。如果提供了文本,则设置当前文本。
const spinner = ora("Loading unicorns").start();// 旋转器1s后变为黄色,文案变为:Loading rainbows
setTimeout(() => {spinner.color = "yellow";spinner.text = "Loading rainbows";
}, 1000);// 停止旋转器,将其更改为绿色 ✔ 并保留当前文本或文本(如果提供)。返回实例。请参阅下面的 GIF。
// setTimeout(() => {
//   spinner.succeed("succeed");
// }, 2000);// 停止旋转器,将其更改为红色 ✖ 并保留当前文本或文本(如果提供)。返回实例。
setTimeout(() => {spinner.fail("fail");
}, 2000);
  1. git-clone:下载项目模版工具,安装:npm install git-clone
  2. figlet:终端生成艺术字,安装:npm insatll figlet
#!/usr/bin/env node
var figlet = require("figlet");// 将 Figlet 对象作为函数调用是调用文本函数的简写。此方法允许您从文本创建 ASCII 艺术。
// 输入文本 - 要转换为 ASCII 艺术的文本字符串。
// 选项 - 指示字体名称的字符串或选项对象(如下所述)
// 回调 - 使用生成的 ASCII Art 执行的函数。figlet("Hello World!!", function (err, data) {if (err) {console.log("Something went wrong...");console.dir(err);return;}console.log(data);
});// 该方法是上述方法的同步版本
// 输入文本 - 要转换为 ASCII 艺术的文本字符串。
// 字体选项 - 指示字体名称的字符串或选项对象(如下所述)。
console.log(figlet.textSync("Boo!", {font: "Ghost", //类型:字符串 默认值:'标准' 指示要使用的 Figlet 字体的字符串值。horizontalLayout: "default", //指示要使用的水平布局的字符串值verticalLayout: "default", //指示要使用的垂直布局的字符串值width: 80, //宽度whitespaceBreak: true, //此选项与“宽度”结合使用。如果此选项设置为 true,则库在限制宽度时将尝试在空白处分解文本。})
);

请添加图片描述

  1. fs-extra:用来操作本地目录,安装:npm run fs-extra

实现脚手架

#!/usr/bin/env node// 操作终端命令行
const { program } = require("commander");
// 艺术字
const figlet = require("figlet");
// 操作文件
const fs = require("fs-extra");
// 获取路径
const path = require("path");
// 命令行交互
const inquirer = require("inquirer");
// 彩色输出
const chalk = require("chalk");
//控制台loadding
const ora = require("ora");// clone 项目
const gitClone = require("git-clone");// 项目仓库
const projectList = {vue: "https://gitee.com/y_project/RuoYi-Vue.git",react: "https://gitee.com/whiteshader/ruoyi-react.git","react&ts": "https://gitee.com/whiteshader/ruoyi-react.git","vue&ts": "https://gitee.com/lyforvue/ruoyi_vue3_ts.git",
};// 修改帮助信息的首行展示
program.usage("<command> [options]");// 版本号
program.version(`v${require("../package.json").version}`);// 艺术字展示 监听 help添加提示信息
program.on("--help", function () {console.log(figlet.textSync("kfc vme50", {font: "Ghost",horizontalLayout: "default",verticalLayout: "default",width: 100,whitespaceBreak: true,}));
});// 创建项目的命令
program.command("create <app-name>") // 创建项目的命令 name必填.description("创建新项目") //描述//执行命令后的回调【命令后的值,】.action(async function (name, option) {//创建一个名为name的文件夹,把我们模板项目的代码都放到文件夹下// 1. 先判断有没有名为name的文件夹const cwd = process.cwd(); //获取命令执行的文件目录// 创建项目的位置const targetPath = path.join(cwd, name);// 如果文件夹存在if (fs.existsSync(targetPath)) {const res = await inquirer.prompt([{name: "action",type: "list",message: "是否覆盖已有文件夹?",choices: [{name: "YES",value: true,},{name: "NO",value: false,},],},]);//不覆盖 直接返回,让用户取一个新的名字再创建if (!res.action) return;fs.remove(targetPath);console.log(chalk.red("已删除之前的文件夹"));}//新建项目const res = await inquirer.prompt([{name: "type",type: "list",message: "请选择使用的框架",choices: [{name: "Vue",value: "vue",},{name: "React",value: "react",},],},{name: "ts",type: "list",message: "是否使用ts项目",choices: [{name: "YES",value: true,},{name: "NO",value: false,},],},]);// 是否为tsconst rep = res.type + (res.ts ? "&ts" : "");// 拉取项目模板const spinner = ora("正在加载项目模板...").start();gitClone(projectList[rep], //拉取路径targetPath, //保存路径//分支{checkout: "master",},//回调函数(err) => {if (!err) {fs.remove(path.resolve(targetPath, ".git"));spinner.succeed("项目模板加载完成!");console.log("now run:");console.log(chalk.green(`\n  cd ${name}`));console.log(chalk.green("  npm install"));console.log(chalk.green(`  npm run ${res.type === "react" ? "start" : "dev"}\n`));} else {spinner.fail(chalk.red("项目模板加载失败,请重新获取!", err));}});});//解析控制台参数
program.parse(process.argv);

发布

  1. npm官网注册npm账号
  2. 在本地登录并发布
# 登录刚注册的账号
npm login
Username: 用户名
Password: 密码
Email: 注册邮箱
Enter one-time password: 一次性密码  邮箱会收到邮件# 在我们脚手架的根目录下执行发布命令
npm publish

注意:

  1. 登录和发包前一定要先查看npm的源,需要修改为https://registry.npmjs.org/
  2. 在发布时包名不能重复,所以可以先在npm官网搜索下看看有没有存在的包,如果出现403错误可能是包名和线上的包重复了,修改package.json中的name即可
  3. 如果以后要更新包,更新package.json的version,再发布一下即可
  4. 在npm官网上为你的包添加readme
  5. 登陆npm官网可以在setting中删除你自己发的包

相关文章:

【从0-1实现一个前端脚手架】

目录 介绍为什么需要脚手架&#xff1f;一个脚手架应该具备哪些功能&#xff1f; 脚手架实现初始化项目相关依赖实现脚手架 发布 介绍 为什么需要脚手架&#xff1f; 脚手架本质就是一个工具&#xff0c;作用是能够让使用者专注于写代码&#xff0c;它可以让我们只用一个命令…...

AI文章管理系统(自动生成图文分发到分站)

最近帮一个网上的朋友做了一套AI文章生成系统。他的需求是这样&#xff1a; 1、做一个服务端转接百度文心一言的生成文章的API接口。 2、服务端能注册用户&#xff0c;用户在服务端注册充值后可以获取一个令牌&#xff0c;这个令牌填写到客户端&#xff0c;客户端就可以根据客…...

【Leetcode 每日一题】3270. 求出数字答案

问题背景 给你三个 正 整数 n u m 1 num_1 num1​&#xff0c; n u m 2 num_2 num2​ 和 n u m 3 num_3 num3​。 数字 n u m 1 num_1 num1​&#xff0c; n u m 2 num_2 num2​ 和 n u m 3 num_3 num3​ 的数字答案 k e y key key 是一个四位数&#xff0c;定义如下&…...

基于单片机的无线气象仪系统设计(论文+源码)

1系统方案设计 如图2.1所示为无线气象仪系统设计框架。系统设计采用STM32单片机作为主控制器&#xff0c;结合DHT11温湿度传感器、光敏传感器、BMP180气压传感器、PR-3000-FS-N01风速传感器实现气象环境的温度、湿度、光照、气压、风速等环境数据的检测&#xff0c;并通过OLED1…...

【数据库】Mysql精简回顾复习

一、概念 数据库&#xff08;DB&#xff09;&#xff1a;数据存储的仓库数据库管理系统&#xff08;DBMS&#xff09;&#xff1a;操纵和管理数据库的大型软件SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;是一套标准关系型数据库&#xff08;RDBMS&#xff09;&…...

深入理解 HTTP 的 GET、POST 方法与 Request 和 Response

HTTP 协议是构建 Web 应用的基石&#xff0c;GET 和 POST 是其中最常用的请求方法。无论是前端开发、后端开发&#xff0c;还是接口测试&#xff0c;对它们的深入理解都显得尤为重要。在本文中&#xff0c;我们将介绍 GET 和 POST 方法&#xff0c;以及 Request 和 Response 的…...

MySQL 中联合索引相比单索引性能提升在哪?

首先我们要清楚所以也是要占用磁盘空间的&#xff0c;随着表中数据量越来越多&#xff0c;索引的空间也是随之提升的&#xff0c;因而单表不建议定义过多的索引&#xff0c;所以使用联合索引可以在一定程度上可以减少索引的空间占用其次&#xff0c;使用联合索引的情况下&#…...

第34天:安全开发-JavaEE应用反射机制攻击链类对象成员变量方法构造方法

时间轴&#xff1a; Java反射相关类图解&#xff1a; 反射&#xff1a; 1、什么是 Java 反射 参考&#xff1a; https://xz.aliyun.com/t/9117 Java 提供了一套反射 API &#xff0c;该 API 由 Class 类与 java.lang.reflect 类库组成。 该类库包含了 Field 、 Me…...

C++笔记之数据单位与C语言变量类型和范围

C++笔记之数据单位与C语言变量类型和范围 code review! 文章目录 C++笔记之数据单位与C语言变量类型和范围一、数据单位1. 数据单位表:按单位的递增顺序排列2. 关于换算关系的说明3. 一般用法及注意事项4. 扩展内容5. 理解和使用建议二、C 语言变量类型和范围基本数据类型标准…...

算法-拆分数位后四位数字的最小和

力扣题目2160. 拆分数位后四位数字的最小和 - 力扣&#xff08;LeetCode&#xff09; 给你一个四位 正 整数 num 。请你使用 num 中的 数位 &#xff0c;将 num 拆成两个新的整数 new1 和 new2 。new1 和 new2 中可以有 前导 0 &#xff0c;且 num 中 所有 数位都必须使用。 …...

Python 管理 GitHub Secrets 和 Workflows

在现代软件开发中,自动化配置管理变得越来越重要。本文将介绍如何使用 Python 脚本来管理 GitHub 仓库的 Secrets 和 Workflows,这对于需要频繁更新配置或管理多个仓库的团队来说尤为有用。我们将分三个部分进行讨论:设置 GitHub 权限、创建 GitHub Secret 和创建 GitHub Wo…...

指令的修饰符

指令的修饰符 参考文献&#xff1a; Vue的快速上手 Vue指令上 Vue指令下 Vue指令的综合案例 文章目录 指令的修饰符指令修饰符 结语 博客主页: He guolin-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&…...

C# 正则表达式完全指南

C# 正则表达式完全指南 C#通过 System.Text.RegularExpressions 命名空间提供强大的正则表达式支持。本指南将详细介绍C#中正则表达式的使用方法、性能优化和最佳实践。 1. 基础知识 1.1 命名空间导入 using System.Text.RegularExpressions;1.2 基本使用 public class Re…...

【笔记整理】记录参加骁龙AIPC开发者技术沙龙的笔记

AIoT 首先了解了一个概念叫AIoT&#xff0c;我的理解就是AI IoT 5G&#xff0c;通过AI的发展使得边缘计算、数据整合和处理变得快捷方便&#xff0c;不仅限于传统的云端数据处理&#xff0c;在边缘的IoT设备上也可以进行智能化打造&#xff0c;通过5G的通信能力扩展可以实现…...

论文解析 | 基于语言模型的自主代理调查

论文 《A Survey on Large Language Model-based Autonomous Agents》 对基于大型语言模型&#xff08;LLM&#xff09;的自主智能体&#xff08;Autonomous Agents&#xff09;进行了全面调查。随着大型语言模型&#xff08;如 GPT 系列、BERT、T5 等&#xff09;的快速发展&a…...

面试加分项:Android Framework AMS 全面概述和知识要点

第一章:AMS 的架构与组件 1.1 AMS 整体架构 在 Android 系统的庞大体系中,AMS(Activity Manager Service)就如同一个中枢神经系统,是整个系统的核心服务之一,对应用的性能和用户体验有着直接且关键的影响 。它的整体架构由 Client 端和 Service 端两大部分组成,这两端相…...

EasyCVR视频汇聚平台如何配置webrtc播放地址?

EasyCVR安防监控视频系统采用先进的网络传输技术&#xff0c;支持高清视频的接入和传输&#xff0c;能够满足大规模、高并发的远程监控需求。平台支持多协议接入&#xff0c;能将接入到视频流转码为多格式进行分发&#xff0c;包括RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、W…...

用户界面软件04

后果 使用这种架构很容易对两个层面的非功能性需求进行优化&#xff0c;但是你仍然需要小心不要将功能 需求重复实现。 现在&#xff0c;两个层面可能有完全不同的设计。比如&#xff0c;用户界面层可能使用配件模型&#xff08;Widget Model&#xff09;&#xff0c; 以大量的…...

C#,数值计算,矩阵相乘的斯特拉森(Strassen’s Matrix Multiplication)分治算法与源代码

Volker Strassen 1 矩阵乘法 矩阵乘法是机器学习中最基本的运算之一&#xff0c;对其进行优化是多种优化的关键。通常&#xff0c;将两个大小为N X N的矩阵相乘需要N^3次运算。从那以后&#xff0c;我们在更好、更聪明的矩阵乘法算法方面取得了长足的进步。沃尔克斯特拉森于1…...

linux:文件的创建/删除/复制/移动/查看/查找/权限/类型/压缩/打包

关于文件的关键词 创建 touch 删除 rm 复制 cp 权限 chmod 移动 mv 查看内容 cat(全部); head(前10行); tail(末尾10行); more,less 查找 find 压缩 gzip ; bzip 打包 tar 编辑 sed 创建文件 格式&#xff1a; touch 文件名 删除文件 复制文件 移动文件 查看文…...

SQL Server查询计划操作符——查询计划相关操作符(3)

7.3. 查询计划相关操作符 19)Collapse:该操作符对更改处理进行优化。当执行一个更改时,其能被劈成(用Split操作符)一个删除和一个插入。其参数列包含一个确定一系列键值字段的GROUP BY:()子句。如果查询处理器遇到删除和插入相同键值的毗邻行,其将用一个更高效的更改操作…...

【Notepad++】Notepad++如何删除包含某个字符串所在的行

Notepad如何删除包含某个字符串所在的行 一&#xff0c;简介二&#xff0c;操作方法三&#xff0c;总结 一&#xff0c;简介 在使用beyoundcompare软件进行对比的时候&#xff0c;常常会出现一些无关紧要的地方&#xff0c;且所在行的内容是变化的&#xff0c;不方便进行比较&…...

Android 来电白名单 只允许联系人呼入电话

客户需求只允许通讯录中联系人可以呼入电话。参考自带的黑名单实现 CallsManager.java类中的onSuccessfulIncomingCall方法有一些过滤器&#xff0c;可以仿照黑名单的方式添加自己的过滤器。 packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java …...

【计算机网络】lab3 802.11 (无线网络帧)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;计算机网络_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2.…...

单片机(MCU)-简单认识

简介&#xff1a; 内部集成了CPU&#xff0c;RAM&#xff0c;ROM&#xff0c;定时器&#xff0c;中断系统&#xff0c;通讯接口等一系列电脑的常用硬件功能。 单片机的任务是信息采集&#xff08;依靠传感器&#xff09;&#xff0c;处理&#xff08;依靠CPU&#xff09;&…...

全面教程:Nacos 2.3.2 启用鉴权与 MySQL 数据存储配置

全面教程&#xff1a;Nacos 2.3.2 启用鉴权与 MySQL 数据存储配置 1. 配置 Nacos 开启鉴权功能 1.1 修改 application.properties 配置文件 在 Nacos 2.3.2 中&#xff0c;开启鉴权功能需要修改 conf/application.properties 文件。按照以下方式配置&#xff1a; # 开启鉴权…...

软件23种设计模式完整版[附Java版示例代码]

一、什么是设计模式 设计模式是在软件设计中反复出现的问题的通用解决方案。它们是经过多次验证和应用的指导原则,旨在帮助软件开发人员解决特定类型的问题,提高代码的可维护性、可扩展性和重用性。 设计模式是一种抽象化的思维方式,可以帮助开发人员更好地组织和设计他们…...

国标GB28181-2022视频平台EasyGBS小知识:局域网ip地址不够用怎么解决?

在局域网中&#xff0c;IP地址不足的问题通常不会在小型网络中出现&#xff0c;但在拥有超过255台设备的大型局域网中&#xff0c;就需要考虑如何解决IP地址不够用的问题了。 在企业局域网中&#xff0c;经常会出现私有IP地址如192.168.1.x到192.168.1.255不够用的情况。由于0…...

PHP 循环控制结构深度剖析:从基础到实战应用

PHP 循环控制结构深度剖析&#xff1a;从基础到实战应用 PHP提供了多种控制结构&#xff0c;其中循环控制结构是最常见的结构之一。它们使得我们能够高效地重复执行一段代码&#xff0c;直到满足某个条件为止。本文将从PHP循环的基础知识出发&#xff0c;逐步分析其在实际项目…...

vue的属性绑定

重建一个新的项目 App.vue main.js HelloWorld.vue 属性绑定 双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute&#xff0c;应该使用 v-bind 指令 <template><div v-bind:id"dynamicId" v-bind:class"dynamicClass">…...

杭州竞彩网站开发/产品全网营销推广

微信小程序是一种不需要下载安装即可使用的应用&#xff0c;它实现了应用“触手可及”的梦想&#xff0c;微信用户只需要扫一扫或搜一下即可打开应用。那么如何开发微信小程序?接下来让我们看看搭建微信小程序的零基础玩法。小程序是依托微信诞生的&#xff0c;由于微信属于强…...

淘宝做网站推广怎么样/头条号权重查询

Reflect对象与Proxy对象一样&#xff0c;也是 ES6 为了操作对象而提供的新 API Reflect设计目的&#xff1a; 将Object对象的一些明显属于语言内部的方法&#xff08;比如Object.defineProperty&#xff09;&#xff0c;放到Reflect对象上。修改某些Object方法的返回结果&#…...

wap浏览器免费下载/百度seo关键词排名 s

标题中的substring方法指的是字符串的substring(int beginIndex, int endIndex)方法&#xff0c;这个方法在jdk6,7是有差异的。 substring有什么用&#xff1f; substring返回的是字符串索引位置beginIndex开始&#xff0c;endIndex-1结束的字符串。 来看这个例子&#xff1…...

做网站需要那些编程语言/网络营销策略主要包括

文章目录hashmap基础hashmap的nodehashmap的容量hashmap的负载因子hashmap的hash()算法HashMap里面的hash()返回值hashmap的数组链表/树问题hashmap为什么引入链表为什么jdk1.8会引入红黑树呢hashmap为什么一开始不就使用红黑树&#xff1f;HashMap的底层数组取值的时候&#x…...

网站建设首页图片插入/网站推广在哪好

arr.reduce(function(prev,cur,index,arr){ ... }, init);其中&#xff0c; arr 表示原数组&#xff1b; prev 表示上一次调用回调时的返回值&#xff0c;或者初始值 init; cur 表示当前正在处理的数组元素&#xff1b; index 表示当前正在处理的数组元素的索引&#xff0c;若提…...

网站模板免费下载中文版/百度电话客服24小时

“计算机科学只存在两个难题&#xff1a;缓存失效和命名。” ——Phil KarIton 前言 命名一直是我编程过程中很头痛的事&#xff0c;有时为了一个恰当的名称是想了又想&#xff0c;还忍不住Google一下。命名真是一门艺术&#xff0c;好的命名那叫一个高大上。今天总结一些前端命…...