import { Observable } from "rxjs"; const Sdic = { "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", "[": "{", "]": "}", "\\": "|", ";": ":", "'": '"', ",": "<", ".": ">", "/": "?" }; function IsLower(s: string) { return s.toLowerCase() === s; } function GetShiftChar(cur: KeyboardEvent): string { if (cur.keyCode >= 65 && cur.keyCode <= 90) { return IsLower(cur.key) ? cur.key.toUpperCase() : cur.key.toLowerCase(); } else { return Sdic[cur.key]; } } function GetStop(input: HTMLInputElement) { const end$ = Observable.fromEvent(input, "compositionend"); const keyup$ = Observable.fromEvent<KeyboardEvent>(input, "keyup"); const enter$ = keyup$.filter(e => e.keyCode === 13); return Observable.combineLatest(end$.merge(enter$), keyup$).debounceTime(250); } function GetLast(str: string) { return str.substr(str.length - 1, 1); } export function GetInputSource(input: HTMLInputElement) { const stop$ = GetStop(input); return Observable.fromEvent<KeyboardEvent>(input, "keyup") .scan( (prev, cur) => { // //漢字 // if (cur.keyCode === 231) { // return { // IsShift: false, // key: GetLast(input.value) // }; // } return { IsShift: cur.keyCode === 16, key: prev.IsShift ? GetShiftChar(cur) : cur.key }; }, { IsShift: false, key: "" } ) .map(t => t.key) .filter(t => t != null && t.length === 1) .bufferWhen(() => stop$) .map(arr => arr.join("").trim()); }
<template> <div> <div class="input-group"> <input type="text" class="form-control" :readonly="readonly" ref="input" /> <span class="input-group-btn"> <button type="button" class="btn btn-danger" @click="clear">X</button> </span> </div> <ul> <li v-for="(s, i) in list" :key="i" v-text="s"> </li> </ul> </div> </template> <script> import { GetInputSource } from '@/utils/Typeahead.ts'; const TRUE_RESULT = '123abc!@#$%^&<>;[]'; export default { data() { return { value: '', TRUE_RESULT, list: [] } }, computed: { readonly() { return this.value != null && this.value != ''; } }, mounted() { this.clear(); }, methods: { init() { const input = this.$refs.input; this.sub && this.sub.unsubscribe(); this.sub = GetInputSource(input) .takeWhile(() => !this.readonly) .subscribe(this.add); }, add(str) { console.log(str); console.log(str === TRUE_RESULT); this.SetValue(str); this.list.push(str); }, async SetValue(val) { this.value = val; await this.$nextTick(); const input = this.$refs.input; input.value = val; input.focus(); }, clear() { this.init(); this.SetValue(''); } }, beforeDestroy() { this.sub && this.sub.unsubscribe(); } } </script>