apiCreateDynamicComponent.spec.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { ref, shallowRef } from '@vue/reactivity'
  2. import { nextTick, resolveDynamicComponent } from '@vue/runtime-dom'
  3. import {
  4. createComponentWithFallback,
  5. createDynamicComponent,
  6. renderEffect,
  7. setHtml,
  8. setInsertionState,
  9. template,
  10. } from '../src'
  11. import { makeRender } from './_utils'
  12. const define = makeRender()
  13. describe('api: createDynamicComponent', () => {
  14. const A = () => document.createTextNode('AAA')
  15. const B = () => document.createTextNode('BBB')
  16. test('direct value', async () => {
  17. const val = shallowRef<any>(A)
  18. const { html } = define({
  19. setup() {
  20. return createDynamicComponent(() => val.value)
  21. },
  22. }).render()
  23. expect(html()).toBe('AAA<!--dynamic-component-->')
  24. val.value = B
  25. await nextTick()
  26. expect(html()).toBe('BBB<!--dynamic-component-->')
  27. // fallback
  28. val.value = 'foo'
  29. await nextTick()
  30. expect(html()).toBe('<foo></foo><!--dynamic-component-->')
  31. })
  32. test('global registration', async () => {
  33. const val = shallowRef('foo')
  34. const { app, html, mount } = define({
  35. setup() {
  36. return createDynamicComponent(() => val.value)
  37. },
  38. }).create()
  39. app.component('foo', A)
  40. app.component('bar', B)
  41. mount()
  42. expect(html()).toBe('AAA<!--dynamic-component-->')
  43. val.value = 'bar'
  44. await nextTick()
  45. expect(html()).toBe('BBB<!--dynamic-component-->')
  46. // fallback
  47. val.value = 'baz'
  48. await nextTick()
  49. expect(html()).toBe('<baz></baz><!--dynamic-component-->')
  50. })
  51. test('render fallback with insertionState', async () => {
  52. const { html, mount } = define({
  53. setup() {
  54. const html = ref('hi')
  55. const n1 = template('<div></div>', true)() as any
  56. setInsertionState(n1)
  57. const n0 = createComponentWithFallback(
  58. resolveDynamicComponent('button') as any,
  59. ) as any
  60. renderEffect(() => setHtml(n0, html.value))
  61. return n1
  62. },
  63. }).create()
  64. mount()
  65. expect(html()).toBe('<div><button>hi</button></div>')
  66. })
  67. })