feat: optimize Chinese input(just support v-model)
parent
cc613c9012
commit
aa074df796
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* Not type checking this file because flow doesn't like attaching
|
||||||
|
* properties to Elements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const inBrowser = typeof window !== 'undefined'
|
||||||
|
export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
|
||||||
|
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
|
||||||
|
function makeMap (
|
||||||
|
str,
|
||||||
|
expectsLowerCase
|
||||||
|
) {
|
||||||
|
const map = Object.create(null)
|
||||||
|
const list = str.split(',')
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
map[list[i]] = true
|
||||||
|
}
|
||||||
|
return expectsLowerCase
|
||||||
|
? val => map[val.toLowerCase()]
|
||||||
|
: val => map[val]
|
||||||
|
}
|
||||||
|
const isTextInputType = makeMap('text,number,password,search,email,tel,url')
|
||||||
|
|
||||||
|
function onCompositionStart (e) {
|
||||||
|
e.target.composing = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCompositionEnd (e) {
|
||||||
|
// prevent triggering an input event for no reason
|
||||||
|
if (!e.target.composing) return
|
||||||
|
e.target.composing = false
|
||||||
|
trigger(e.target, 'input')
|
||||||
|
}
|
||||||
|
|
||||||
|
function trigger (el, type) {
|
||||||
|
const e = document.createEvent('HTMLEvents')
|
||||||
|
e.initEvent(type, true, true)
|
||||||
|
el.dispatchEvent(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* istanbul ignore if */
|
||||||
|
if (isIE9) {
|
||||||
|
// http://www.matts411.com/post/internet-explorer-9-oninput/
|
||||||
|
document.addEventListener('selectionchange', () => {
|
||||||
|
const el = document.activeElement
|
||||||
|
if (el && el.vmodel) {
|
||||||
|
trigger(el, 'input')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
install: (Vue, options) => {
|
||||||
|
Vue.directive('ant-input', {
|
||||||
|
inserted (el, binding, vnode, oldVnode) {
|
||||||
|
if (vnode.tag === 'textarea' || isTextInputType(el.type)) {
|
||||||
|
if (!binding.modifiers || !binding.modifiers.lazy) {
|
||||||
|
el.addEventListener('compositionstart', onCompositionStart)
|
||||||
|
el.addEventListener('compositionend', onCompositionEnd)
|
||||||
|
// Safari < 10.2 & UIWebView doesn't fire compositionend when
|
||||||
|
// switching focus before confirming composition choice
|
||||||
|
// this also fixes the issue where some browsers e.g. iOS Chrome
|
||||||
|
// fires "change" instead of "input" on autocomplete.
|
||||||
|
el.addEventListener('change', onCompositionEnd)
|
||||||
|
/* istanbul ignore if */
|
||||||
|
if (isIE9) {
|
||||||
|
el.vmodel = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
|
@ -52,7 +52,9 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
this.$forceUpdate()
|
this.$forceUpdate()
|
||||||
}
|
}
|
||||||
this.$emit('change.value', e.target.value)
|
if (!e.target.composing) {
|
||||||
|
this.$emit('change.value', e.target.value)
|
||||||
|
}
|
||||||
this.$emit('change', e)
|
this.$emit('change', e)
|
||||||
this.$emit('input', e)
|
this.$emit('input', e)
|
||||||
},
|
},
|
||||||
|
@ -185,6 +187,9 @@ export default {
|
||||||
class: classNames(getInputClassName(), getClass(this)),
|
class: classNames(getInputClassName(), getClass(this)),
|
||||||
ref: 'input',
|
ref: 'input',
|
||||||
}
|
}
|
||||||
|
if ($listeners['change.value']) {
|
||||||
|
inputProps.directives = [{ name: 'ant-input' }]
|
||||||
|
}
|
||||||
return this.renderLabeledIcon(
|
return this.renderLabeledIcon(
|
||||||
<input
|
<input
|
||||||
{...inputProps}
|
{...inputProps}
|
||||||
|
@ -203,6 +208,11 @@ export default {
|
||||||
change: this.handleChange,
|
change: this.handleChange,
|
||||||
keydown: this.handleKeyDown,
|
keydown: this.handleKeyDown,
|
||||||
},
|
},
|
||||||
|
directives: [
|
||||||
|
{
|
||||||
|
name: 'ant-input',
|
||||||
|
},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
return <TextArea {...textareaProps} ref='input' />
|
return <TextArea {...textareaProps} ref='input' />
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,9 +96,11 @@ export default {
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$forceUpdate()
|
this.$forceUpdate()
|
||||||
this.$emit('change.value', e.target.value)
|
|
||||||
this.$emit('change', e)
|
|
||||||
}
|
}
|
||||||
|
if (!e.target.composing) {
|
||||||
|
this.$emit('change.value', e.target.value)
|
||||||
|
}
|
||||||
|
this.$emit('change', e)
|
||||||
this.$emit('input', e)
|
this.$emit('input', e)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -133,6 +135,9 @@ export default {
|
||||||
input: handleTextareaChange,
|
input: handleTextareaChange,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if ($listeners['change.value']) {
|
||||||
|
textareaProps.directives = [{ name: 'ant-input' }]
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<textarea
|
<textarea
|
||||||
{...textareaProps}
|
{...textareaProps}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import { asyncExpect } from '@/tests/utils'
|
import { asyncExpect } from '@/tests/utils'
|
||||||
import Search from '../Search'
|
import Input from '../index'
|
||||||
import Button from '../../button'
|
import Button from '../../button'
|
||||||
import focusTest from '../../../tests/shared/focusTest'
|
import focusTest from '../../../tests/shared/focusTest'
|
||||||
|
|
||||||
|
const { Search } = Input
|
||||||
describe('Input.Search', () => {
|
describe('Input.Search', () => {
|
||||||
focusTest(Search)
|
focusTest(Search)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
|
import Vue from 'vue'
|
||||||
import Input from './Input'
|
import Input from './Input'
|
||||||
import Group from './Group'
|
import Group from './Group'
|
||||||
import Search from './Search'
|
import Search from './Search'
|
||||||
import TextArea from './TextArea'
|
import TextArea from './TextArea'
|
||||||
|
import antInputDirective from '../_util/antInputDirective'
|
||||||
|
|
||||||
|
Vue.use(antInputDirective)
|
||||||
|
|
||||||
Input.Group = Group
|
Input.Group = Group
|
||||||
Input.Search = Search
|
Input.Search = Search
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Api from './components/api'
|
||||||
import './components'
|
import './components'
|
||||||
import demoBox from './components/demoBox'
|
import demoBox from './components/demoBox'
|
||||||
import demoContainer from './components/demoContainer'
|
import demoContainer from './components/demoContainer'
|
||||||
import Test from '../components/carousel/demo/index'
|
import Test from '../components/test/index'
|
||||||
|
|
||||||
Vue.use(VueClipboard)
|
Vue.use(VueClipboard)
|
||||||
Vue.use(VueRouter)
|
Vue.use(VueRouter)
|
||||||
|
|
Loading…
Reference in New Issue