Loading... ## Ant的优势之处 AntDesign目前在前端是使用的非常广泛的一个前端资源库,其拥有丰富的组件 这一点特别是在ant-design-pro上体现的更明显,对比与element-ui上,一般在处理复杂后台业务的时候建议使用ant,在处理想要更好更漂亮的ui时建议使用element ## 关于Input组件的@clear事件 关于Input输入框组件上,element-ui和ant都提供了clear用于清空当前用户的输入内容 ```javascript <el-input placeholder="请输入内容" v-model="input" clearable @clear='fireEvent' /> <a-input placeholder="请输入内容" allow-clear @change="onChange" /> <a-input-search placeholder="请输入内容" allow-clear @change="onChange" @search='fireSearch' /> ``` 但是他们的不同之处是element提供了clear事件之后的回调,而ant并未提供该功能 ant这里倒是有一个类似的`a-input-search`的能力`(@search)`来对事件进行触发,但是回看官方文档就会发现,Enter和Clear动作都会导致`(@search)`的触发,其定制化并不符合我们的需求,我只想要@clear的回调,因此可能要涉及到对ant组件库中Input组件的功能进行调整 ## 源码跟踪 1. 首先我们跟踪到ant中Input组件的源码,找到对应的`/input/index.js`,然后发现实际组件是`/input/Input.js`文件  2. 跟踪后发现其引用了另一个文件`/input/ClearableLabeledInput.js`然后跟踪发现在#34有一个`renderClearIcon`方法,该方法最后渲染出来了一个clear按钮,并且具有onclick事件`handleReset`  3. 查看调用发现该事件函数的定义在`/input/Input.js`中 ```javascript handleReset: function handleReset(e) { var _this2 = this; this.setValue('', function () { _this2.focus(); }); resolveOnChange(this.$refs.input, e, this.onChange); }, ``` 4. 根据3中的发现,其实最终的问题就是onclear之后,事件没有向上抛出一个@clear的emit消息,因此我们只需要在这里增加一行`this.$nextTick(() => this.$emit('clear', e))`就可以解决这个clear事件的触发 5. 现在的问题是,我们如何去修改他的源码,并且还能在prod打包的时候也生效 ## 修改方案 这里根据vite的文档我们引入了一个外部的库来ant的原始代码进行变更:`@rollup/plugin-replace` 文档地址:[https://www.npmjs.com/package/@rollup/plugin-replace](https://www.npmjs.com/package/@rollup/plugin-replace) 其实际原理就是在开发模式和编译模式下,都对其源代码进行拦截并修改 这里提供一下,我这里的修改方案: ```javascript const fs = require('fs') const replace = require('@rollup/plugin-replace') const defaultReg = /(@ant-design-vue-v1\\design\\es\\input\\Input\.js)|(@ant-design-vue-v1\/design\/es\/input\/Input\.js)/ const exportFn = (reg = defaultReg) => { return { name: 'vite-plugin-qdesign-input-clear-event-resolver', configResolved(config) { // 以来预构建时候替换 esbuild config.optimizeDeps.esbuildOptions.plugins = config.optimizeDeps .esbuildOptions.plugins ? config.optimizeDeps.esbuildOptions.plugins : [] config.optimizeDeps.esbuildOptions.plugins.push({ name: 'replace-code', setup(build) { // MARK 调试的时候可以尝试直接idea启动debug模式,加断点,确认代码的执行无误 // MARK 页面debugger确认的时候先用调试编译,触发debug模式的断点,触发资源更新,然后再正常启动触发页面的断点,可能会快一些 build.onLoad( { filter: reg, }, (args) => { // 首先获取源代码内容 let source = fs.readFileSync(args.path, 'utf8') source = source.replace('var _this2 = this;', `var _this2 = this;this.$nextTick(()=>this.$emit('clear', e))`) return { contents: source, } }, ) }, }) // 添加打包时的替换 rollup config.plugins.push( replace({ // MARK 调试的时候断点加在:@rollup/plugin-replace/dist/rollup-plugin-replace.cjs.js // MARK 然后调用idea的debug模式,触发断点,调试速度最快 values: { 'var _this2 = this;': (id) => { return `var _this2 = this;this.$nextTick(()=>this.$emit('clear', e))` }, }, delimiters: ['', ''], // replace方法在进行匹配的时候是采用的正则,因此会自动带上前缀和后缀['\\b', '\\b(?!\\.)'],按需使用 include: [reg], preventAssignment: true, }), ) }, } } module.exports = exportFn ``` 在上面的代码中#4行表示了在rollup中需要匹配的文件正则-适配linux和windows 其主要替换代码在#26和#41行 自此,AntDesignVue的Input输入框就具有了清空会回调的能力,Input.TextArea也有这个问题,可以按需增加 自此,我们就可以正常使用ant中Input组件的@clear事件了 ```javascript <a-input placeholder="请输入内容" allow-clear @clear="clearEventFire" /> ``` 最后修改:2022 年 07 月 27 日 11 : 26 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,或者你想py,请随意赞赏 ×Close 赞赏作者 扫一扫支付 支付宝支付 微信支付