// Vue Add Attribute Loader // 用于在构建时为Vue文件的button标签添加name属性和权限控制属性 const { parse, compileTemplate } = require('@vue/compiler-sfc') module.exports = function(source) { const callback = this.async() try { // 解析Vue文件 const { descriptor } = parse(source, { filename: this.resourcePath }) if (!descriptor.template || !descriptor.template.ast) { // 如果没有template,直接返回原内容 return callback(null, source) } let modified = false // 遍历AST,找到button节点并添加属性 const addAttributesToButton = (node) => { if (node.type === 1 && node.tag === 'button') { // 检查是否已经有name属性 const hasNameAttr = node.props.some(prop => prop.type === 6 && prop.name === 'name' ) if (!hasNameAttr) { // 生成唯一的name值 const componentName = this.resourcePath.split('/').pop().replace('.vue', '').toLowerCase() const uniqueSuffix = Math.random().toString(36).substr(2, 6) const nameValue = `${componentName}-${uniqueSuffix}` // 添加name属性 node.props.push({ type: 6, name: 'name', value: { type: 2, content: nameValue, loc: node.loc }, loc: node.loc }) // 检查是否已经有v-permission-control指令 const hasPermissionControl = node.props.some(prop => prop.type === 7 && prop.name === 'v-permission-control' ) if (!hasPermissionControl) { // 添加v-permission-control指令(不添加:disabled,避免重复) node.props.push({ type: 7, name: 'v-permission-control', exp: { type: 4, content: 'true', isStatic: false, loc: node.loc }, loc: node.loc }) } modified = true } } // 递归处理子节点 if (node.children) { node.children.forEach(addAttributesToButton) } } // 开始遍历AST addAttributesToButton(descriptor.template.ast) // 如果修改了AST,重新生成Vue文件 if (modified) { // 由于Vue编译器没有直接的AST到字符串转换,我们使用字符串替换的方式 // 先找到template部分 const templateMatch = source.match(/(]*>)([\s\S]*?)(<\/template>)/) if (templateMatch) { let templateContent = templateMatch[2] // 为每个button添加属性(使用字符串替换) templateContent = templateContent.replace( /]*?)(\s*\/?>)/g, (match, attrs, closing) => { // 检查是否已经有name属性 if (attrs.includes('name=')) { return match // 已经有name属性,不修改 } // 生成唯一的name值 const componentName = this.resourcePath.split('/').pop().replace('.vue', '').toLowerCase() const uniqueSuffix = Math.random().toString(36).substr(2, 6) const nameValue = `${componentName}-${uniqueSuffix}` // 检查是否已经有v-permission-control指令 const hasPermissionControl = attrs.includes('v-permission-control') // 构建新的属性字符串 let newAttrs = attrs newAttrs += ` name="${nameValue}"` if (!hasPermissionControl) { newAttrs += ` v-permission-control` } return `