Browse Source

tweak style merge for performance

dev
Evan You 8 years ago
parent
commit
b69b4a4eef
  1. 2
      flow/vnode.js
  2. 3
      src/platforms/web/compiler/modules/style.js
  3. 14
      src/platforms/web/runtime/modules/style.js
  4. 42
      src/platforms/web/util/style.js
  5. 2
      types/vnode.d.ts

2
flow/vnode.js

@ -37,7 +37,7 @@ declare interface VNodeData {
tag?: string;
staticClass?: string;
class?: any;
staticStyle?: string;
staticStyle?: { [key: string]: any };
style?: Array<Object> | Object;
props?: { [key: string]: any };
attrs?: { [key: string]: string };

3
src/platforms/web/compiler/modules/style.js

@ -1,6 +1,7 @@
/* @flow */
import { parseText } from 'compiler/parser/text-parser'
import { parseStyleText } from 'web/util/style'
import {
getAndRemoveAttr,
getBindingAttr,
@ -22,7 +23,7 @@ function transformNode (el: ASTElement, options: CompilerOptions) {
)
}
}
el.staticStyle = JSON.stringify(staticStyle)
el.staticStyle = JSON.stringify(parseStyleText(staticStyle))
}
const styleBinding = getBindingAttr(el, 'style', false /* getStatic */)

14
src/platforms/web/runtime/modules/style.js

@ -1,7 +1,7 @@
/* @flow */
import { cached, camelize, extend, looseEqual } from 'shared/util'
import { normalizeBindingStyle, getStyle } from 'web/util/style'
import { cached, camelize, extend } from 'shared/util'
import { normalizeStyleBinding, getStyle } from 'web/util/style'
const cssVarRE = /^--/
const setProp = (el, name, val) => {
@ -43,14 +43,11 @@ function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) {
let cur, name
const el: any = vnode.elm
const oldStyle: any = oldVnode.data.style || {}
const style: Object = normalizeBindingStyle(vnode.data.style || {})
vnode.data.style = extend({}, style)
const style = normalizeStyleBinding(vnode.data.style) || {}
const newStyle: Object = getStyle(vnode, true)
vnode.data.style = style.__ob__ ? extend({}, style) : style
if (looseEqual(el._prevStyle, newStyle)) {
return
}
const newStyle = getStyle(vnode, true)
for (name in oldStyle) {
if (newStyle[name] == null) {
@ -64,7 +61,6 @@ function updateStyle (oldVnode: VNodeWithData, vnode: VNodeWithData) {
setProp(el, name, cur == null ? '' : cur)
}
}
el._prevStyle = newStyle
}
export default {

42
src/platforms/web/util/style.js

@ -2,7 +2,7 @@
import { cached, extend, toObject } from 'shared/util'
const parseStyleText = cached(function (cssText) {
export const parseStyleText = cached(function (cssText) {
const rs = {}
if (!cssText) {
return rs
@ -20,17 +20,21 @@ const parseStyleText = cached(function (cssText) {
return rs
})
function normalizeStyleData (styleData: Object): Object {
const style = normalizeBindingStyle(styleData.style)
const staticStyle = parseStyleText(styleData.staticStyle)
return extend(extend({}, staticStyle), style)
// merge static and dynamic style data on the same vnode
function normalizeStyleData (data: VNodeData): ?Object {
const style = normalizeStyleBinding(data.style)
// static style is pre-processed into an object during compilation
// and is always a fresh object, so it's safe to merge into it
return data.staticStyle
? extend(data.staticStyle, style)
: style
}
export function normalizeBindingStyle (bindingStyle: any): Object {
// normalize possible array / string values into Object
export function normalizeStyleBinding (bindingStyle: any): ?Object {
if (Array.isArray(bindingStyle)) {
return toObject(bindingStyle)
}
if (typeof bindingStyle === 'string') {
return parseStyleText(bindingStyle)
}
@ -42,25 +46,29 @@ export function normalizeBindingStyle (bindingStyle: any): Object {
* so that parent component's style could override it
*/
export function getStyle (vnode: VNode, checkChild: boolean): Object {
let data = vnode.data
let parentNode = vnode
let childNode = vnode
data = normalizeStyleData(data)
const res = {}
let styleData
if (checkChild) {
let childNode = vnode
while (childNode.child) {
childNode = childNode.child._vnode
if (childNode.data) {
data = extend(normalizeStyleData(childNode.data), data)
if (childNode.data && (styleData = normalizeStyleData(childNode.data))) {
extend(res, styleData)
}
}
}
if ((styleData = normalizeStyleData(vnode.data))) {
extend(res, styleData)
}
let parentNode = vnode
while ((parentNode = parentNode.parent)) {
if (parentNode.data) {
data = extend(data, normalizeStyleData(parentNode.data))
if (parentNode.data && (styleData = normalizeStyleData(parentNode.data))) {
extend(res, styleData)
}
}
return data
return res
}

2
types/vnode.d.ts

@ -38,7 +38,7 @@ export interface VNodeData {
tag?: string;
staticClass?: string;
class?: any;
staticStyle?: string;
staticStyle?: { [key: string]: any };
style?: Object[] | Object;
props?: { [key: string]: any };
attrs?: { [key: string]: any };

Loading…
Cancel
Save