Skip to content

Commit

Permalink
fix(ssr): better handle v-html hydration
Browse files Browse the repository at this point in the history
fix #6519
  • Loading branch information
yyx990803 committed Sep 7, 2017
1 parent f323719 commit 0f00f8f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 19 deletions.
57 changes: 38 additions & 19 deletions src/core/vdom/patch.js
Original file line number Diff line number Diff line change
Expand Up @@ -547,27 +547,46 @@ export function createPatchFunction (backend) {
if (!elm.hasChildNodes()) {
createChildren(vnode, children, insertedVnodeQueue)
} else {
let childrenMatch = true
let childNode = elm.firstChild
for (let i = 0; i < children.length; i++) {
if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue)) {
childrenMatch = false
break
// v-html and domProps: innerHTML
if (isDef(i = data) && isDef(i = i.domProps) && isDef(i = i.innerHTML)) {
if (i !== elm.innerHTML) {
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' &&
typeof console !== 'undefined' &&
!bailed
) {
bailed = true
console.warn('Parent: ', elm)
console.warn('server innerHTML: ', i)
console.warn('client innerHTML: ', elm.innerHTML)
}
return false
}
childNode = childNode.nextSibling
}
// if childNode is not null, it means the actual childNodes list is
// longer than the virtual children list.
if (!childrenMatch || childNode) {
if (process.env.NODE_ENV !== 'production' &&
typeof console !== 'undefined' &&
!bailed
) {
bailed = true
console.warn('Parent: ', elm)
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)
} else {
// iterate and compare children lists
let childrenMatch = true
let childNode = elm.firstChild
for (let i = 0; i < children.length; i++) {
if (!childNode || !hydrate(childNode, children[i], insertedVnodeQueue)) {
childrenMatch = false
break
}
childNode = childNode.nextSibling
}
// if childNode is not null, it means the actual childNodes list is
// longer than the virtual children list.
if (!childrenMatch || childNode) {
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' &&
typeof console !== 'undefined' &&
!bailed
) {
bailed = true
console.warn('Parent: ', elm)
console.warn('Mismatching childNodes vs. VNodes: ', elm.childNodes, children)
}
return false
}
return false
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions test/unit/modules/vdom/patch/hydration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,30 @@ describe('vdom patch: hydration', () => {
done()
}, 50)
})

it('should hydrate v-html with children', () => {
const dom = createMockSSRDOM('<span>foo</span>')

new Vue({
data: {
html: `<span>foo</span>`
},
template: `<div v-html="html">hello</div>`
}).$mount(dom)

expect('not matching server-rendered content').not.toHaveBeenWarned()
})

it('should warn mismatching v-html', () => {
const dom = createMockSSRDOM('<span>bar</span>')

new Vue({
data: {
html: `<span>foo</span>`
},
template: `<div v-html="html">hello</div>`
}).$mount(dom)

expect('not matching server-rendered content').toHaveBeenWarned()
})
})

0 comments on commit 0f00f8f

Please sign in to comment.