diff --git a/src/platforms/web/server/modules/attrs.js b/src/platforms/web/server/modules/attrs.js index fb90e8b5..286f6894 100644 --- a/src/platforms/web/server/modules/attrs.js +++ b/src/platforms/web/server/modules/attrs.js @@ -1,12 +1,16 @@ -import { isBooleanAttr, isEnumeratedAttr } from 'web/util/index' +import { isBooleanAttr, isEnumeratedAttr, propsToAttrMap } from 'web/util/index' export default function renderAttrs (node) { - if (node.data.attrs || node.data.staticAttrs) { - return serialize(node.data.staticAttrs) + serialize(node.data.attrs) + if (node.data.attrs || node.data.props || node.data.staticAttrs) { + return ( + serialize(node.data.staticAttrs) + + serialize(node.data.attrs) + + serialize(node.data.props, true) + ) } } -function serialize (attrs) { +function serialize (attrs, asProps) { let res = '' if (!attrs) { return res @@ -16,6 +20,9 @@ function serialize (attrs) { // leave it to the style module continue } + if (asProps) { + key = propsToAttrMap[key] || key.toLowerCase() + } if (attrs[key] != null) { if (isBooleanAttr(key)) { res += ` ${key}="${key}"` diff --git a/src/platforms/web/util/attrs.js b/src/platforms/web/util/attrs.js index ebadf0ad..06c2506e 100644 --- a/src/platforms/web/util/attrs.js +++ b/src/platforms/web/util/attrs.js @@ -14,5 +14,12 @@ export const isBooleanAttr = makeMap( 'truespeed,typemustmatch,visible' ) +export const propsToAttrMap = { + acceptCharset: 'accept-charset', + className: 'class', + htmlFor: 'for', + httpEquiv: 'http-equiv', +} + export const xlinkNS = 'http://www.w3.org/1999/xlink' export const isXlink = name => name.charAt(5) === ':' && name.slice(0, 5) === 'xlink' diff --git a/src/server/create-streaming-renderer.js b/src/server/create-streaming-renderer.js index 367356e5..f49325a8 100644 --- a/src/server/create-streaming-renderer.js +++ b/src/server/create-streaming-renderer.js @@ -2,25 +2,30 @@ import RenderStream from './render-stream' import { renderStartingTag } from './render-starting-tag' export function createStreamingRenderer (modules, directives, isUnaryTag) { - function renderComponent (component, write, next) { + function renderComponent (component, write, next, isRoot) { component.$mount() - renderNode(component._vnode, write, next) + renderNode(component._vnode, write, next, isRoot) } - function renderNode (node, write, next) { + function renderNode (node, write, next, isRoot) { if (node.componentOptions) { node.data.hook.init(node) - renderComponent(node.child, write, next) + renderComponent(node.child, write, next, isRoot) } else { if (node.tag) { - renderElement(node, write, next) + renderElement(node, write, next, isRoot) } else { write(node.text, next) } } } - function renderElement (el, write, next) { + function renderElement (el, write, next, isRoot) { + if (isRoot) { + if (!el.data) el.data = {} + if (!el.data.attrs) el.data.attrs = {} + el.data.attrs['server-rendered'] = true + } const startTag = renderStartingTag(el, modules, directives) const endTag = `${el.tag}>` if (isUnaryTag(el.tag)) { @@ -50,7 +55,7 @@ export function createStreamingRenderer (modules, directives, isUnaryTag) { return function renderToStream (component) { return new RenderStream((write, done) => { - renderComponent(component, write, done) + renderComponent(component, write, done, true) }) } } diff --git a/src/server/create-sync-renderer.js b/src/server/create-sync-renderer.js index dc70067a..10ec77c4 100644 --- a/src/server/create-sync-renderer.js +++ b/src/server/create-sync-renderer.js @@ -1,33 +1,44 @@ import { renderStartingTag } from './render-starting-tag' export function createSyncRenderer (modules, directives, isUnaryTag) { - function renderComponent (component) { + function renderComponent (component, isRoot) { component.$mount() - return renderNode(component._vnode) + return renderNode(component._vnode, isRoot) } - function renderNode (node) { + function renderNode (node, isRoot) { if (node.componentOptions) { node.data.hook.init(node) - return renderComponent(node.child) + return renderComponent(node.child, isRoot) } else { return node.tag - ? renderElement(node) + ? renderElement(node, isRoot) : node.text } } - function renderElement (el) { + function renderElement (el, isRoot) { + if (isRoot) { + if (!el.data) el.data = {} + if (!el.data.attrs) el.data.attrs = {} + el.data.attrs['server-rendered'] = true + } const startTag = renderStartingTag(el, modules, directives) + const endTag = `${el.tag}>` if (isUnaryTag(el.tag)) { return startTag + } else if (!el.children || !el.children.length) { + return startTag + endTag } else { - const children = el.children - ? el.children.map(renderNode).join('') - : '' - return startTag + children + `${el.tag}>` + let children = '' + for (let i = 0; i < el.children.length; i++) { + children += renderNode(el.children[i]) + } + return startTag + children + endTag } } - return renderComponent + return function renderToString (component) { + return renderComponent(component, true) + } } diff --git a/test/ssr/ssr.stream.spec.js b/test/ssr/ssr.stream.spec.js index 1eceb638..27abb302 100644 --- a/test/ssr/ssr.stream.spec.js +++ b/test/ssr/ssr.stream.spec.js @@ -10,6 +10,7 @@ describe('SSR: renderToStream', () => {
yoyo
{{ test }} +yoyo
hiyoyo
' + + '' + + 'hi' + + '' + + 'yoyo
{{ test }} +yoyo
hiyoyo
' + + '' + + 'hi' + + '' + + '