ssrVSkip.spec.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. import { compile } from '@vue/compiler-ssr'
  2. describe('ssr: v-skip', () => {
  3. test('basic', () => {
  4. expect(compile(`<div v-skip="foo"/>`).code).toMatchInlineSnapshot(`
  5. "const { createCommentVNode: _createCommentVNode } = require("vue")
  6. const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  7. return function ssrRender(_ctx, _push, _parent, _attrs) {
  8. if (_ctx.foo) {
  9. _createCommentVNode("v-skip", true)
  10. } else {
  11. _push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
  12. }
  13. }"
  14. `)
  15. })
  16. test('with text children', () => {
  17. expect(compile(`<div v-skip="foo">hello</div>`).code)
  18. .toMatchInlineSnapshot(`
  19. "const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  20. return function ssrRender(_ctx, _push, _parent, _attrs) {
  21. if (_ctx.foo) {
  22. _push(\`<!--[-->hello<!--]-->\`)
  23. } else {
  24. _push(\`<div\${_ssrRenderAttrs(_attrs)}>hello</div>\`)
  25. }
  26. }"
  27. `)
  28. })
  29. test('with element children', () => {
  30. expect(compile(`<div v-skip="foo"><span/></div>`).code)
  31. .toMatchInlineSnapshot(`
  32. "const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  33. return function ssrRender(_ctx, _push, _parent, _attrs) {
  34. if (_ctx.foo) {
  35. _push(\`<span></span>\`)
  36. } else {
  37. _push(\`<div\${_ssrRenderAttrs(_attrs)}><span></span></div>\`)
  38. }
  39. }"
  40. `)
  41. })
  42. test('with component children', () => {
  43. expect(compile(`<div v-skip="foo"><MyComponent/></div>`).code)
  44. .toMatchInlineSnapshot(`
  45. "const { resolveComponent: _resolveComponent } = require("vue")
  46. const { ssrRenderComponent: _ssrRenderComponent, ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  47. return function ssrRender(_ctx, _push, _parent, _attrs) {
  48. const _component_MyComponent = _resolveComponent("MyComponent")
  49. if (_ctx.foo) {
  50. _push(_ssrRenderComponent(_component_MyComponent, null, null, _parent))
  51. } else {
  52. _push(\`<div\${_ssrRenderAttrs(_attrs)}>\`)
  53. _push(_ssrRenderComponent(_component_MyComponent, null, null, _parent))
  54. _push(\`</div>\`)
  55. }
  56. }"
  57. `)
  58. })
  59. test('with multiple children', () => {
  60. expect(compile(`<div v-skip="foo"><span/><span/></div>`).code)
  61. .toMatchInlineSnapshot(`
  62. "const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  63. return function ssrRender(_ctx, _push, _parent, _attrs) {
  64. if (_ctx.foo) {
  65. _push(\`<!--[--><span></span><span></span><!--]-->\`)
  66. } else {
  67. _push(\`<div\${_ssrRenderAttrs(_attrs)}><span></span><span></span></div>\`)
  68. }
  69. }"
  70. `)
  71. })
  72. test('nested v-skip', () => {
  73. expect(compile(`<div v-skip="foo"><div v-skip="bar"/></div>`).code)
  74. .toMatchInlineSnapshot(`
  75. "const { createCommentVNode: _createCommentVNode } = require("vue")
  76. const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  77. return function ssrRender(_ctx, _push, _parent, _attrs) {
  78. if (_ctx.foo) {
  79. _push(\`<!--[-->\`)
  80. if (_ctx.bar) {
  81. _createCommentVNode("v-skip", true)
  82. } else {
  83. _push(\`<div></div>\`)
  84. }
  85. _push(\`<!--]-->\`)
  86. } else {
  87. _push(\`<div\${_ssrRenderAttrs(_attrs)}>\`)
  88. if (_ctx.bar) {
  89. _createCommentVNode("v-skip", true)
  90. } else {
  91. _push(\`<div></div>\`)
  92. }
  93. _push(\`</div>\`)
  94. }
  95. }"
  96. `)
  97. })
  98. test('v-if + v-skip', () => {
  99. expect(compile(`<div v-if="ok" v-skip="foo"/>`).code)
  100. .toMatchInlineSnapshot(`
  101. "const { createCommentVNode: _createCommentVNode } = require("vue")
  102. const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  103. return function ssrRender(_ctx, _push, _parent, _attrs) {
  104. if (_ctx.ok) {
  105. _push(\`<!--[-->\`)
  106. if (_ctx.foo) {
  107. _createCommentVNode("v-skip", true)
  108. } else {
  109. _push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
  110. }
  111. _push(\`<!--]-->\`)
  112. } else {
  113. _push(\`<!---->\`)
  114. }
  115. }"
  116. `)
  117. })
  118. test('with key', () => {
  119. expect(compile(`<div v-skip="ok" key="foo"/>`).code).toMatchInlineSnapshot(`
  120. "const { createCommentVNode: _createCommentVNode, mergeProps: _mergeProps } = require("vue")
  121. const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  122. return function ssrRender(_ctx, _push, _parent, _attrs) {
  123. if (_ctx.ok) {
  124. _createCommentVNode("v-skip", true)
  125. } else {
  126. _push(\`<div\${_ssrRenderAttrs(_mergeProps({ key: "foo" }, _attrs))}></div>\`)
  127. }
  128. }"
  129. `)
  130. })
  131. test('v-else + v-skip', () => {
  132. expect(compile(`<div v-if="ok"/><div v-else v-skip="nested"/>`).code)
  133. .toMatchInlineSnapshot(`
  134. "const { createCommentVNode: _createCommentVNode } = require("vue")
  135. const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  136. return function ssrRender(_ctx, _push, _parent, _attrs) {
  137. if (_ctx.ok) {
  138. _push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
  139. } else {
  140. _push(\`<!--[-->\`)
  141. if (_ctx.nested) {
  142. _createCommentVNode("v-skip", true)
  143. } else {
  144. _push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
  145. }
  146. _push(\`<!--]-->\`)
  147. }
  148. }"
  149. `)
  150. })
  151. test('v-else-if + v-skip', () => {
  152. expect(
  153. compile(`<div v-if="ok"/><div v-else-if="yes" v-skip="nested"/>`).code,
  154. ).toMatchInlineSnapshot(`
  155. "const { createCommentVNode: _createCommentVNode } = require("vue")
  156. const { ssrRenderAttrs: _ssrRenderAttrs } = require("vue/server-renderer")
  157. return function ssrRender(_ctx, _push, _parent, _attrs) {
  158. if (_ctx.ok) {
  159. _push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
  160. } else if (_ctx.yes) {
  161. _push(\`<!--[-->\`)
  162. if (_ctx.nested) {
  163. _createCommentVNode("v-skip", true)
  164. } else {
  165. _push(\`<div\${_ssrRenderAttrs(_attrs)}></div>\`)
  166. }
  167. _push(\`<!--]-->\`)
  168. } else {
  169. _push(\`<!---->\`)
  170. }
  171. }"
  172. `)
  173. })
  174. test('on component', () => {
  175. expect(compile(`<Comp v-skip="foo"/>`).code).toMatchInlineSnapshot(`
  176. "const { resolveComponent: _resolveComponent } = require("vue")
  177. const { ssrRenderComponent: _ssrRenderComponent, ssrRenderSkipComponent: _ssrRenderSkipComponent } = require("vue/server-renderer")
  178. return function ssrRender(_ctx, _push, _parent, _attrs) {
  179. const _component_Comp = _resolveComponent("Comp")
  180. _push(_ssrRenderSkipComponent(_push, _ctx.foo, _component_Comp, _attrs, null, _parent))
  181. }"
  182. `)
  183. })
  184. test('on component with default slot', () => {
  185. expect(compile(`<Comp v-skip="ok">foo</Comp>`).code).toMatchInlineSnapshot(`
  186. "const { resolveComponent: _resolveComponent, withCtx: _withCtx, createTextVNode: _createTextVNode } = require("vue")
  187. const { ssrRenderComponent: _ssrRenderComponent, ssrRenderSkipComponent: _ssrRenderSkipComponent } = require("vue/server-renderer")
  188. return function ssrRender(_ctx, _push, _parent, _attrs) {
  189. const _component_Comp = _resolveComponent("Comp")
  190. _push(_ssrRenderSkipComponent(_push, _ctx.ok, _component_Comp, _attrs, {
  191. default: _withCtx((_, _push, _parent, _scopeId) => {
  192. if (_push) {
  193. _push(\`foo\`)
  194. } else {
  195. return [
  196. _createTextVNode("foo")
  197. ]
  198. }
  199. }),
  200. _: 1 /* STABLE */
  201. }, _parent))
  202. }"
  203. `)
  204. })
  205. test('on component with multiple named slot', () => {
  206. expect(
  207. compile(
  208. `<Comp v-skip="ok">
  209. <template #default>default</template>
  210. <template #foo>foo</template>
  211. </Comp>`,
  212. ).code,
  213. ).toMatchInlineSnapshot(`
  214. "const { resolveComponent: _resolveComponent, withCtx: _withCtx, createTextVNode: _createTextVNode } = require("vue")
  215. const { ssrRenderComponent: _ssrRenderComponent, ssrRenderSkipComponent: _ssrRenderSkipComponent } = require("vue/server-renderer")
  216. return function ssrRender(_ctx, _push, _parent, _attrs) {
  217. const _component_Comp = _resolveComponent("Comp")
  218. _push(_ssrRenderSkipComponent(_push, _ctx.ok, _component_Comp, _attrs, {
  219. default: _withCtx((_, _push, _parent, _scopeId) => {
  220. if (_push) {
  221. _push(\`default\`)
  222. } else {
  223. return [
  224. _createTextVNode("default")
  225. ]
  226. }
  227. }),
  228. foo: _withCtx((_, _push, _parent, _scopeId) => {
  229. if (_push) {
  230. _push(\`foo\`)
  231. } else {
  232. return [
  233. _createTextVNode("foo")
  234. ]
  235. }
  236. }),
  237. _: 1 /* STABLE */
  238. }, _parent))
  239. }"
  240. `)
  241. })
  242. test('on component with multiple implicit slot', () => {
  243. expect(
  244. compile(
  245. `<Comp v-skip="ok">
  246. <span/>
  247. <template #foo>foo</template>
  248. <div/>
  249. </Comp>`,
  250. ).code,
  251. ).toMatchInlineSnapshot(`
  252. "const { resolveComponent: _resolveComponent, withCtx: _withCtx, createTextVNode: _createTextVNode, createVNode: _createVNode } = require("vue")
  253. const { ssrRenderComponent: _ssrRenderComponent, ssrRenderSkipComponent: _ssrRenderSkipComponent } = require("vue/server-renderer")
  254. return function ssrRender(_ctx, _push, _parent, _attrs) {
  255. const _component_Comp = _resolveComponent("Comp")
  256. _push(_ssrRenderSkipComponent(_push, _ctx.ok, _component_Comp, _attrs, {
  257. foo: _withCtx((_, _push, _parent, _scopeId) => {
  258. if (_push) {
  259. _push(\`foo\`)
  260. } else {
  261. return [
  262. _createTextVNode("foo")
  263. ]
  264. }
  265. }),
  266. default: _withCtx((_, _push, _parent, _scopeId) => {
  267. if (_push) {
  268. _push(\`<span\${
  269. _scopeId
  270. }></span><div\${
  271. _scopeId
  272. }></div>\`)
  273. } else {
  274. return [
  275. _createVNode("span"),
  276. _createVNode("div")
  277. ]
  278. }
  279. }),
  280. _: 1 /* STABLE */
  281. }, _parent))
  282. }"
  283. `)
  284. })
  285. test('on dynamic component', () => {
  286. expect(
  287. compile(
  288. `<component :is="Comp" v-skip="ok">
  289. <slot/>
  290. </component>`,
  291. ).code,
  292. ).toMatchInlineSnapshot(`
  293. "const { resolveDynamicComponent: _resolveDynamicComponent, withCtx: _withCtx, renderSlot: _renderSlot, createVNode: _createVNode } = require("vue")
  294. const { ssrRenderSlot: _ssrRenderSlot, ssrRenderVNode: _ssrRenderVNode, ssrRenderSkipComponent: _ssrRenderSkipComponent } = require("vue/server-renderer")
  295. return function ssrRender(_ctx, _push, _parent, _attrs) {
  296. _ssrRenderSkipComponent(_push, _ctx.ok, _push, _createVNode(_resolveDynamicComponent(_ctx.Comp), _attrs, {
  297. default: _withCtx((_, _push, _parent, _scopeId) => {
  298. if (_push) {
  299. _ssrRenderSlot(_ctx.$slots, "default", {}, null, _push, _parent, _scopeId)
  300. } else {
  301. return [
  302. _renderSlot(_ctx.$slots, "default")
  303. ]
  304. }
  305. }),
  306. _: 3 /* FORWARDED */
  307. }), _parent)
  308. }"
  309. `)
  310. })
  311. test('fragment with component v-skip', () => {
  312. expect(
  313. compile(`
  314. <div></div>
  315. <Comp v-skip="ok"><span/></Comp>
  316. `).code,
  317. ).toMatchInlineSnapshot(`
  318. "const { resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode } = require("vue")
  319. const { ssrRenderComponent: _ssrRenderComponent, ssrRenderSkipComponent: _ssrRenderSkipComponent } = require("vue/server-renderer")
  320. return function ssrRender(_ctx, _push, _parent, _attrs) {
  321. const _component_Comp = _resolveComponent("Comp")
  322. _push(\`<!--[--><div></div>\`)
  323. _push(_ssrRenderSkipComponent(_push, _ctx.ok, _component_Comp, null, {
  324. default: _withCtx((_, _push, _parent, _scopeId) => {
  325. if (_push) {
  326. _push(\`<span\${_scopeId}></span>\`)
  327. } else {
  328. return [
  329. _createVNode("span")
  330. ]
  331. }
  332. }),
  333. _: 1 /* STABLE */
  334. }, _parent))
  335. _push(\`<!--]-->\`)
  336. }"
  337. `)
  338. })
  339. })