element系列 - input 改造

361 阅读1分钟

系列

element系列 - input 改造

element系列 - select 改造

element系列 - form 改造

element系列 - tree 改造

element系列 - pagination 改造

需求

  • 密码框不要自动记住密码
  • 密码框后面的显示/关闭密码图片更换

对 element input 的改造基于需求,为什么要改造呢,因为element组件的参数不能满足需求了,要么改源码,要么如下Hack:

github项目地址

密码框不要自动记住密码

这个密码框不要自动记住密码真实让人深恶痛绝,有些产品非要去掉这个记住密码功能,而你又束手无措,改造 el-input一劳永逸

官方策略:

developer.mozilla.org/zh-CN/docs/…

autocomplete="off"autocomplete="new-password" 都是不行的,但是不妨碍演示

import Vue from 'vue'
import { Input } from 'element-ui'
export const elInputOffAutoHack = Vue => {
    const autoCompleteHack = {
        props: {
          /**
           * 控制初始是否默认关闭密码框密码填充功能
           * 传false时即可关闭mounted中dom操作的逻辑
           * 如登录页面的填充还是有必要
           */
          defaultOffAutoCompletionPassword: {
            type: Boolean,
            default: true
          }
        },
        mounted() {
          if (this.defaultOffAutoCompletionPassword && this.type == 'password') {
            this.$refs?.input.setAttribute('autocomplete', 'new-password')
          }
        }
    }
    Object.assign(Input, {
        mixins: [...(Input.mixins || []), autoCompleteHack]
    })
    Vue.use(Input)
}
Vue.use(elInputOffAutoHack)

另可以试试: 你可以给Input设置一个默认的readonly属性,然后 onfocus="this.removeAttribute('readonly');" onblur="this.setAttribute('readonly',true);"来改变这个状态让输入框可以输入或者只读,这样就不会被记住密码填充了

密码框后面的显示/关闭密码图片更换

el-input密码框后面的眼睛图标是内置的,不能通过参数传递,需求是换两张不同图标

image.png

思路: 看 el-input 源码,图标编辑时会触发 handlePasswordVisible 函数,于是重写 handlePasswordVisible函数,加上自定义两种图标的css样式

import Vue from 'vue'
import { Input } from 'element-ui'
import { removeClass, addClass, on } from 'element-ui/lib/utils/dom'
export const elInputEyeIconHack =  Vue => {

  const handlePasswordVisible = Input.methods.handlePasswordVisible

  const ClassMap = {
    open: 'my-icon-eyes-open',
    close: 'my-icon-eyes-close'
  }
  const passwordEyeIconHack = {
    props: {
      changePasswordEyeIcon: {
        type: Boolean,
        default: true
      }
    },
    mounted() {
      if (this.toggleEyeIcon) {
        on(this.getInput(), 'focus', () => {
          this.innerEyeDomHack()
        })
      }
    },
    computed: {
      toggleEyeIcon: {
        get() {
          return (
            this.showPassword &&
            this.changePasswordEyeIcon &&
            this.type !== 'textarea'
          )
        }
      }
    },
    methods: {
      innerEyeDomHack(element) {
        this.$nextTick(() => {
          element =
            element ||
            this.$el.querySelector(
              '.el-input__suffix-inner .el-input__icon.el-icon-view'
            )
          if (this.toggleEyeIcon) {
            const type = this.getInput().getAttribute('type')
            if (type === 'password') {
              removeClass(element, ClassMap.open)
              addClass(element, ClassMap.close)
            } else {
              removeClass(element, ClassMap.close)
              addClass(element, ClassMap.open)
            }
          }
        })
      }
    }
  }

  Object.assign(Input, {
    mixins: [...(Input.mixins || []), passwordEyeIconHack]
  })
  Object.assign(Input.methods, {
    handlePasswordVisible(...args) {
      handlePasswordVisible.apply(this, args)
      this.innerEyeDomHack(args[0].target)
    }
  })

  Vue.use(Input)
}


Vue.use(elInputEyeIconHack)

效果:

眼睛开闭图标就是两个自定义的了

image.png

image.png