apiExpose.spec.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import { nodeOps, render } from '@vue/runtime-test'
  2. import { defineComponent, h, ref } from '../src'
  3. describe('api: expose', () => {
  4. test('via setup context', () => {
  5. const Child = defineComponent({
  6. render() {},
  7. setup(_, { expose }) {
  8. expose({
  9. foo: 1,
  10. bar: ref(2)
  11. })
  12. return {
  13. bar: ref(3),
  14. baz: ref(4)
  15. }
  16. }
  17. })
  18. const childRef = ref()
  19. const Parent = {
  20. setup() {
  21. return () => h(Child, { ref: childRef })
  22. }
  23. }
  24. const root = nodeOps.createElement('div')
  25. render(h(Parent), root)
  26. expect(childRef.value).toBeTruthy()
  27. expect(childRef.value.foo).toBe(1)
  28. expect(childRef.value.bar).toBe(2)
  29. expect(childRef.value.baz).toBeUndefined()
  30. })
  31. test('via options', () => {
  32. const Child = defineComponent({
  33. render() {},
  34. data() {
  35. return {
  36. foo: 1
  37. }
  38. },
  39. setup() {
  40. return {
  41. bar: ref(2),
  42. baz: ref(3)
  43. }
  44. },
  45. expose: ['foo', 'bar']
  46. })
  47. const childRef = ref()
  48. const Parent = {
  49. setup() {
  50. return () => h(Child, { ref: childRef })
  51. }
  52. }
  53. const root = nodeOps.createElement('div')
  54. render(h(Parent), root)
  55. expect(childRef.value).toBeTruthy()
  56. expect(childRef.value.foo).toBe(1)
  57. expect(childRef.value.bar).toBe(2)
  58. expect(childRef.value.baz).toBeUndefined()
  59. })
  60. test('options + context', () => {
  61. const Child = defineComponent({
  62. render() {},
  63. expose: ['foo'],
  64. data() {
  65. return {
  66. foo: 1
  67. }
  68. },
  69. setup(_, { expose }) {
  70. expose({
  71. bar: ref(2)
  72. })
  73. return {
  74. bar: ref(3),
  75. baz: ref(4)
  76. }
  77. }
  78. })
  79. const childRef = ref()
  80. const Parent = {
  81. setup() {
  82. return () => h(Child, { ref: childRef })
  83. }
  84. }
  85. const root = nodeOps.createElement('div')
  86. render(h(Parent), root)
  87. expect(childRef.value).toBeTruthy()
  88. expect(childRef.value.foo).toBe(1)
  89. expect(childRef.value.bar).toBe(2)
  90. expect(childRef.value.baz).toBeUndefined()
  91. })
  92. test('options: empty', () => {
  93. const Child = defineComponent({
  94. render() {},
  95. expose: [],
  96. data() {
  97. return {
  98. foo: 1
  99. }
  100. }
  101. })
  102. const childRef = ref()
  103. const Parent = {
  104. setup() {
  105. return () => h(Child, { ref: childRef })
  106. }
  107. }
  108. const root = nodeOps.createElement('div')
  109. render(h(Parent), root)
  110. expect(childRef.value).toBeTruthy()
  111. expect('foo' in childRef.value).toBe(false)
  112. })
  113. test('options: empty + setup context', () => {
  114. const Child = defineComponent({
  115. render() {},
  116. expose: [],
  117. setup(_, { expose }) {
  118. expose({
  119. foo: 1
  120. })
  121. }
  122. })
  123. const childRef = ref()
  124. const Parent = {
  125. setup() {
  126. return () => h(Child, { ref: childRef })
  127. }
  128. }
  129. const root = nodeOps.createElement('div')
  130. render(h(Parent), root)
  131. expect(childRef.value).toBeTruthy()
  132. expect(childRef.value.foo).toBe(1)
  133. })
  134. test('with $parent/$root', () => {
  135. const Child = defineComponent({
  136. render() {
  137. expect((this.$parent! as any).foo).toBe(1)
  138. expect((this.$parent! as any).bar).toBe(undefined)
  139. expect((this.$root! as any).foo).toBe(1)
  140. expect((this.$root! as any).bar).toBe(undefined)
  141. }
  142. })
  143. const Parent = defineComponent({
  144. expose: [],
  145. setup(_, { expose }) {
  146. expose({
  147. foo: 1
  148. })
  149. return {
  150. bar: 2
  151. }
  152. },
  153. render() {
  154. return h(Child)
  155. }
  156. })
  157. const root = nodeOps.createElement('div')
  158. render(h(Parent), root)
  159. })
  160. test('expose should allow access to built-in instance properties', () => {
  161. const GrandChild = defineComponent({
  162. render() {
  163. return h('div')
  164. }
  165. })
  166. const grandChildRef = ref()
  167. const Child = defineComponent({
  168. render() {
  169. return h('div')
  170. },
  171. setup(_, { expose }) {
  172. expose()
  173. return () => h(GrandChild, { ref: grandChildRef })
  174. }
  175. })
  176. const childRef = ref()
  177. const Parent = {
  178. setup() {
  179. return () => h(Child, { ref: childRef })
  180. }
  181. }
  182. const root = nodeOps.createElement('div')
  183. render(h(Parent), root)
  184. expect(childRef.value.$el.tag).toBe('div')
  185. expect(grandChildRef.value.$parent).toBe(childRef.value)
  186. expect(grandChildRef.value.$parent.$parent).toBe(grandChildRef.value.$root)
  187. })
  188. })