4

三个技巧高效写 Element UI(Vue)

 2 years ago
source link: https://ssshooter.com/2021-10-16-efficient-element-ui/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
2021-11-23coding

安装 element-ui-helper 插件,可得到 element ui 悬停提示,不用每次都翻文档。

缺点也是有一点,tips 的显示框有点小了,不过跟插件本身也没关系,查了一下,vscode 暂时还没有提供可以修改 tips 大小的方法,只有修改 vscode 全局 css 的 workaround

如果还是有其他需要自己魔改的话,GitHub 仓库在此,vscode API 文档看这里

Snippet

snippet 的意思就是“代码片段”,一般我们不会记住 ui 框架的细节,记住组件名字就差不多得了,但是只知道名字怎么用呢……

一般来说自然是在文档找关键字,然后 ctrl+c/v,但是借助 snippet,可以让 vscode 给你找组件代码。

虽然可以通过插件安装 snippet,但是更灵活的方法是用 ctrl+P 创建 snippet 文件。

snippet 文件的结构大概就这样:

{
  "Basic: Layout el-row": {
    "prefix": "elrow",
    "body": [
      "<el-row :gutter=\"${1:20}\">",
      "\t<el-col :span=\"${2:12}\" :offset=\"${3:0}\">${4}</el-col>",
      "\t<el-col :span=\"${5:12}\" :offset=\"${6:0}\">${7}</el-col>",
      "</el-row>",
      "${8}"
    ],
    "description": "Element UI <el-row> with <el-col>"
  }
}

"Basic: Layout el-row" 是 snippet 的名称,对象是 snippet 的详细配置:prefix 指只需要输入 elrow 就会出现可选择的提示,description 是对这个 snippet 的描述,选择该 snippet 就能自动输入 body 的内容。

Element-UI-Snippets 仓库中,找到 snippets 文件夹下的两个 json 文件,贴到你创建的 snippet 就可以了。

plop 就要比前面两项复杂许多,这是一个根据用户配置生成高度重复代码文件的工具。说到重复代码生成,很容易想到各种低代码解决方案,例如 form-generator,确实可以比较方便地解决表单生成问题,但是对于有相同关联逻辑的多个页面,只生成一个表单也不太够。还有其他只需要 json 配置即可含逻辑的页面的工具,不过也有很大的局限性,毕竟生成的东西不一定好改,如果某些细节需要定制的话将会变得十分麻烦。

所以最后还是选择 plop 吧,自己写模板,至少自己的需求是可以完美满足的!

plop 大概由三个部分组成,其中关系后面会说到:

使用 plop 的第一步是写一个 plopfile.js,这个文件一般长这样:

module.exports = function(plop) {
  plop.setHelper('equal', function(a, b) {
    return a === b
  })
  plop.setGenerator('table-view', tableViewGenerator)
}

其实就是写一个函数,plop 会给你注入 plop 对象,你就能调用各种方法实现你的代码生成需求,最常使用的函数就是 setHelpersetGenerator

文档传送门:https://plopjs.com/documentation/#setgenerator

配置中最重要的是 setGenerator,在配置生成器时,有三个参数 description(非必填)、promptsactions

prompts

配置 prompts 对用户的提问时使用了 Inquirer.js,所以要查怎么配提问还得到 Inquirer.js 的文档查询。

const prompts = [
  {
    type: 'input',
    name: 'name',
    message: 'view name please',
    validate: notEmpty('name'),
  },
]

不过在我的工作场景中基本不怎么依赖 Inquirer.js,因为配置太复杂了,还不如直接写一份 json 来得快(但是……prompts 是必填项,所以只好象征性地留一个 name 使用 prompts 提问)。

另外,也可以通过 plop.setPrompt 配置可复用的 prompt。

actions

接着是 actions,跟 prompt 一样,action 也有类似的配置方法 setActionType,但是一般我们只用两种内置 action:addaddMany 就可以了。

因为 add 比较简单感觉没什么需要特别注意,这里举例一个 addMany 的配置:

const actions = [
  {
    type: 'add',
    templateFile: 'plop/table-view/api.js.hbs',
    path: `src/api/alert/${name}.js`,
  },
  {
    type: 'addMany',
    templateFiles: 'plop/table-view/**/*.vue.hbs',
    destination: `src/views/${name}`,
    base: 'plop/table-view',
    stripExtensions: ['hbs'],
  },
]

add 是一个模板对应一个结果文件,所以你可以很清晰地指定结果文件的位置和文件名,但是 addMany 是一组模板的生成,配置的东西自然多一点。

要生成多个文件甚至一个文件夹,最重要的是 templateFiles 字段,这是一个 glob 字符串,这 globblob 没啥关系,反而有点像正则表达式,中文叫通配符,就是用特定规则匹配一系列结果的小工具,下面是几条很简单的规则:

  • * 匹配 / 除外任何字符
  • ? 匹配 / 除外任何 1 个字符
  • ** 匹配包括 / 的任何字符
  • {} 用逗号隔开可以产生“或”的效果
  • ! 出现在开头表示取反

'plop/table-view/**/*.hbs' 的意思就是 plop/table-view 下的所有 hbs 文件(hbs 就是一个模板引擎,后面详细讲)。

destination 是生成文件的目标文件夹,base 是生成文件可能需要把外层文件夹去掉,可能说起来不太清楚,实践一下就很好理解了。

stripExtensions 用于处理“模板到结果”的文件名转换问题,因为 addMany 不像 add 可以指定目标文件名,那么整个文件夹搬过去不能改名字就出大问题了,直接一个 hbs 文件,怎么搞嘛,而这个字段就是用于删除多余的 hbs 后缀,模板文件可以这样命名:example.vue.hbs,生成的结果就是 example.vue

有时候我们的需求不只是生成新的文件,还要往老文件新增一些代码,最典型的就是加一个页面的时候还需要在路由文件新增路由,这时候就可以使用 append action。

const actions = [
  {
    type: 'append',
    path: 'src/router/index.js',
    pattern: '// insert new route',
    templateFile: 'plop/router/index.hbs',
  },
]

看配置不难理解,其实就是在 path 所在的文件夹中搜寻 pattern(可以是 RegExp),然后在找到的位置 append 一段模板。

handlebars

plop 的目的是生成一份或一系列定制的代码文件,上面说了获取用户输入数据,借用了 Inquirer.js,而模板语言使用的正是 handlebars。

对于习惯写 Vue template 的用户来说,写 handlebars 模板需要一些思维转换(例如十分熟悉的 {{ x || y }} 的写法行不通,也没有直接 elseif 的方法),不过还好,官方提供了 playground,能让刚接触 hbs 的用户比较直观地尝试各种特性。

说到 helper 有没感觉前面看到过,没错,plop 的 setHelper 其实就是给 handlebars 设置 helper。

举个例子,要做到 Vue 模板 {{ x || y }} 的效果,需要自定义一个 helper:

Handlebars.registerHelper('coalesce', function(a, b) {
  return a || b
})

上面是 handlebars 原生的 helper 注册,在 plop 中则是使用 plop.setHelper,传参都一样。在配置 helper 后,在模板里写 coalesce x y 就能达到 {{ x || y }} 的效果。

需要特别注意,如果你在 handlebars 模板的 {{}} 里填写一个以上的关键字,就会自动变成调用 helper 了

另外还有一个常见小问题,就是 hbs 和 vue 模板的冲突,单行可以用 \,多行可以用 {{{{raw}}}} 直接输出 {{}}

\{{escaped}}
{{{{raw}}}}
  {{escaped}}
{{{{/raw}}}}

自带 helper

plop(非 hbs)自带了一些 helper,都用于处理字符串格式:

  • camelCase: changeFormatToThis
  • snakeCase: change_format_to_this
  • dashCase/kebabCase: change-format-to-this
  • dotCase: change.format.to.this
  • pathCase: change/format/to/this
  • properCase/pascalCase: ChangeFormatToThis
  • lowerCase: change format to this
  • sentenceCase: Change format to this,
  • constantCase: CHANGE_FORMAT_TO_THIS
  • titleCase: Change Format To This
  • 提示插件让你省去翻文档的时间
  • snippet 让你免受手打组件代码的麻烦
  • 简单的表单生成需求直接使用表单生成器也不失为一个好方法
  • 对于表格、表单、包括 api 相关逻辑的生成,使用 plop 定制的生成代码会非常爽

其实不只是 element-ui,所有框架都是这个思路,只不过 element-ui 刚好能找到现成的。最后,省下来的时间,可以造造新轮子,分享一下 plop 配置,创造美好前端新世界。(此处有一个若隐若现的狗头


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK