Skip to content

Commit

Permalink
fix(ssr): fix on-component directives rendering (#12661)
Browse files Browse the repository at this point in the history
fix #10733
  • Loading branch information
manniL committed Aug 18, 2022
1 parent bba6b3d commit 165a14a
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 2 deletions.
10 changes: 9 additions & 1 deletion packages/server-renderer/src/render.ts
Expand Up @@ -206,6 +206,11 @@ function renderComponentInner(node, isRoot, context) {
type: 'Component',
prevActive
})
if (isDef(node.data) && isDef(node.data.directives)) {
childNode.data = childNode.data || {}
childNode.data.directives = node.data.directives
childNode.isComponentRootElement = true
}
renderNode(childNode, isRoot, context)
}

Expand Down Expand Up @@ -372,7 +377,10 @@ function renderStartingTag(node: VNode, context) {
if (dirRenderer) {
// directives mutate the node's data
// which then gets rendered by modules
dirRenderer(node, dirs[i])
dirRenderer(
node.isComponentRootElement ? node.parent : node,
dirs[i]
)
}
}
}
Expand Down
94 changes: 93 additions & 1 deletion packages/server-renderer/test/ssr-string.spec.ts
Expand Up @@ -1086,7 +1086,7 @@ describe('SSR: renderToString', () => {
)
})

it('custom directives', done => {
it('custom directives on raw element', done => {
const renderer = createRenderer({
directives: {
'class-prefixer': (node, dir) => {
Expand Down Expand Up @@ -1129,6 +1129,98 @@ describe('SSR: renderToString', () => {
)
})

it('custom directives on component', done => {
const Test = {
template: '<span>hello world</span>'
}
const renderer = createRenderer({
directives: {
'class-prefixer': (node, dir) => {
if (node.data.class) {
node.data.class = `${dir.value}-${node.data.class}`
}
if (node.data.staticClass) {
node.data.staticClass = `${dir.value}-${node.data.staticClass}`
}
}
}
})
renderer.renderToString(
new Vue({
template:
'<p><Test v-class-prefixer="\'my\'" class="class1" :class="\'class2\'" /></p>',
components: { Test }
}),
(err, result) => {
expect(err).toBeNull()
expect(result).toContain(
'<p data-server-rendered="true"><span class="my-class1 my-class2">hello world</span></p>'
)
done()
}
)
})

it('custom directives on element root of a component', done => {
const Test = {
template:
'<span v-class-prefixer="\'my\'" class="class1" :class="\'class2\'">hello world</span>'
}
const renderer = createRenderer({
directives: {
'class-prefixer': (node, dir) => {
if (node.data.class) {
node.data.class = `${dir.value}-${node.data.class}`
}
if (node.data.staticClass) {
node.data.staticClass = `${dir.value}-${node.data.staticClass}`
}
}
}
})
renderer.renderToString(
new Vue({
template: '<p><Test /></p>',
components: { Test }
}),
(err, result) => {
expect(err).toBeNull()
expect(result).toContain(
'<p data-server-rendered="true"><span class="my-class1 my-class2">hello world</span></p>'
)
done()
}
)
})

it('custom directives on element with parent element', done => {
const renderer = createRenderer({
directives: {
'class-prefixer': (node, dir) => {
if (node.data.class) {
node.data.class = `${dir.value}-${node.data.class}`
}
if (node.data.staticClass) {
node.data.staticClass = `${dir.value}-${node.data.staticClass}`
}
}
}
})
renderer.renderToString(
new Vue({
template:
'<p><span v-class-prefixer="\'my\'" class="class1" :class="\'class2\'">hello world</span></p>'
}),
(err, result) => {
expect(err).toBeNull()
expect(result).toContain(
'<p data-server-rendered="true"><span class="my-class1 my-class2">hello world</span></p>'
)
done()
}
)
})

it('should not warn for custom directives that do not have server-side implementation', done => {
renderToString(
new Vue({
Expand Down
1 change: 1 addition & 0 deletions src/core/vdom/vnode.ts
Expand Up @@ -33,6 +33,7 @@ export default class VNode {
fnOptions?: ComponentOptions | null // for SSR caching
devtoolsMeta?: Object | null // used to store functional render context for devtools
fnScopeId?: string | null // functional scope id support
isComponentRootElement?: boolean | null // for SSR directives

constructor(
tag?: string,
Expand Down

0 comments on commit 165a14a

Please sign in to comment.