基于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前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Node.js 可以使用 readline 模块来实现交互式界面。首先需要引入 readline 模块,然后使用 createInterface 方法创建一个 readline.Interface 实例,接着使用 on 方法监听用户输入事件,使用 question 方法向用户提问并获取用户输入,最后使用 close 方法关闭 readline.Interface 实例。以下是示例代码: ``` const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.on('line', (input) => { console.log(`用户输入了:${input}`); }); rl.question('请输入您的姓名:', (answer) => { console.log(`您好,${answer}!`); rl.close(); }); ``` 在上面的示例中,当用户输入一行文本时,会触发 line 事件,并将用户输入的文本作为参数传递给回调函数。当用户回答问题并按下回车键时,会触发 question 回调函数,并将用户输入的文本作为参数传递给回调函数。最后使用 close 方法关闭 readline.Interface 实例。 希望这个回答对你有帮助! ### 回答2: 要开发出一个良好的交互式界面,可以使用Node.js配合其他相关技术。 首先可以使用Node.js的核心模块`readline`来处理命令行交互。`readline`模块提供了多种方法来读取用户输入和输出文本,可以实现简单的交互逻辑。可以使用`createInterface`方法创建一个`Interface`实例,然后通过`question`方法向用户提问并获取输入,使用回调函数处理用户输入。还可以使用`on`方法监听用户按下某个键的事件。 除了`readline`,还可以使用相关的第三方包来实现更复杂的交互界面。例如,可以使用`Inquirer.js`来构建命令行交互界面,它提供了很多种选择和输入的方式,并且可以自定义各种交互元素的样式。 另外,还可以使用Web技术来构建一个图形化的交互界面。可以使用Node.js的`http`模块创建一个HTTP服务器,然后使用HTML、CSS和JavaScript来开发前端界面。可以使用前端框架如React、Vue.js等来组织和管理界面的组件和数据。通过HTTP接口,前端界面和后端可以实现数据通信和交互。 在开发过程中,需要注意以下几点来保证良好的用户体验: 1. 提供清晰的提示和说明,让用户知道如何操作和输入。 2. 对输入进行验证和处理,确保输入的合法性和安全性。 3. 对界面进行良好的设计和布局,使其易于理解和使用。 4. 及时处理用户输入和请求,给予及时反馈和响应。 5. 可以提供帮助文档或指令来辅助用户操作。 总之,使用Node.js可以根据需求选择适合的技术和工具来开发出良好的交互式界面,提高用户体验。 ### 回答3: 要开发一个良好的交互式界面,你可以使用Node.js中的以下工具和库: 1. Readline模块:可以使用readline模块来创建命令行交互界面。它提供了接收用户输入、输出文本、设置事件处理等功能,非常适合创建简单的交互界面。 2. Inquirer.js库:Inquirer.js是一个功能强大的交互式命令行界面库,可以快速构建菜单、问题和提示,通过调用它提供的方法来设置问题、选项和事件处理程序,从而与用户进行交互。 3. Blessed库:Blessed是一个用于构建命令行界面的JavaScript库。它提供了各种组件、布局等功能,可以创建各种复杂的交互式界面,如图表、表格、列表等。 4. Socket.io库:如果你希望在用户界面中实现实时的交互和通信,可以使用Socket.io库。它提供了一个基于事件的实时通信框架,可以在服务器端和客户端之间实现双向通信,使得实时更新和操作成为可能。 5. Web框架:如果你希望创建一个基于Web的交互界面,你可以选择使用Node.js的Web框架,如Express或Koa。这些框架提供了路由、中间件、模板引擎等功能,可以创建具有良好交互性的Web界面。 总结起来,Node.js提供了多种工具和库来开发良好的交互式界面,你可以根据你的需求选择合适的工具和库来实现你想要的交互效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JYeontu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值