普通视图
sv-print可视化打印组件不完全指南⑤
上期探讨了sv-print简单的插件机制,以及实现了参数的重写,项目是TS创建的,参数的写法就显得那么格格不入了。所以本期探索探索 用ES6的写法来重构它,让后续编写更加的方便。
前言
如果你对 ES6 或者 原型链不熟悉。那么本期,你将有所收获,本着授人以鱼不如授人以渔的思想。 本篇从调试分析,到实战落地。
调试分析
上篇说的,它几个核心的方法: createTarget、getValue、setValue、destroy 以及 可选的 css。
见下方代码,看着就难受😢
const fieldOptionFun = (configs: any) => {
return function () {
function t() {
this.name = "field";
}
return (
(t.prototype.createTarget = function (t, i, e) {
}),
(t.prototype.getValue = function () {
}),
(t.prototype.setValue = function (t: any) {
}),
(t.prototype.destroy = function () {
}),
t
);
}
};
看不懂先别慌,发个朋友圈先(console.log)
const testFun = filedOption();
const test = new testFun();
console.log(test);
思考🤔: 为什么要这样写? 咱们可以复制的函数,让 AI 解释一下。
亮相参数对象:
ES6改写
为了继承,为了简洁。
新增一个基类:baseOption.ts
export interface BaseOption {
/**
* 参数名称
*/
name: string;
/**
* 会修改 DOM 样式的属性才需要: eg: color, backgroundColor
* @param printElement 元素对象
* @param value 该属性值
*/
css?(printElement: HTMLElement, value: string | number | boolean): void;
/**
* 创建参数DOM
* @param printElement 元素对象
* @param options 元素参数
* @param printElementType 元素类型对象
*/
createTarget(printElement: any, options: any, printElementType: any): HTMLElement;
getValue(): string | number | boolean;
setValue(value: string | number | boolean): void;
destroy(): void;
}
重新实现fieldOption
新建一个 fieldOption.ts
export class FieldOption implements BaseOption {
public name: string = "field";
isSelect: boolean = false;
target: any = null;
vueApp: any = null;
vueAppIns: any = null;
configs: any = {};
constructor(configs: any) {
this.configs = configs;
}
createTarget(printElement: any, options: any, printElementType: any): HTMLElement {
const fileds = printElement.getFields();
this.isSelect = fileds && fileds.length > 0;
const el = globalThis.$(
`<div class="hiprint-option-item hiprint-option-item-row">
<div class="hiprint-option-item-label">字段名</div>
<div class="hiprint-option-item-field">
<div id="fieldOption">
</div>
</div>
`
);
this.target = el;
this.vueApp = createApp(fieldVueApp, {
onChange: (value) => {
console.log("onChange", value);
printElement && printElement.submitOption();
},
options: fileds || this.configs.fieldList,
dialog: this.configs.dialog,
});
this.vueApp.use(Button);
this.vueApp.use(Modal);
this.vueApp.use(AutoComplete);
setTimeout(() => {
this.vueAppIns = this.vueApp.mount("#fieldOption");
}, 0);
return this.target;
}
getValue(): string | number | boolean {
return this.vueAppIns && this.vueAppIns.getValue();
}
setValue(value: string | number | boolean): void {
setTimeout(() => {
if (this.vueAppIns) {
this.vueAppIns.setValue(value);
}
}, 0);
}
destroy(): void {
if (this.vueApp) {
this.vueApp.unmount();
}
this.target.remove();
}
}
稍微改吧改吧,亮个相,测试一下效果,它的原型链是否正常:
可以看到,核心方法在原型链上。 咱们存储为全局变量测试一下方法
啊哈,能调用就行成了~ 但是整体流程还是有报错的,如下图:
不要慌,不要慌,报错意思是咱们传的不是一个构造函数。
嘿嘿,那不就好说了嘛。 套一套
export const FieldOptionFun = (configs: any) => {
return function () {
return new FieldOption(configs);
};
};
咱们对比输出看看实际对象:
后者,我们明显可以看到对象的痕迹。
看看整个fieldOption.ts文件
这样思路一打开,咱们可以有更好的去拓展实现参数的处理。
所以控制台是再基础不过的调试手段了。大家一定要仔细探索观察输出的对象格式。
总结
本篇深入探索了参数对象的格式,在控制台中寻找到了重要线索。结合AI可以快速知晓函数具体作用。以及匿名函数、立即执行函数。
控制台输出的对象,其实也是很细致的,比如文本、字符串它的颜色是不一样的,function 也有特殊的标识。
问题并没有你想象的那么难处理,重要的是找对方法。
如果需要源码,公众号回复:plugin-demo
如果看到这里,你还是疑问,想要一对一技术指导,欢迎私信联系我。
记得点个赞咯~
评论区也可交流,想要不简说说什么技术,疑难解答。
下期再见👋🏻
AntD X Vue流式对话实战:实现Markdown渲染聊天机器人
前端工程化-包管理NPM-package.json 和 package-lock.json 详解
package.json 和 package-lock.json 详解
1.package.json
基本概念
package.json 是 Node.js 项目的核心配置文件,它定义了项目的基本信息、依赖项、脚本命令等。
主要字段
基本信息字段
name: 项目名称(必填)
version: 项目版本(必填,遵循语义化版本规范) 版本号形如:X.Y.Z,有三部分组成,依次叫主版本号、次版本号、修订号;
description: 项目描述
author: 作者信息
license: 开源许可证
依赖管理字段
dependencies: 生产环境依赖
devDependencies: 开发环境依赖
peerDependencies: 同伴依赖
optionalDependencies: 可选依赖
脚本字段
scripts: 定义可以通过 npm run 执行的脚本命令
其他配置
main: 项目入口文件
repository: 代码仓库信息
keywords: 关键词数组,用于 npm 搜索
engines: 指定 Node.js 和 npm 的版本要求
示例
{
"name": "my-project",
"version": "3.2.1",
"description": "A sample project",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "jest"
},
"dependencies": {
"express": "^4.17.1"
},
"devDependencies": {
"jest": "^26.6.3"
}
}
2.package-lock.json
基本概念
package-lock.json 是 npm 5+ 版本引入的文件,用于锁定依赖树的确切版本,确保不同环境下安装完全相同的依赖。
主要特点
自动生成:由 npm 自动创建和维护,使用 npm install 安装包后就会自动生成。
精确版本控制:记录每个依赖包的确切版本
依赖关系树:完整记录依赖树结构
安装优化:加快后续安装速度
文件作用
版本锁定:防止因语义化版本导致的意外升级
一致性保证:确保团队成员和 CI/CD 系统使用相同的依赖版本
安装效率:记录已解析的依赖树,避免重复计算
与 package.json 的关系
package.json 定义的是版本范围
package-lock.json 记录的是确切版本
当两者冲突时,以 package-lock.json 为准(npm 5+)
3.最佳实践
版本管理
将 package-lock.json 提交到版本控制系统
不要手动修改 package-lock.json
依赖安装
npm 安装包的方式分为本地安装和全局安装。安装使用npm install或简写形式npm i。
本地安装
使用 npm ci 命令(基于 package-lock.json 安装,用于生产环境)
使用 npm install <参数> <package-name> 命令(会更新 package-lock.json,用于开发环境)
全局安装
npm i -g <package-name>
npm i --global <package-name>
让安装的包放到对应依赖位置
开发依赖(devDependencies)中,传递参数 --save-dev 或 -D 即可。
生产依赖(dependencies)中,传递参数 --save 或 -S 即可。
不想放在开发依赖也不想放在生产依赖,使用npm install --no-save。
注意:包默认安装到生产依赖(dependencies)中
线上环境,只需要安装dependencies中的包,使用npm install --prod命令。
删除包
npm uninstall <package-name>
// 简写形式
npm un <package-name>
全局删除 npm uninstall -g <package-name>
更新依赖
使用 npm update 更新次要版本和补丁版本
使用 npm install package@version 更新主版本
安全考虑
定期运行 npm audit 检查安全漏洞
使用 npm audit fix 修复已知漏洞
4.常见问题
4.1: 为什么有时 node_modules 和 package-lock.json 会不一致?
通常是因为手动修改了 package.json 或在不同 npm 版本间切换导致的。可以删除 node_modules 和 package-lock.json 后重新安装。
4.2.可以删除 package-lock.json 吗?
不推荐,删除后会导致依赖版本不确定性,可能引入兼容性问题。
4.3. yarn.lock 和 package-lock.json 有什么区别?
两者功能类似,都是锁定依赖版本,只是格式不同。yarn.lock 是 Yarn 包管理工具生成的。