123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- <template>
- <view class="input-component" @click.self="onFocus" :class="{'active':withFocus}">
- <view class="bubbleTip" v-show="haserror && withFocus">
- <view>
- <bubble-tip msg="输入了错误的值"></bubble-tip>
- </view>
- </view>
- <view class="text-container" :style="{'font-size':fontSize,'height':fontSize}">
- <view class="text-sequence">
- <text v-for="(item, key) in sequence" :key="key">{{item}}</text>
- <view v-if="withFocus" class="fiction-cursor"></view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import bubbleTip from "./bubble-tip.vue"
- export default {
- components: {
- "bubble-tip": bubbleTip
- },
- props: {
- "fontSize": {
- type: String,
- default: "1rem"
- },
- "value": {
- type: String,
- default: ""
- },
- "focus": {
- type: Boolean,
- default: false
- },
- "maxLength": {
- type: Number,
- default: null
- },
- "type": {
- type: String
- },
- "validate": {
- type: Function
- }
- },
- // #ifdef VUE3
- emits: {
- "complete": null,
- "updateValue": null,
- "returned": null,
- "error": null,
- "onFocus": null
- },
- // #endif
- data() {
- return {
- sequence: this.value.split(""),
- withFocus: this.focus,
- haserror: false
- };
- },
- methods: {
- onFocus() {
- this.withFocus = true;
- this.$emit("onFocus", true)
- },
- onComplete() {
- this.$emit("onFocus", false);
- this.$emit("complete");
- },
- inPut(character) {
- //console.log(character, this);
- let ins = this;
- let arr = JSON.parse(JSON.stringify(ins.sequence));
- if (character === "delete") {
- if (arr.length > 0) {
- arr.pop();
- } else {
- this.$emit("returned");
- }
- } else if (character !== "delete") {
- if (ins.maxLength) {
- if (ins.maxLength > arr.length) {
- arr.push(character);
- if (arr.length === ins.maxLength) {
- this.checkStr(arr.join("")) && ins.onComplete();
- }
- } else {
- this.checkStr(arr.join("")) && ins.onComplete();
- }
- } else {
- arr.push(character);
- }
- }
- if (this.checkStr(arr.join(""))) {
- ins.sequence = arr;
- ins.$emit("updateValue", arr.join(""));
- }
- },
- checkStr(str) {
- //console.log(this.validate);
- this.haserror = false;
- if (this.validate) {
- let r = this.validate(str);
- if (r === false) {
- this.haserror = true;
- uni.vibrateLong({
- success: function() {}
- });
- this.$nextTick(function() {
- setTimeout(() => {
- this.haserror = false;
- }, 1000)
- })
- this.$emit("error");
- }
- return r;
- }
- return true;
- }
- },
- watch: {
- "focus": {
- handler(n, o) {
- //console.log("watch focus",n,o)
- this.checkStr(this.sequence.join(""))
- this.withFocus = n;
- }
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .bubbleTip {
- position: absolute;
- top: 0px;
- left: 50%;
- transform: translate(-50%, -105%);
- }
- .input-component {
- width: 100%;
- background-color: #FFFFFF;
- padding-top: 20rpx;
- padding-bottom: 20rpx;
- position: relative;
- border-radius: 6px;
- box-sizing: border-box;
- }
- .active {
- border: 1px solid #0080fb;
- }
- .text-container {
- display: flex;
- align-items: center;
- justify-content: space-around;
- .text-sequence {
- display: flex;
- height: 100%;
- align-items: center;
- }
- }
- .fiction-cursor {
- width: 2rpx;
- height: 100%;
- background-color: #666;
- animation: flashing 0.9s infinite;
- }
- @keyframes flashing {
- 0% {
- background-color: rgba(0, 0, 0, 0);
- }
- 100% {
- background-color: #666;
- }
- }
- </style>
|