目标

  • [] 11:00-12:00 typescript
  • [] 15:00-16:00 vue3
  • [] 16:30-17:30 英语

琐碎

今天做了一个滑动验证的功能

前备知识

ontouchstart,ontouchmove 和 ontouchend 事件是为触摸设备设计的,它们分别对应于鼠标事件 mousedown,mousemove 和 mouseup。

ontouchstart 事件在用户触摸屏幕时触发,类似于鼠标事件 mousedown。 ontouchmove 事件在用户移动手指时触发,类似于鼠标事件 mousemove。 ontouchend 事件在用户停止触摸屏幕时触发,类似于鼠标事件 mouseup。 不同之处在于,触摸事件支持多点触控,可以处理多个手指的输入。因此,触摸事件对象包含一个名为 changedTouches 的属性,该属性是一个数组,包含了每个手指的信息。而鼠标事件只能处理单个鼠标指针的输入。

组件
<template>
  <div>
    <div class="movebox" ref="movebox">
      <div class="movego"></div>
      <div class="txt" id="txt">按住滑块,拖动到最右边</div>
      <div class="move moveBefore" v-move="pull"></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  directives: {
    move(el, binding) {
      const moveCompution = (endx, type = 1) => {
        el.className = "move moveBefore";
        el.style.left = endx + "px";
        let width =
          document.querySelector(".movebox").offsetWidth -
          document.querySelector(".move").offsetWidth;
        el.parentNode.children[0].style.width = endx + "px";
        el.parentNode.children[1].innerHTML = "按住滑块,拖动到最右边";
        if (endx <= 0) {
          el.style.left = 0 + "px";
          el.parentNode.children[0].style.width = 0 + "px";
        }
        if (parseInt(el.style.left) >= width) {
          el.style.left = width + "px";
          el.parentNode.children[0].style.width = width + "px";
          el.parentNode.children[1].innerHTML =
            "<span style='color:#fff'>验证通过</span>";
          el.className = "move moveSuccess";
          if (type === 1) {
            document.ontouchmove = null;
            el.ontouchstart = null;
          } else {
            document.onmousemove = null;
            el.onmousedown = null;
          }
          binding.value();
        }
      };
      const move = function (e) {
        if (e.changedTouches && e.changedTouches.length > 0) {
          let Y = e.changedTouches[0].clientX - el.offsetLeft;
          document.ontouchmove = function (e) {
            let endx = e.changedTouches[0].clientX - Y;
            moveCompution(endx, 1);
          };
        } else {
          let X = e.clientX - el.offsetLeft;
          document.onmousemove = function (e) {
            let endx = e.clientX - X;
            moveCompution(endx, 2);
          };
        }
      };

      el.onmousedown = move;
      el.ontouchstart = move;

      document.ontouchend = function () {
        document.ontouchmove = null;
        document.onmousemove = null;
      };

      document.onmouseup = function () {
        document.onmousemove = null;
        document.ontouchmove = null;
      };
    },
  },
  methods: {
    pull() {
      console.log("完成");
    },
  },
};
</script>

<style lang="scss" scoped>
.movebox {
  position: relative;
  background-color: #e8e8e8;
  width: 600px;
  height: 60px;
  line-height: 40px;
  text-align: center;
  margin-top: 10px;
  user-select: none;
  -o-user-select: none;
  -ms-user-select: none;
  .txt {
    position: absolute;
    top: 15px;
    left: 100px;
    width: 359px;
    -moz-user-select: none;
    -webkit-user-select: none;
    user-select: none;
    -o-user-select: none;
    -ms-user-select: none;
    font-size: 24px;
    color: #fff;
  }
  .movego {
    background-color: $--color-warning;
    height: 60px;
    width: 0px;
  }
  .move {
    position: absolute;
    top: -1px;
    left: 0px;
    width: 62px;
    height: 60px;
    border: 1px solid #ccc;
    cursor: move;
    border-radius: 4px;
    background: #fff;
  }
  .moveBefore {
    background: $--color-link;
    opacity: 0.5;
  }
  .moveSuccess {
    background: $--color-link;
  }
}
</style>

重构 el-input

<template>
  <div
    @click="$emit('click')"
    :class="[
      'input-cell',
      'flex-row-start-center',
      { 'hide-border': hideBorder },
    ]"
  >
    <!-- <input
      :readonly="readonly"
      v-model="newVal"
      ref="input"
      @focus="onFocus($event)"
      :placeholder="placeholder"
      :type="type"
      @change="change"
    /> -->

    <el-input
      v-bind="$attrs"
      v-on="$listeners"
      class="jk-input"
      ref="input"
      :placeholder="placeholder"
      :value="value"
      :maxLength="maxLength"
      :type="maxLength > 50 ? 'textarea' : type"
      v-if="type !== 'number'"
      @input="$emit('input', $event)"
      @change="change"
      @focus="onFocus($event)"
    ></el-input>

    <el-input-number
      v-bind="$attrs"
      v-on="$listeners"
      class="jk-input"
      ref="input"
      :placeholder="placeholder"
      :value="value"
      :precision="maxLength || 2"
      @input="$emit('input', $event)"
      @change="change"
      @focus="onFocus($event)"
      :controls="false"
      v-else
    ></el-input-number>

    <slot name="end"></slot>
  </div>
</template>

<script>
export default {
  model: {
    prop: "value",
    event: "input",
  },

  watch: {
    value: {
      handler() {},
    },
  },

  props: {
    value: {
      type: [String, Number],
      default: "",
    },
    maxLength: Number,

    readonly: {
      type: Boolean,
      default: false,
    },
    hideBorder: Boolean,
    type: {
      type: String,
      default: "text",
    },
    placeholder: String,
    max: Number,
    min: Number,
  },

  methods: {
    change() {
      // console.log('change')
    },
    focus() {
      this.$refs.input.focus();
    },
    onFocus(e) {
      // if(!this.readonly)
      // e.target?.scrollIntoView(false)
      this.$emit("focus", e);
    },
  },
};
</script>

<style lang="scss" scoped>
.input-cell {
  padding-bottom: 5px;
  border-bottom: 1px solid $--color-border;

  &.hide-border {
    border-bottom: none;
  }

  .jk-input {
    flex: 1;
    width: 100%;
    font-size: $--text-size-medium-x;
    &::v-deep {
      .el-input__inner,
      .el-textarea__inner {
        border: none !important;
        border-radius: none;
        padding: 0;
        text-align: left;
      }
    }
  }
}
</style>

总结

好饿

明日目标

  • [] 11:00-12:00 typescript
  • [] 15:00-16:00 vue3响应式原理看完
  • [] 16:30-17:30 英语