vue中登录性能优化--防抖

前端性能优化防抖:防止抖动,单位时间内事件触发会被重置,避免事件被误伤触发多次。代码实现重在清零 clearTimeout。防抖可以比作等电梯,只要有一个人进来,就需要再等一会儿。业务场景有避免登录按钮多次点击的重复提交。

多次触发事件时清除上一次触发的setTimeout,保证setTimeOut中的function在最近一次触发事件后的delayed时间才执行。

本文参考了这个https://github.com/zhaodongming/debounce-throttling

vue代码实现:
html部分(用了elementUI框架)

            <el-form
              :model="param"
              :rules="rules"
              ref="param"
              label-width="80px"
              class="ms-content"
            >
              <el-form-item
                prop="username"
                label="账号:"
                style="margin-bottom:42px"
              >
                <el-input
                  prefix-icon="iconfont el-icon-user"
                  v-model="param.username"
                  placeholder="请输入用户名"
                >el-input>
              el-form-item>
              <el-form-item prop="password" label="密码:">
                <el-input
                  prefix-icon="iconfont el-icon-lock"
                  type="password"
                  placeholder="请输入密码"
                  v-model="param.password"
                >
                el-input>
              el-form-item>
                <el-button
                  id="submitbtn"
                  style="width:100%;height:40px;margin-top:20px"
                  type="primary"
                  >登录el-button
                >
            el-form>

js
下面的clickFun 设置了delayed为1000,当鼠标在点击登录按钮时,连续快速点击n次,每次间隔不超过1秒钟,点击第一次后不到一秒再点击第二次,则第一次的setTimeOut事件被clearTimeout清除,以此类推,当点击第n次后1秒内不再点击,则不再执行clearTimeout,setTimeOut中的function方法执行。


<script>
export default {
  data() {
    return {
      param: {
        username: '',
        password: '',
        type: ''
      },
      rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
      }
    };
  },
  mounted() {
	this.submitFun();
  },
  methods: {
  submitFun() {
      let domSubmit = document.getElementById('submitbtn');
      let clickFun = this.debounce(() => {
        console.log('防抖成功');
        this.submitForm('param');
      }, 1000);
      domSubmit.addEventListener('click', clickFun); // 监听click事件
      window.onkeydown = function(event) { // 监听回车登录事件
        var e = event || window.event;
        if (e && e.keyCode == 13) {
          //回车键的键值为13
          //调用登录按钮的登录事件
          clickFun();
        }
      };
    },
    debounce(fun, delayed) {
      let timeout = null; 
      // 使用闭包,让每次调用时点击定时器状态不丢失
      return function() {
        let context = this;
        let args = arguments;
        clearTimeout(timeout);  // 多次触发事件时清除上一次触发的setTimeout,保证setTimeOut中的function在最近一次触发事件后的delayed时间才执行。
        timeout = setTimeout(function() {
          fun.apply(context, args);
        }, delayed);
      };
    },
    // 这个submitForm中的方法是项目需要,里面不用照抄
    submitForm(formName) {
      const params = this.param;
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.axios
            .post('/xxx/login', {
              grantType: 'password',
              account: this.param.username,
              password: this.param.password, 
              clientType: 0
            })
            .then(res => {
              if (res.data.Type == 200) {
                sessionStorage.setItem('user_token', res.data.Data.AccessToken);
                this.axios
                  .get('/xxx/xxx', {
                    headers: {
                      Authorization:
                        'Bearer ' + sessionStorage.getItem('user_token')
                    }
                  })
                  .then(info => {
                    if (info.data == 'MainMenu') {
                      this.$message.success('登录成功');
                      localStorage.setItem('ms_username', this.param.username);
                      this.$router.push('/route/xxx');
                    } else {
                      this.$message.warning('token错误,请重新登录!');
                    }
                  })
                  .catch(err => {
                    console.log(err);
                  });
              } else {
                this.$message.error(res.data.Content);
              }
            })
            .catch(err => {
              console.log(err);
            });
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    }
  }
}
</script>

html示例移步https://github.com/zhaodongming/debounce-throttling

你可能感兴趣的:(前端性能优化,vue,js,前端性能优化)