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>