refactor: new attrs merge strategy

This commit is contained in:
Evan You
2018-09-24 19:11:14 -04:00
parent 85cd69a988
commit a1b9144009
7 changed files with 87 additions and 60 deletions

View File

@@ -1,29 +1,11 @@
// compiler should normlaize class + :class bindings on the same element
// into a single binding ['staticClass', dynamic]
export function patchClass(el: Element, value: any, isSVG: boolean) {
export function patchClass(el: Element, value: string, isSVG: boolean) {
// directly setting className should be faster than setAttribute in theory
if (isSVG) {
el.setAttribute('class', normalizeClass(value))
el.setAttribute('class', value)
} else {
el.className = normalizeClass(value)
el.className = value
}
}
function normalizeClass(value: any): string {
let res = ''
if (typeof value === 'string') {
res = value
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
res += normalizeClass(value[i]) + ' '
}
} else if (typeof value === 'object') {
for (const name in value) {
if (value[name]) {
res += name + ' '
}
}
}
return res.trim()
}

View File

@@ -1,5 +1,3 @@
import { isObservable } from '@vue/core'
// style properties that should NOT have "px" added when numeric
const nonNumericRE = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i
@@ -10,44 +8,19 @@ export function patchStyle(el: any, prev: any, next: any, data: any) {
} else if (typeof next === 'string') {
style.cssText = next
} else {
// TODO: warn invalid value in dev
const normalizedNext: any = normalizeStyle(next)
// If next is observed, the user is likely to mutate the style object.
// We need to replace data.style with the normalized clone.
if (isObservable(next)) {
data.style = normalizedNext
}
for (const key in normalizedNext) {
let value = normalizedNext[key]
for (const key in next) {
let value = next[key]
if (typeof value === 'number' && !nonNumericRE.test(key)) {
value = value + 'px'
}
style[key] = value
}
if (prev && typeof prev !== 'string') {
prev = normalizeStyle(prev)
for (const key in prev) {
if (!normalizedNext[key]) {
if (!next[key]) {
style[key] = ''
}
}
}
}
}
function normalizeStyle(value: any): Record<string, string | number> | void {
if (value && typeof value === 'object') {
return value
} else if (Array.isArray(value)) {
const res: Record<string, string | number> = {}
for (let i = 0; i < value.length; i++) {
const normalized = normalizeStyle(value[i])
if (normalized) {
for (const key in normalized) {
res[key] = normalized[key]
}
}
}
return res
}
}