浏览代码

Merge pull request #496 from Drjingfubo/next

feat: taro shortpassword
love_forever 4 年之前
父节点
当前提交
a182affd3c

+ 1 - 0
src/config.json

@@ -571,6 +571,7 @@
         {
         {
           "version": "3.0.0",
           "version": "3.0.0",
           "name": "ShortPassword",
           "name": "ShortPassword",
+          "taro": true,
           "type": "component",
           "type": "component",
           "cName": "短密码",
           "cName": "短密码",
           "desc": "短密码组件",
           "desc": "短密码组件",

+ 2 - 3
src/packages/__VUE/calendaritem/index.vue

@@ -493,9 +493,8 @@ export default create({
       requestAniFrame(() => {
       requestAniFrame(() => {
         if (weeksPanel?.value && monthsPanel?.value) {
         if (weeksPanel?.value && monthsPanel?.value) {
           const top = weeksPanel?.value.getBoundingClientRect().bottom;
           const top = weeksPanel?.value.getBoundingClientRect().bottom;
-          const monthsDoms = monthsPanel.value.getElementsByClassName(
-            '.calendar-month'
-          );
+          const monthsDoms =
+            monthsPanel.value.getElementsByClassName('.calendar-month');
           for (let i = 0; i < monthsDoms.length; i++) {
           for (let i = 0; i < monthsDoms.length; i++) {
             if (
             if (
               monthsDoms[i].getBoundingClientRect().top <= top &&
               monthsDoms[i].getBoundingClientRect().top <= top &&

+ 16 - 0
src/packages/__VUE/shortpassword/index.scss

@@ -12,6 +12,13 @@
   font-size: $font-size-1;
   font-size: $font-size-1;
   color: $text-color;
   color: $text-color;
 }
 }
+.nut-shortpsdWx-subtitle {
+  display: block;
+  margin-top: 12px;
+  line-height: 1;
+  font-size: $font-size-1;
+  color: $text-color;
+}
 
 
 .nut-input-w {
 .nut-input-w {
   padding: 24px 0 10px 0;
   padding: 24px 0 10px 0;
@@ -28,6 +35,14 @@
     padding: 0 12px;
     padding: 0 12px;
     opacity: 0;
     opacity: 0;
   }
   }
+  .nut-inputWx-real {
+    width: 247px;
+    height: 41px;
+    padding: 0 12px;
+    opacity: 0;
+    position: relative;
+    z-index: 2;
+  }
 }
 }
 
 
 .nut-popup {
 .nut-popup {
@@ -83,6 +98,7 @@
     line-height: 1;
     line-height: 1;
     font-size: $font-size-1;
     font-size: $font-size-1;
     color: $shortpsd-forget;
     color: $shortpsd-forget;
+    display: flex;
   }
   }
 }
 }
 
 

+ 167 - 0
src/packages/__VUE/shortpassword/index.taro.vue

@@ -0,0 +1,167 @@
+<template>
+  <view>
+    <nut-popup
+      :style="{
+        padding: '32px 24px 28px 24px',
+        borderRadius: '12px',
+        textAlign: 'center'
+      }"
+      v-model:visible="show"
+      :closeable="true"
+      @click-close-icon="closeIcon"
+      :close-on-click-overlay="closeOnClickOverlay"
+      @click-overlay="close"
+    >
+      <view class="nut-shortpsd-title">{{ title }}</view>
+      <view class="nut-shortpsdWx-subtitle">{{ desc }}</view>
+      <view class="nut-input-w">
+        <input
+          ref="realpwd"
+          class="nut-inputWx-real"
+          type="number"
+          :maxlength="length"
+          v-model="realInput"
+          @input="changeValue"
+        />
+        <view class="nut-shortpsd-fake">
+          <view
+            class="nut-shortpsd-li"
+            v-for="(sublen, index) in new Array(comLen)"
+            v-bind:key="index"
+          >
+            <view
+              class="nut-shortpsd-icon"
+              v-if="realInput.length > index"
+            ></view>
+          </view>
+        </view>
+      </view>
+      <view class="nut-shortpsd-message">
+        <view class="nut-shortpsd-error">{{ errorMsg }}</view>
+        <view class="nut-shortpsd-forget" @click="onTips" v-if="tips">
+          <nut-icon class="icon" size="11px" name="tips"></nut-icon>
+          <view>{{ tips }}</view>
+        </view>
+      </view>
+      <view v-if="!noButton" class="nut-shortpsd-footer">
+        <view class="nut-shortpsd-cancle" @click="close">取消</view>
+        <view class="nut-shortpsd-sure" @click="sureClick">确认</view>
+      </view>
+    </nut-popup>
+  </view>
+</template>
+<script lang="ts">
+import { ref, computed, watch } from 'vue';
+import { createComponent } from '@/packages/utils/create';
+const { create } = createComponent('shortpassword');
+import Taro from '@tarojs/taro';
+export default create({
+  props: {
+    title: {
+      type: String,
+      default: '请输入密码'
+    },
+    desc: {
+      type: String,
+      default: '您使用了虚拟资产,请进行验证'
+    },
+    tips: {
+      type: String,
+      default: '忘记密码'
+    },
+    visible: {
+      type: Boolean,
+      default: false
+    },
+    modelValue: {
+      type: String,
+      default: ''
+    },
+    errorMsg: {
+      type: String,
+      default: ''
+    },
+    noButton: {
+      type: Boolean,
+      default: true
+    },
+    closeOnClickOverlay: {
+      type: Boolean,
+      default: true
+    },
+    length: {
+      type: [String, Number], //4~6
+      default: 6
+    }
+  },
+  emits: [
+    'update:modelValue',
+    'update:visible',
+    'complete',
+    'change',
+    'ok',
+    'tips',
+    'close',
+    'cancel'
+  ],
+  setup(props, { emit }) {
+    const realInput = ref(props.modelValue);
+    const realpwd = ref();
+    const comLen = computed(() => range(Number(props.length)));
+    const show = ref(props.visible);
+    // 方法
+    function sureClick() {
+      emit('ok', realInput.value);
+    }
+    watch(
+      () => props.visible,
+      value => {
+        show.value = value;
+      }
+    );
+    function changeValue(e: Event) {
+      const input = e.target as HTMLInputElement;
+      let val = input.value;
+      if (val.length > comLen.value) {
+        val = val.slice(0, comLen.value);
+        realInput.value = val;
+      }
+      if (realInput.value.length === comLen.value) {
+        emit('complete', val);
+      }
+      emit('change', val);
+      emit('update:modelValue', val);
+    }
+    function close() {
+      emit('update:visible', false);
+      emit('cancel');
+    }
+    function closeIcon() {
+      emit('update:visible', false);
+      emit('close');
+    }
+    function range(val: number) {
+      return Math.min(Math.max(4, val), 6);
+    }
+    function onTips() {
+      emit('tips');
+    }
+    return {
+      comLen,
+      sureClick,
+      realInput,
+      realpwd,
+      range,
+      changeValue,
+      close,
+      onTips,
+      show,
+      closeIcon
+    };
+  }
+});
+</script>
+
+<style lang="scss">
+@import 'index.scss';
+</style>

+ 1 - 0
src/sites/mobile-taro/vue/src/app.config.ts

@@ -1,5 +1,6 @@
 export default {
 export default {
   pages: [
   pages: [
+    'pages/shortpassword/index',
     'pages/textarea/index',
     'pages/textarea/index',
     'pages/calendar/index',
     'pages/calendar/index',
     'pages/input/index',
     'pages/input/index',

+ 1 - 1
src/sites/mobile-taro/vue/src/pages/input/index.vue

@@ -77,7 +77,7 @@ export default {
       val7: '',
       val7: '',
       val8: '文案'
       val8: '文案'
     });
     });
-    setTimeout(function() {
+    setTimeout(function () {
       state.val1 = '异步数据';
       state.val1 = '异步数据';
     }, 2000);
     }, 2000);
     const change = (value: string | number, event: Event) => {
     const change = (value: string | number, event: Event) => {

+ 112 - 0
src/sites/mobile-taro/vue/src/pages/shortpassword/index.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="demo">
+    <nut-shortpassword
+      v-model="state.value"
+      v-model:visible="state.visible"
+      :no-button="state.noButton"
+      :length="state.length"
+      :error-msg="state.errorMsg"
+      @change="methods.onChange"
+      @complete="methods.onComplete"
+      @ok="methods.onOk"
+      @tips="methods.onTips"
+      @close="methods.close"
+      @cancel="methods.cancel"
+    >
+    </nut-shortpassword>
+    <nut-cell
+      title="基础用法"
+      is-link
+      @click="
+        state.visible = true;
+        state.noButton = true;
+        state.length = 6;
+        state.errorMsg = '';
+      "
+    ></nut-cell>
+    <nut-cell
+      title="显示按钮组"
+      is-link
+      @click="
+        state.visible = true;
+        state.noButton = false;
+        state.length = 6;
+        state.errorMsg = '';
+      "
+    ></nut-cell>
+    <nut-cell
+      title="自定义密码长度4"
+      is-link
+      @click="
+        state.visible = true;
+        state.noButton = true;
+        state.length = 4;
+        state.errorMsg = '';
+      "
+    ></nut-cell>
+    <nut-cell
+      title="忘记密码提示语事件回调"
+      is-link
+      @click="
+        state.visible = true;
+        state.length = 6;
+        state.errorMsg = '';
+        state.noButton = true;
+      "
+    ></nut-cell>
+    <nut-cell
+      title="错误提示语"
+      is-link
+      @click="
+        state.visible = true;
+        state.length = 6;
+        state.noButton = true;
+        state.errorMsg = '请输入正确密码';
+      "
+    ></nut-cell>
+  </div>
+</template>
+
+<script lang="ts">
+import { reactive, getCurrentInstance } from 'vue';
+export default {
+  setup() {
+    // let { proxy } = getCurrentInstance() as any;
+
+    const state = reactive({
+      visible: false,
+      noButton: true,
+      value: '',
+      errorMsg: '',
+      length: 6
+    });
+    const methods = {
+      onChange(val: string) {
+        console.log(val);
+
+        // val && proxy.$toast.text(val);
+      },
+      onOk(val: string) {
+        // val && proxy.$toast.text(val);
+        state.visible = false;
+      },
+
+      onComplete() {},
+      onTips() {
+        // proxy.$toast.text('执行忘记密码逻辑');
+      },
+      close() {
+        // proxy.$toast.text('点击icon关闭弹窗');
+      },
+      cancel() {
+        // proxy.$toast.text('点击取消按钮关闭弹窗');
+      }
+    };
+
+    return {
+      state,
+      methods
+    };
+  }
+};
+</script>