We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
原来非受控组件的if else分支太多,会影响效率,也影响检测程序的评估分数
function getOptionValue(props) { //typeof props.value === 'undefined' return isDefined(props.value) ? props.value : props.children[0].text } function isDefined(a) { return !(a === null || a === undefined) } export function postUpdateSelectedOptions(vnode) { var props = vnode.props, multiple = !!props.multiple, value = isDefined(props.value) ? props.value : isDefined(props.defaultValue) ? props.defaultValue : multiple ? [] : '', options = []; collectOptions(vnode, props, options) if (multiple) { updateOptionsMore(vnode, options, options.length, value) } else { updateOptionsOne(vnode, options, options.length, value) } } function collectOptions(vnode, props, ret) { var arr = props.children for (var i = 0, n = arr.length; i < n; i++) { var el = arr[i] if (el.type === 'option') { ret.push(el) } else if (el.type === 'optgroup') { collectOptions(el, el.props, ret) } } } function updateOptionsOne(vnode, options, n, propValue) { // Do not set `select.value` as exact behavior isn't consistent across all // browsers for all cases. var selectedValue = '' + propValue; for (let i = 0; i < n; i++) { let option = options[i] let value = getOptionValue(option.props) if (value === selectedValue) { setDomSelected(option, true) return } } if (n) { setDomSelected(options[0], true) } } function updateOptionsMore(vnode, options, n, propValue) { var selectedValue = {} try { for (let i = 0; i < propValue.length; i++) { selectedValue['&' + propValue[i]] = true } } catch (e) { /* istanbul ignore next */ console.warn('<select multiple="true"> 的value应该对应一个字符串数组') } for (let i = 0; i < n; i++) { let option = options[i] let value = getOptionValue(option.props) let selected = selectedValue.hasOwnProperty('&' + value) setDomSelected(option, selected) } } function setDomSelected(option, selected) { if (option._hostNode) { option._hostNode.selected = selected } } //react的单向流动是由生命周期钩子的setState选择性调用(不是所有钩子都能用setState),受控组件,事务机制 function stopUserInput(e) { var target = e.target var name = e.type === 'textarea' ? 'innerHTML' : 'value' target[name] = target._lastValue } function stopUserClick(e) { e.preventDefault() } export function processFormElement(vnode, dom, props) { var domType = dom.type if (/text|password|number|date|time|color|month/.test(domType)) { if ('value' in props && !hasOtherControllProperty(props, textMap)) { console.warn(`你为${domType}元素指定了value属性,但是没有提供另外的${Object.keys(textMap)} 等用于控制value变化的属性,那么它是一个非受控组件,用户无法通过输入改变元素的value值`) dom.oninput = stopUserInput } } else if (/checkbox|radio/.test(domType)) { if ('checked' in props && !hasOtherControllProperty(props, checkedMap)) { console.warn(`你为${domType}元素指定了value属性,但是没有提供另外的${Object.keys(checkedMap)} 等用于控制value变化的属性,那么它是一个非受控组件,用户无法通过输入改变元素的value值`) dom.onclick = stopUserClick } } else if (/select/.test(domType)) { if (!('value' in props || 'defaultValue' in props)) { console.warn(`select元素必须指定value或defaultValue属性`) } postUpdateSelectedOptions(vnode) } } var textMap = { onChange: 1, onInput: 1, readOnly: 1, disabled: 1 } var checkedMap = { onChange: 1, onClick: 1, readOnly: 1, disabled: 1 } function hasOtherControllProperty(props, map) { for (var i in props) { if (map[i]) { return true } } return false }
上面的processFormElement 的复杂度为8。
如果使用映射,可以大大减少复杂度
export function processFormElement(vnode, dom, props) { var domType = dom.type var duplexType = duplexMap[domType] if (duplexType) { var data = duplexData[duplexType] var duplexProp = data[0] var keys = data[1] var eventName = data[2] if (duplexProp in props && !hasOtherControllProperty(props, keys)) { console.warn(`你为${vnode.type}[type=${domType}]元素指定了${duplexProp}属性,但是没有提供另外的${Object.keys(keys)} 等用于控制${duplexProp}变化的属性,那么它是一个非受控组件,用户无法通过输入改变元素的${duplexProp}值`) dom[eventName] = data[3] } if (duplexType === 3) { postUpdateSelectedOptions(vnode) } } } function hasOtherControllProperty(props, keys) { for (var key in props) { if (keys[key]) { return true } } } var duplexMap = { color: 1, date: 1, datetime: 1, 'datetime-local': 1, email: 1, month: 1, number: 1, password: 1, range: 1, search: 1, tel: 1, text: 1, time: 1, url: 1, week: 1, textarea: 1, checkbox: 2, radio: 2, 'select-one': 3, 'select-multiple': 3 } function preventUserInput(e) { var target = e.target var name = e.type === 'textarea' ? 'innerHTML' : 'value' target[name] = target._lastValue } function preventUserClick(e) { e.preventDefault() } function preventUserChange(e) { var target = e.target var value = target._lastValue var options = target.options if (target.multiple) { updateOptionsMore(options, options.length, value) } else { updateOptionsOne(options, options.length, value) } } var duplexData = { 1: ['value', { onChange: 1, onInput: 1, readOnly: 1, disabled: 1 }, 'oninput', preventUserInput], 2: ['checked', { onChange: 1, onClick: 1, readOnly: 1, disabled: 1 }, 'onclick', preventUserClick], 3: ['value', { onChange: 1, disabled: 1 }, 'onchange', preventUserChange] } export function postUpdateSelectedOptions(vnode) { var props = vnode.props, multiple = !!props.multiple, value = isDefined(props.value) ? props.value : isDefined(props.defaultValue) ? props.defaultValue : multiple ? [] : '', options = []; collectOptions(vnode, props, options) if (multiple) { updateOptionsMore(options, options.length, value) } else { updateOptionsOne(options, options.length, value) } } function isDefined(a) { return !(a === null || a === void 666) } /** * 收集虚拟DOM select下面的options元素,如果是真实DOM直接用select.options * * @param {VNode} vnode * @param {any} props * @param {Array} ret */ function collectOptions(vnode, props, ret) { var arr = props.children for (var i = 0, n = arr.length; i < n; i++) { var el = arr[i] if (el.type === 'option') { ret.push(el) } else if (el.type === 'optgroup') { collectOptions(el, el.props, ret) } } } function updateOptionsOne(options, n, propValue) { var selectedValue = '' + propValue; for (let i = 0; i < n; i++) { let option = options[i] let value = getOptionValue(option, option.props) if (value === selectedValue) { getOptionSelected(option, true) return } } if (n) { getOptionSelected(options[0], true) } } function updateOptionsMore(options, n, propValue) { var selectedValue = {} try { for (let i = 0; i < propValue.length; i++) { selectedValue['&' + propValue[i]] = true } } catch (e) { /* istanbul ignore next */ console.warn('<select multiple="true"> 的value应该对应一个字符串数组') } for (let i = 0; i < n; i++) { let option = options[i] let value = getOptionValue(option, option.props) let selected = selectedValue.hasOwnProperty('&' + value) getOptionSelected(option, selected) } } function getOptionValue(option, props) { if (!props) { return getDOMOptionValue(option) } return props.value === undefined ? props.children[0].text : props.value } function getDOMOptionValue(node) { if (node.hasAttribute && node.hasAttribute('value')) { return node.getAttribute('value') } var attr = node.getAttributeNode('value') if (attr && attr.specified) { return attr.value } return node.innerHTML.trim() } function getOptionSelected(option, selected) { var dom = option._hostNode || option dom.selected = selected }
The text was updated successfully, but these errors were encountered:
上面是react,下面是我的anu 性能更好,且内存消耗更低
Sorry, something went wrong.
fix: RubyLouvre#9 (RubyLouvre#10)
66b077d
chore(🤖):1.7.4 [skip ci]
3751dd5
## [1.7.4](75team/anu@v1.7.3...v1.7.4) (2020-11-03) ### Bug Fixes * [RubyLouvre#9](75team#9) ([RubyLouvre#10](75team#10)) ([66b077d](75team@66b077d))
No branches or pull requests
原来非受控组件的if else分支太多,会影响效率,也影响检测程序的评估分数

上面的processFormElement 的复杂度为8。
如果使用映射,可以大大减少复杂度
The text was updated successfully, but these errors were encountered: