vShow.spec.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import {
  2. withDirectives,
  3. defineComponent,
  4. h,
  5. nextTick,
  6. VNode,
  7. ref,
  8. watch
  9. } from '@vue/runtime-core'
  10. import { render, Transition, vShow } from '@vue/runtime-dom'
  11. const withVShow = (node: VNode, exp: any) =>
  12. withDirectives(node, [[vShow, exp]])
  13. let root: any
  14. beforeEach(() => {
  15. root = document.createElement('div')
  16. })
  17. describe('runtime-dom: v-show directive', () => {
  18. test('should check show value is truthy', async () => {
  19. const component = defineComponent({
  20. data() {
  21. return { value: true }
  22. },
  23. render() {
  24. return [withVShow(h('div'), this.value)]
  25. }
  26. })
  27. render(h(component), root)
  28. const $div = root.querySelector('div')
  29. expect($div.style.display).toEqual('')
  30. })
  31. test('should check show value is falsy', async () => {
  32. const component = defineComponent({
  33. data() {
  34. return { value: false }
  35. },
  36. render() {
  37. return [withVShow(h('div'), this.value)]
  38. }
  39. })
  40. render(h(component), root)
  41. const $div = root.querySelector('div')
  42. expect($div.style.display).toEqual('none')
  43. })
  44. it('should update show value changed', async () => {
  45. const component = defineComponent({
  46. data() {
  47. return { value: true }
  48. },
  49. render() {
  50. return [withVShow(h('div'), this.value)]
  51. }
  52. })
  53. render(h(component), root)
  54. const $div = root.querySelector('div')
  55. const data = root._vnode.component.data
  56. expect($div.style.display).toEqual('')
  57. data.value = false
  58. await nextTick()
  59. expect($div.style.display).toEqual('none')
  60. data.value = {}
  61. await nextTick()
  62. expect($div.style.display).toEqual('')
  63. data.value = 0
  64. await nextTick()
  65. expect($div.style.display).toEqual('none')
  66. data.value = []
  67. await nextTick()
  68. expect($div.style.display).toEqual('')
  69. data.value = null
  70. await nextTick()
  71. expect($div.style.display).toEqual('none')
  72. data.value = '0'
  73. await nextTick()
  74. expect($div.style.display).toEqual('')
  75. data.value = undefined
  76. await nextTick()
  77. expect($div.style.display).toEqual('none')
  78. data.value = 1
  79. await nextTick()
  80. expect($div.style.display).toEqual('')
  81. })
  82. test('should respect display value in style attribute', async () => {
  83. const component = defineComponent({
  84. data() {
  85. return { value: true }
  86. },
  87. render() {
  88. return [
  89. withVShow(h('div', { style: { display: 'block' } }), this.value)
  90. ]
  91. }
  92. })
  93. render(h(component), root)
  94. const $div = root.querySelector('div')
  95. const data = root._vnode.component.data
  96. expect($div.style.display).toEqual('block')
  97. data.value = false
  98. await nextTick()
  99. expect($div.style.display).toEqual('none')
  100. data.value = true
  101. await nextTick()
  102. expect($div.style.display).toEqual('block')
  103. })
  104. // #2583
  105. test('the value of `display` set by v-show should not be overwritten by the style attribute when updated', async () => {
  106. const style = ref('width: 100px')
  107. const display = ref(false)
  108. const component = defineComponent({
  109. render() {
  110. return withVShow(h('div', { style: style.value }), display.value)
  111. }
  112. })
  113. render(h(component), root)
  114. const $div = root.querySelector('div')
  115. expect($div.style.display).toEqual('none')
  116. style.value = 'width: 50px'
  117. await nextTick()
  118. expect($div.style.display).toEqual('none')
  119. display.value = true
  120. await nextTick()
  121. expect($div.style.display).toEqual('')
  122. })
  123. // #2583, #2757
  124. test('the value of `display` set by v-show should not be overwritten by the style attribute when updated (with Transition)', async () => {
  125. const style = ref('width: 100px')
  126. const display = ref(false)
  127. const component = defineComponent({
  128. setup() {
  129. const innerValue = ref(false)
  130. watch(display, val => {
  131. innerValue.value = val
  132. })
  133. return () => {
  134. return h(Transition, () =>
  135. withVShow(
  136. h('div', { style: style.value }, innerValue.value),
  137. display.value
  138. )
  139. )
  140. }
  141. }
  142. })
  143. render(h(component), root)
  144. const $div = root.querySelector('div')
  145. expect($div.style.display).toEqual('none')
  146. style.value = 'width: 50px'
  147. await nextTick()
  148. expect($div.style.display).toEqual('none')
  149. display.value = true
  150. await nextTick()
  151. expect($div.style.display).toEqual('')
  152. })
  153. })