diff --git a/src/platforms/web/server/modules/style.js b/src/platforms/web/server/modules/style.js
index 7822023f7a3..a98dec68be7 100644
--- a/src/platforms/web/server/modules/style.js
+++ b/src/platforms/web/server/modules/style.js
@@ -2,24 +2,43 @@
import { hyphenate, toObject } from 'shared/util'
-export default function renderStyle (node: VNodeWithData): ?string {
+function concatStyleString (former: string, latter: string) {
+ if (former === '' || latter === '' || former.charAt(former.length - 1) === ';') {
+ return former + latter
+ }
+ return former + ';' + latter
+}
+
+function generateStyleText (node) {
const staticStyle = node.data.attrs && node.data.attrs.style
- if (node.data.style || staticStyle) {
- let styles = node.data.style
- let res = ''
- if (styles) {
- if (typeof styles === 'string') {
- res += styles
- } else {
- if (Array.isArray(styles)) {
- styles = toObject(styles)
- }
- for (const key in styles) {
- res += `${hyphenate(key)}:${styles[key]};`
- }
- res += staticStyle || ''
+ let styles = node.data.style
+ const parentStyle = node.parent ? generateStyleText(node.parent) : ''
+
+ if (!styles && !staticStyle) {
+ return parentStyle
+ }
+
+ let dynamicStyle = ''
+ if (styles) {
+ if (typeof styles === 'string') {
+ dynamicStyle += styles
+ } else {
+ if (Array.isArray(styles)) {
+ styles = toObject(styles)
+ }
+ for (const key in styles) {
+ dynamicStyle += `${hyphenate(key)}:${styles[key]};`
}
}
+ }
+
+ dynamicStyle = concatStyleString(parentStyle, dynamicStyle)
+ return concatStyleString(dynamicStyle, staticStyle || '')
+}
+
+export default function renderStyle (node: VNodeWithData): ?string {
+ const res = generateStyleText(node)
+ if (res) {
return ` style=${JSON.stringify(res)}`
}
}
diff --git a/src/server/render.js b/src/server/render.js
index 0aec0bf8fea..0b12ad5484f 100644
--- a/src/server/render.js
+++ b/src/server/render.js
@@ -150,9 +150,20 @@ function renderElement (el, isRoot, context) {
}
}
+function hasAncestorData (node: VNode) {
+ const parentNode = node.parent
+ return parentNode && (parentNode.data || hasAncestorData(parentNode))
+}
+
function renderStartingTag (node: VNode, context) {
let markup = `<${node.tag}`
const { directives, modules } = context
+
+ // construct synthetic data for module processing
+ // because modules like style also produce code by parent VNode data
+ if (!node.data && hasAncestorData(node)) {
+ node.data = {}
+ }
if (node.data) {
// check directives
const dirs = node.data.directives
diff --git a/test/ssr/ssr-string.spec.js b/test/ssr/ssr-string.spec.js
index c9d7965f4cd..6ca84e6948b 100644
--- a/test/ssr/ssr-string.spec.js
+++ b/test/ssr/ssr-string.spec.js
@@ -86,6 +86,87 @@ describe('SSR: renderToString', () => {
})
})
+ it('custom component style', done => {
+ renderVmWithOptions({
+ template: '