componentAttrs.spec.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import { nextTick, ref, watchEffect } from '@vue/runtime-dom'
  2. import { createComponent, setText, template } from '../src'
  3. import { makeRender } from './_utils'
  4. const define = makeRender<any>()
  5. // TODO: port more tests from rendererAttrsFallthrough.spec.ts
  6. describe('attribute fallthrough', () => {
  7. it('should allow attrs to fallthrough', async () => {
  8. const t0 = template('<div>')
  9. const { component: Child } = define({
  10. props: ['foo'],
  11. setup(props: any) {
  12. const n0 = t0() as Element
  13. watchEffect(() => setText(n0, props.foo))
  14. return n0
  15. },
  16. })
  17. const foo = ref(1)
  18. const id = ref('a')
  19. const { host } = define({
  20. setup() {
  21. return createComponent(
  22. Child,
  23. {
  24. foo: () => foo.value,
  25. id: () => id.value,
  26. },
  27. null,
  28. true,
  29. )
  30. },
  31. }).render()
  32. expect(host.innerHTML).toBe('<div id="a">1</div>')
  33. foo.value++
  34. await nextTick()
  35. expect(host.innerHTML).toBe('<div id="a">2</div>')
  36. id.value = 'b'
  37. await nextTick()
  38. expect(host.innerHTML).toBe('<div id="b">2</div>')
  39. })
  40. it('should not fallthrough if explicitly pass inheritAttrs: false', async () => {
  41. const t0 = template('<div>')
  42. const { component: Child } = define({
  43. props: ['foo'],
  44. inheritAttrs: false,
  45. setup(props: any) {
  46. const n0 = t0() as Element
  47. watchEffect(() => setText(n0, props.foo))
  48. return n0
  49. },
  50. })
  51. const foo = ref(1)
  52. const id = ref('a')
  53. const { host } = define({
  54. setup() {
  55. return createComponent(
  56. Child,
  57. {
  58. foo: () => foo.value,
  59. id: () => id.value,
  60. },
  61. null,
  62. true,
  63. )
  64. },
  65. }).render()
  66. expect(host.innerHTML).toBe('<div>1</div>')
  67. foo.value++
  68. await nextTick()
  69. expect(host.innerHTML).toBe('<div>2</div>')
  70. id.value = 'b'
  71. await nextTick()
  72. expect(host.innerHTML).toBe('<div>2</div>')
  73. })
  74. it('should pass through attrs in nested single root components', async () => {
  75. const t0 = template('<div>')
  76. const { component: Grandson } = define({
  77. props: ['custom-attr'],
  78. setup(_: any, { attrs }: any) {
  79. const n0 = t0() as Element
  80. watchEffect(() => setText(n0, attrs.foo))
  81. return n0
  82. },
  83. })
  84. const { component: Child } = define({
  85. setup() {
  86. const n0 = createComponent(
  87. Grandson,
  88. {
  89. 'custom-attr': () => 'custom-attr',
  90. },
  91. null,
  92. true,
  93. )
  94. return n0
  95. },
  96. })
  97. const foo = ref(1)
  98. const id = ref('a')
  99. const { host } = define({
  100. setup() {
  101. return createComponent(
  102. Child,
  103. {
  104. foo: () => foo.value,
  105. id: () => id.value,
  106. },
  107. null,
  108. true,
  109. )
  110. },
  111. }).render()
  112. expect(host.innerHTML).toBe('<div foo="1" id="a">1</div>')
  113. foo.value++
  114. await nextTick()
  115. expect(host.innerHTML).toBe('<div foo="2" id="a">2</div>')
  116. id.value = 'b'
  117. await nextTick()
  118. expect(host.innerHTML).toBe('<div foo="2" id="b">2</div>')
  119. })
  120. })