基于inquirer实现一个控制台多级选择交互功能

简介: 基于inquirer实现一个控制台多级选择交互功能

说在前面

🎈在前端脚手架工具中经常会看到控制台输入参数等操作。例如Vue-cli中初始化项目会提示选择一些参数等。所以在开发脚手架工具或者node控制台程序,就需要用到inquirer工具或者类似的工具。但是使用过inquirer工具的同学应该知道,目前inquirer工具支持的交互方式只有以下几种:input, number, confirm, list, rawlist, expand, checkbox, password, editor,最近自己在封装一个脚手架工具时需要使用到多级选择的功能来进行交互,但是看了一遍inquirer的文档,发现并没有可以直接使用的多级选择器类型交互,于是便开始基于inquirer进行二次封装,实现多级选择交互的功能。

效果展示

配置好参数后直接运行,效果如下图👇

实现思路

功能分解

首先我们先来分解一下这个功能,我们拥有一份树级结构的数据:

{
    'aa': [ 'aaa1', 'aaa2', 'aaa3', 'aaa4' ],
    'bb': [ 'bbb1', 'bbb2' ],
    'cc': [ 'ccc1' ]
}

我们需要实现以下这几个功能:

  • 1、按级展示对应的数据

接收的参数数据应该为树级结构的数据,我们应该对其进行分级展示(像电脑上的文件目录层级一样)。

  • 2、非叶子级的节点点击应该可以下钻

对于非叶子级的节点(及当前节点拥有子节点),我们对其点击应该进行下钻并展示其子节点的数据。

  • 3、叶子节点可以多选

遍历到叶子级别的数据时,我们需要支持多选功能。

  • 4、跨父节点数据保持

当我们进入一个叶子层级并进行了选择之后,我们还需要返回进入其他层级进行选择,这时我们需要保存在不同层级下选中的数据内容。

功能实现

将功能分解成几个小点之后,我们便可以按照分解好的功能点来逐点实现:

  • 1、按级展示对应的数据

这一点的功能其实就是一个单选选择框的功能,我们发现这点可以直接使用inquirer中类型为list的组件来实现。

const options = [{
    type: 'list',
    name: 'choice',
    message: 'your choice:',
    default: 0,
    choices: [
        { value: 1, name: '张三' },
        { value: 2, name: '李四' }
    ]
}];
const j = new JInquirer(options);
const res = j.prompt().then(res=>{
    console.log(res);
});

运行的结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xo1ZhUCX-1668566115879)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/922dda3d632a48c09de9c7c7d9dee17b~tplv-k3u1fbpfcp-watermark.image?)]

这里我们只需要将传入的树级结构数据遍历到的层级的key提出重新组成list的参数即可:

//叶子节点层级的数据应该为数组类型的数据,所以可以通过isArray来判断当前层级是否为叶子层级
optionTemp.type = Array.isArray(obj) ? 'checkbox' : 'list';
optionTemp.choices = Array.isArray(obj) ? obj : Object.keys(obj);
  • 2、非叶子级的节点点击应该可以下钻

遍历到非叶子层级时,我们需要递归处理其子级节点数据,非叶子层级的列表我们使用的是list单选列表来展示,叶子层级的数据我们使用的是checkbox多选列表来展示,所以我们可以根据当前展示的类别来进行不同的递归处理。

(1)非叶子层级

对于非叶子层级的数据,我们点击应该进入下一级:

await this.chooseExpandList(op,deep + 1,pre+answer[option.name],originOption);

(2)叶子层级

对于叶子层级的数据,我们选择完成后应该回到根节点级别继续选择:

await this.chooseExpandList(originOption,0,'',originOption);

完整关键代码如下:

if(optionTemp.type === 'list'){
    if(pre) pre += '/';
    const op = {...option};
    op.choices = obj[answer[option.name]];
    await this.chooseExpandList(op,deep + 1,pre+answer[option.name],originOption);
}else{
    this.tempList[pre] = answer[option.name];
    await this.chooseExpandList(originOption,0,'',originOption);
}
  • 3、叶子节点可以多选

叶子节点列表我们需要支持多选功能,这个功能我们可以直接复用inquirer中类型为checkbox的复选框来实现。

const options1 = [{
    type: 'checkbox',
    name: 'choice',
    message: 'your choice:',
    default: 0,
    choices: [
        { value: 1, name: '张三' },
        { value: 2, name: '李四' }
    ]
}];
const j = new JInquirer(options1);
const res = j.prompt().then(res=>{
    console.log(res);
});

运行结果如下图:

可以使用空格进行选择,ctrl + a 可以全选,ctrl + i 进行反选,回车确认选择内容。

  • 4、跨父节点数据保持

这里我们可以使用两个方案来实现:

(1)使用函数入参来记录选中的数据

我们可以将每次选中的数据在函数的入参中传入,每次回调时更新该参数即可。

(2)在类中添加一个参数来记录。

直接在类中添加一个公共参数来记录,这样读取会比较方便。

比较了两种方法后,我觉得还是直接在类中添加一个公共参数来记录,这样读取会比较方便,所以最后选择了使用方案二来实现该功能。

class JInquirer{
    constructor(options,config){
        this.options = options; //参数
        this.config = config || {}; //配置
        this.answer = {}; //输出结果容器
        this.tempList = {}; //中间值临时容器变量
    }
}

使用方法

1、安装依赖

npm install @jyeontu/j-inquirer

2、在代码中引用

const JInquirer = require('@jyeontu/j-inquirer');

3、示例代码

const options1 = [{
        type:"input",
        message:"请输入你的姓名:",
        name:"name",
        notNull:true
    },{
    type: 'expandList',
    name: 'choice',
    message: '多级选择器测试:',
    choices:{
        'aa': [ 'aaa1', 'aaa2', 'aaa3', 'aaa4' ],
        'bb': [ 'bbb1', 'bbb2' ],
        'cc': [ 'ccc1' ]
      }
}];
const j = new JInquirer(options1);
const res = j.prompt().then(res=>{
    console.log(res);
});

源码地址

https://gitee.com/zheng_yongtao/node-scripting-tool/tree/master/src/JInquirer

觉得有帮助的同学可以帮忙给我点个star,感激不尽~~~

有什么想法或者改良可以给我提个pr,十分欢迎~~~

有什么问题都可以在评论告诉我~~~

往期精彩

面试官:不使用canvas怎么实现一个刮刮卡效果?

vue封装一个3D轮播图组件

vue实现一个鼠标滑动预览视频封面组件(精灵图版本)

node封装一个图片拼接插件

基于inquirer封装一个控制台文件选择器

node封装一个控制台进度条插件

密码太多不知道怎么记录?不如自己写个密码箱小程序

微信小程序实现一个手势图案锁组件

vue封装一个弹幕组件

为了学(mo)习(yu),我竟开发了这样一个插件

程序员的浪漫之——情侣日常小程序

vue简单实现词云图组件

说在后面

🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。

目录
相关文章
|
6月前
|
计算机视觉 索引
扫雷-包含空白展开,标记功能,游戏界面优化-控制台全力复刻
扫雷-包含空白展开,标记功能,游戏界面优化-控制台全力复刻
|
6月前
IntelliJ IDEA 自定义控制台输出多颜色格式功能 --- 安装Grep Console插件
IntelliJ IDEA 自定义控制台输出多颜色格式功能 --- 安装Grep Console插件
1261 0
|
3月前
|
Unix Linux C#
增强用户体验:2个功能强大的.NET控制台应用帮助库
增强用户体验:2个功能强大的.NET控制台应用帮助库
|
存储 监控 Cloud Native
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版功能演示(上)——二、使用控制台
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版功能演示(上)——二、使用控制台
|
CDN
CDN设置防盗链及使用鉴权功能——鉴权URL控制台生成
CDN设置防盗链及使用鉴权功能——鉴权URL控制台生成自制脑图
328 0
CDN设置防盗链及使用鉴权功能——鉴权URL控制台生成
|
人工智能 监控 安全
RPA 流程梳理和适用场景以及控制台功能展示(二)| 学习笔记
快速学习 RPA 流程梳理和适用场景以及控制台功能展示。
RPA 流程梳理和适用场景以及控制台功能展示(二)| 学习笔记
|
Web App开发 文字识别 负载均衡
RPA 流程梳理和适用场景以及控制台功能展示(一)|学习笔记
快速学习 RPA 流程梳理和适用场景以及控制台功能展示(一)
823 0
RPA 流程梳理和适用场景以及控制台功能展示(一)|学习笔记
|
弹性计算 监控 对象存储
ROS 控制台功能概览|学习笔记
快速学习 ROS 控制台功能概览
ROS 控制台功能概览|学习笔记
|
Java
JAVA——实现使用控制台模拟实际开发中上传用户头像的功能
JAVA——实现使用控制台模拟实际开发中上传用户头像的功能
277 0
JAVA——实现使用控制台模拟实际开发中上传用户头像的功能
|
存储 JSON 弹性计算
SLS控制台日志下载功能全新升级
阿里云日志服务(SLS)支持将日志或查询分析结果下载到本地,并提供了控制台、Cloud Shell、SLS CLI以及SLS SDK四种下载方式下载日志。控制台下载的方式无需用户进行额外的配置或部署,只需一些简单的控制台操作便可完成下载,相较于另外三种方式更加便捷、易用,也更受大部分用户的青睐。
796 0
下一篇
无影云桌面