Prompts:让生成器向你提问
🎯 引言
学完这篇文章,你将掌握 Plop 中 prompts 的常用写法。通过不同类型的问题,你可以让生成器在运行前收集必要的信息,比如文件名、是否创建样式文件、选择组件类型等。
🧱 prompts 的基本结构
prompts 是一个数组,每个元素是一个问题对象。Plop 底层使用 Inquirer 来实现命令行交互。
一个基本的问题对象包含这些字段:
{
type: 'input', // 问题类型
name: 'name', // 答案在模板中使用的变量名
message: '请输入名称', // 显示给用户的提示文字
default: 'MyComponent' // 默认值(可选)
}
用户回答后,答案会以 name 为键存储,在模板中通过 {{name}} 使用。
✨ 常用提问类型
input:文本输入
最常用的问题类型,适合获取名称、路径等字符串。
{
type: 'input',
name: 'name',
message: '请输入组件名称'
}
confirm:是 / 否
适合询问“是否需要某个可选文件”。
{
type: 'confirm',
name: 'hasStyle',
message: '是否需要创建样式文件?',
default: true
}
在模板中,hasStyle 的值是布尔类型。可以直接配合 {{#if hasStyle}} 使用。
list:单选
适合让用户从固定选项中选择一个。
{
type: 'list',
name: 'type',
message: '请选择组件类型',
choices: ['基础组件', '业务组件', '布局组件'],
default: '基础组件'
}
checkbox:多选
适合让用户一次性选择多个选项。
{
type: 'checkbox',
name: 'features',
message: '请选择需要生成的文件',
choices: ['script', 'style', 'test'],
default: ['script', 'style']
}
checkbox 返回的是一个数组。在模板中可以用 {{#each features}} 循环遍历。🛠 综合示例:生成组件时询问多个问题
下面我们写一个更贴近实际的生成器,创建组件时同时询问名称、类型和是否需要样式:
export default function (plop) {
plop.setGenerator('component', {
description: '创建一个 Vue 组件',
prompts: [
{
type: 'input',
name: 'name',
message: '请输入组件名称'
},
{
type: 'list',
name: 'type',
message: '请选择组件类型',
choices: ['base', 'business', 'layout'],
default: 'base'
},
{
type: 'confirm',
name: 'hasStyle',
message: '是否需要创建样式文件?',
default: true
}
],
actions: [
{
type: 'add',
path: 'src/components/{{pascalCase name}}.vue',
templateFile: 'plop-templates/component.hbs'
}
]
});
}
模板文件:
<template>
<div class="{{kebabCase name}}">
{{pascalCase name}} 组件
</div>
</template>
<script setup>
// 组件类型:{{type}}
</script>
{{#if hasStyle}}
<style scoped>
.{{kebabCase name}} {
/* {{type}} 组件样式 */
}
</style>
{{/if}}
运行后,如果选择需要样式,生成的文件会包含 <style> 块;否则不会。
⚡ 默认值与校验
default:给出默认答案
{
type: 'input',
name: 'name',
message: '请输入组件名称',
default: 'MyComponent'
}
用户直接回车就会使用 MyComponent。
validate:校验输入
{
type: 'input',
name: 'name',
message: '请输入组件名称',
validate: function (value) {
if (value.trim() === '') {
return '组件名称不能为空';
}
if (!/^[A-Z][a-zA-Z0-9]*$/.test(value)) {
return '组件名称必须以英文大写字母开头';
}
return true;
}
}
如果校验返回字符串,Plop 会把它当错误信息显示出来;返回 true 表示通过。
💡 根据上一题答案动态显示问题
使用 when 可以让某个问题只在特定条件下出现。
{
type: 'confirm',
name: 'hasTest',
message: '是否需要生成测试文件?',
default: false
},
{
type: 'input',
name: 'testName',
message: '请输入测试文件名称',
when: function (answers) {
return answers.hasTest;
}
}
只有当用户选择“需要测试文件”时,才会继续询问测试文件名称。
🧾 小节总结
prompts是问题数组,每个问题包含type、name、message等字段。- 常用类型有
input(文本)、confirm(确认)、list(单选)、checkbox(多选)。 default可以设置默认值,validate可以校验用户输入。when可以根据前面的答案决定是否显示当前问题。
❓ 知识问答
Q1:name 字段有什么作用?
A:name 是答案的变量名。用户回答的内容会保存在这个名下,模板中通过 {{name}} 使用。
Q2:confirm 类型返回什么值?
A:返回 true 或 false。可以直接在 Handlebars 模板中用 {{#if hasStyle}} 做条件判断。
Q3:list 和 checkbox 有什么区别?
A:list 是单选,返回一个字符串;checkbox 是多选,返回一个数组。
Q4:校验函数返回字符串和 true 分别代表什么?
A:返回字符串表示校验失败,字符串内容会作为错误提示显示;返回 true 表示校验通过。
🧪 小练习
请为 component 生成器增加一个问题:询问是否需要生成 props 定义。
{
type: 'confirm',
name: 'hasProps',
// 请在这里补全 message 和 default
}
然后在 component.hbs 模板中使用它:
{{#if hasProps}}
<script setup>
// 请在这里补全 props 定义代码
</script>
{{/if}}
🎉 恭喜你掌握了 Plop 的交互式提问!下一篇我们会学习 actions,了解生成器可以执行哪些具体动作。
