Skip to content

Commit aa074df

Browse files
committed
feat: optimize Chinese input(just support v-model)
1 parent cc613c9 commit aa074df

File tree

6 files changed

+98
-4
lines changed

6 files changed

+98
-4
lines changed

components/_util/antInputDirective.js

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Not type checking this file because flow doesn't like attaching
3+
* properties to Elements.
4+
*/
5+
6+
export const inBrowser = typeof window !== 'undefined'
7+
export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
8+
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
9+
function makeMap (
10+
str,
11+
expectsLowerCase
12+
) {
13+
const map = Object.create(null)
14+
const list = str.split(',')
15+
for (let i = 0; i < list.length; i++) {
16+
map[list[i]] = true
17+
}
18+
return expectsLowerCase
19+
? val => map[val.toLowerCase()]
20+
: val => map[val]
21+
}
22+
const isTextInputType = makeMap('text,number,password,search,email,tel,url')
23+
24+
function onCompositionStart (e) {
25+
e.target.composing = true
26+
}
27+
28+
function onCompositionEnd (e) {
29+
// prevent triggering an input event for no reason
30+
if (!e.target.composing) return
31+
e.target.composing = false
32+
trigger(e.target, 'input')
33+
}
34+
35+
function trigger (el, type) {
36+
const e = document.createEvent('HTMLEvents')
37+
e.initEvent(type, true, true)
38+
el.dispatchEvent(e)
39+
}
40+
41+
/* istanbul ignore if */
42+
if (isIE9) {
43+
// http://www.matts411.com/post/internet-explorer-9-oninput/
44+
document.addEventListener('selectionchange', () => {
45+
const el = document.activeElement
46+
if (el && el.vmodel) {
47+
trigger(el, 'input')
48+
}
49+
})
50+
}
51+
52+
export default {
53+
install: (Vue, options) => {
54+
Vue.directive('ant-input', {
55+
inserted (el, binding, vnode, oldVnode) {
56+
if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
57+
if (!binding.modifiers || !binding.modifiers.lazy) {
58+
el.addEventListener('compositionstart', onCompositionStart)
59+
el.addEventListener('compositionend', onCompositionEnd)
60+
// Safari < 10.2 & UIWebView doesn't fire compositionend when
61+
// switching focus before confirming composition choice
62+
// this also fixes the issue where some browsers e.g. iOS Chrome
63+
// fires "change" instead of "input" on autocomplete.
64+
el.addEventListener('change', onCompositionEnd)
65+
/* istanbul ignore if */
66+
if (isIE9) {
67+
el.vmodel = true
68+
}
69+
}
70+
}
71+
},
72+
})
73+
},
74+
}

components/input/Input.jsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ export default {
5252
} else {
5353
this.$forceUpdate()
5454
}
55-
this.$emit('change.value', e.target.value)
55+
if (!e.target.composing) {
56+
this.$emit('change.value', e.target.value)
57+
}
5658
this.$emit('change', e)
5759
this.$emit('input', e)
5860
},
@@ -185,6 +187,9 @@ export default {
185187
class: classNames(getInputClassName(), getClass(this)),
186188
ref: 'input',
187189
}
190+
if ($listeners['change.value']) {
191+
inputProps.directives = [{ name: 'ant-input' }]
192+
}
188193
return this.renderLabeledIcon(
189194
<input
190195
{...inputProps}
@@ -203,6 +208,11 @@ export default {
203208
change: this.handleChange,
204209
keydown: this.handleKeyDown,
205210
},
211+
directives: [
212+
{
213+
name: 'ant-input',
214+
},
215+
],
206216
}
207217
return <TextArea {...textareaProps} ref='input' />
208218
}

components/input/TextArea.jsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ export default {
9696
})
9797
} else {
9898
this.$forceUpdate()
99+
}
100+
if (!e.target.composing) {
99101
this.$emit('change.value', e.target.value)
100-
this.$emit('change', e)
101102
}
103+
this.$emit('change', e)
102104
this.$emit('input', e)
103105
},
104106

@@ -133,6 +135,9 @@ export default {
133135
input: handleTextareaChange,
134136
},
135137
}
138+
if ($listeners['change.value']) {
139+
textareaProps.directives = [{ name: 'ant-input' }]
140+
}
136141
return (
137142
<textarea
138143
{...textareaProps}

components/input/__tests__/Search.test.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { mount } from '@vue/test-utils'
22
import { asyncExpect } from '@/tests/utils'
3-
import Search from '../Search'
3+
import Input from '../index'
44
import Button from '../../button'
55
import focusTest from '../../../tests/shared/focusTest'
66

7+
const { Search } = Input
78
describe('Input.Search', () => {
89
focusTest(Search)
910

components/input/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import Vue from 'vue'
12
import Input from './Input'
23
import Group from './Group'
34
import Search from './Search'
45
import TextArea from './TextArea'
6+
import antInputDirective from '../_util/antInputDirective'
7+
8+
Vue.use(antInputDirective)
59

610
Input.Group = Group
711
Input.Search = Search

site/dev.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Api from './components/api'
1010
import './components'
1111
import demoBox from './components/demoBox'
1212
import demoContainer from './components/demoContainer'
13-
import Test from '../components/carousel/demo/index'
13+
import Test from '../components/test/index'
1414

1515
Vue.use(VueClipboard)
1616
Vue.use(VueRouter)

0 commit comments

Comments
 (0)