需求
vue template里面的事件名只能已on 开头
实现效果
实现步骤
创建调试程序和 eslint 插件程序
创建调试程序
我创建的文件夹名称为eslint-demo
pnpm create vue
创建eslint 插件程序
我创建的文件夹名称为v-on-name-sartwith-on
首先安装eslint 脚手架
pnpm i -g yo
pnpm i -g generator-eslint
生成 Eslint 插件工程。
yo eslint:plugin
为插件创建一条规则,执行如下命令:
yo eslint:rule
文件目录参考
link 插件
在v-on-name-sartwith-on 这个项目里面执行
pnpm link --global
在eslint-demo 这个项目里面执行(注意, 这里的名称是package.json 里面的名称)
pnpm link --global eslint-plugin-v-on-handler-name-style
编写代码
eslint-demo项目 App.vue
<script setup>
const handler = () => {
console.log('123')
}
</script>
<template>
<p @click="handler" class="a"></p>
</template>
v-on-name-sartwith-on 项目
lib/index.js
/**
* @fileoverview 判断 v-on 的 handler 是否已 on 开头
* @author abigmiu
*/
'use strict';
// const vueParser = require.resolve('vue-eslint-parser');
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const requireIndex = require('requireindex');
//------------------------------------------------------------------------------
// Plugin Definition
//------------------------------------------------------------------------------
const rules = requireIndex(__dirname + '/rules');
module.exports = {
configs: {
recommended: {
plugins: ['v-on-handler-name-style'],
rules: {
'v-on-handler-name-style/v-on-handler-name-style': ['error'],
},
},
},
parser: require.resolve('vue-eslint-parser'), // 这里可能要安装vue-eslint-parser
env: {
browser: true,
es6: true,
},
rules: rules,
};
lib/rules/v-on-handler-name-style.js
/**
* @fileoverview 判断 v-on 的 handler 是否已 on 开头
* @author abigmiu
*/
'use strict';
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion',
docs: {
description: '判断 v-on 的 handler 规则',
},
fixable: 'code', // Or `code` or `whitespace`
schema: [],
messages: {
error: '事件名不已 on 开头',
},
},
create(context) {
// variables should be defined here
//----------------------------------------------------------------------
// Helpers
//----------------------------------------------------------------------
// any helper functions should go here or else delete this section
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
return context.parserServices.defineTemplateBodyVisitor({
"VAttribute[directive=true][key.name.name='on'][key.argument!=null]"(
node
) {
const value = node.value;
if (value.type === 'VExpressionContainer') {
const expression = value.expression;
const reg = /^on[A-Z]/;
if (!reg.test(expression.name)) {
context.report({
node,
messageId: 'error',
loc: value.loc,
});
}
}
},
// visitor functions for different types of nodes
});
},
};
为什么需要context.parserServices.defineTemplateBodyVisitor
vue-eslint-parser提供了以下三个处理api 方法:// 处理 template 语法树遍历方法 // Define handlers to traverse the template body context.parserServices.defineTemplateBodyVisitor() // 获取缓存的 template 语法树结构 context.parserServices.getTemplateBodyTokenStore() // 获取根结点 document fragment. context.parserServices.getDocumentFragment()
VAttributedirective=true[key.argument!=null] 这个选择器怎么确定的
AST explorer 用这个网站, 注意红框位置, 要选择对应的选择器 才能选择
参考链接
手把手教你实现一个自定义 eslint 规则 - 掘金 (juejin.cn)
写一个 eslint 插件:vue template 中 class 顺序的检查和自动修复 - 掘金 (juejin.cn)