前几天看面试题,其中提到 React 的 setState
何时为同步何时为异步。那篇文章提到要根据 isBatchingUpdate
来判断。当时我就信以为真了。
过了几天有时间就去看了下 React 源码,根本没有 isBatchingUpdate
!之后依次翻阅历史版本,从 v18 一直到 v15.6,果真看到了。没想到这应该是 2018 的面试题吧。
正好突然想起了 React 对输入框的单向绑定,想看看具体实现。结果发现没有啥特殊逻辑。又想到公司的项目输入框,错误数据总是先显示出来,瞬间又被删除,体验不好。就想着封装一个 Vue 组件试试。
其实 2019 年我就写过方案了,只不过当时没有封装而已。现在来看,原理是正确的。
Input.vue
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <template> <input ref="input" /> </template>
<script> export default { props: { value: { type: String, default: "" }, }, data() { return { oldVal: "", }; }, computed: { input() { return this.$refs.input; }, }, watch: { value(newVal, oldVal) { this.oldVal = newVal; this.input.value = newVal; }, }, methods: { listener(e) { const target = e.target; target.value = this.oldVal; this.$emit("input", e); }, }, mounted() { this.oldVal = this.value; this.input.value = this.value; this.input.addEventListener("input", this.listener); }, beforeUnmount() { this.input.removeEventListener("input", this.listener); }, }; </script>
|
App.vue
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <Input :value="val" @input="onInput" /> </template>
<script> import Input from "./components/Input"; export default { components: { Input }, data() { return { val: "123", }; }, methods: { onInput(e) { const val = e.target.value; this.val = val.replace(/\D+/g, ""); }, }, }; </script>
|
在线看效果:https://codesandbox.io/s/vue-input-component-f412y
–END–