From 79c0d7bcfbcd1ac492e7ceb77f5024d09efdc6b3 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 2 Nov 2017 23:04:31 -0400 Subject: [PATCH] fix(ssr): properly render textarea value partial fix for #6986 --- src/platforms/web/server/modules/dom-props.js | 3 +++ src/server/optimizing-compiler/codegen.js | 3 +++ src/server/optimizing-compiler/modules.js | 4 +++ test/ssr/ssr-string.spec.js | 25 +++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/src/platforms/web/server/modules/dom-props.js b/src/platforms/web/server/modules/dom-props.js index 98a0daf7f35..57c18eefc89 100644 --- a/src/platforms/web/server/modules/dom-props.js +++ b/src/platforms/web/server/modules/dom-props.js @@ -27,7 +27,10 @@ export default function renderDOMProps (node: VNodeWithData): string { setText(node, props[key], true) } else if (key === 'textContent') { setText(node, props[key], false) + } else if (key === 'value' && node.tag === 'textarea') { + setText(node, props[key], false) } else { + // $flow-disable-line (WTF?) const attr = propsToAttrMap[key] || key.toLowerCase() if (isRenderableAttr(attr) && // avoid rendering double-bound props/attrs twice diff --git a/src/server/optimizing-compiler/codegen.js b/src/server/optimizing-compiler/codegen.js index dfc4477d915..26097c07b48 100644 --- a/src/server/optimizing-compiler/codegen.js +++ b/src/server/optimizing-compiler/codegen.js @@ -205,6 +205,9 @@ function childrenToSegments (el, state): Array { if ((binding = el.attrsMap['v-text'])) { return [{ type: INTERPOLATION, value: `_s(${binding})` }] } + if (el.tag === 'textarea' && (binding = el.attrsMap['v-model'])) { + return [{ type: INTERPOLATION, value: `_s(${binding})` }] + } return el.children ? nodesToSegments(el.children, state) : [] diff --git a/src/server/optimizing-compiler/modules.js b/src/server/optimizing-compiler/modules.js index e01f5ed6fb2..41b1af1d9d2 100644 --- a/src/server/optimizing-compiler/modules.js +++ b/src/server/optimizing-compiler/modules.js @@ -31,6 +31,10 @@ export function applyModelTransform (el: ASTElement, state: CodegenState) { const dir = el.directives[i] if (dir.name === 'model') { state.directives.model(el, dir, state.warn) + // remove value for textarea as its converted to text + if (el.tag === 'textarea' && el.props) { + el.props = el.props.filter(p => p.name !== 'value') + } break } } diff --git a/test/ssr/ssr-string.spec.js b/test/ssr/ssr-string.spec.js index 60c801fab01..20f5ec51a21 100644 --- a/test/ssr/ssr-string.spec.js +++ b/test/ssr/ssr-string.spec.js @@ -1009,6 +1009,31 @@ describe('SSR: renderToString', () => { done() }) }) + + it('render v-model with textarea', done => { + renderVmWithOptions({ + data: { foo: 'bar' }, + template: '
' + }, result => { + expect(result).toContain('') + done() + }) + }) + + it('render v-model with textarea (non-optimized)', done => { + renderVmWithOptions({ + render (h) { + return h('textarea', { + domProps: { + value: 'foo' + } + }) + } + }, result => { + expect(result).toContain('') + done() + }) + }) }) function renderVmWithOptions (options, cb) {