data.spec.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import Vue from 'vue'
  2. describe('Options data', () => {
  3. it('should proxy and be reactive', done => {
  4. const data = { msg: 'foo' }
  5. const vm = new Vue({
  6. data,
  7. template: '<div>{{ msg }}</div>'
  8. }).$mount()
  9. expect(vm.$data).toEqual({ msg: 'foo' })
  10. expect(vm.$data).toBe(data)
  11. data.msg = 'bar'
  12. waitForUpdate(() => {
  13. expect(vm.$el.textContent).toBe('bar')
  14. }).then(done)
  15. })
  16. it('should merge data properly', () => {
  17. const Test = Vue.extend({
  18. data() {
  19. return { a: 1 }
  20. }
  21. })
  22. let vm = new Test({
  23. data: { b: 2 }
  24. })
  25. expect(vm.a).toBe(1)
  26. expect(vm.b).toBe(2)
  27. // no instance data
  28. vm = new Test()
  29. expect(vm.a).toBe(1)
  30. // no child-val
  31. const Extended = Test.extend({})
  32. vm = new Extended()
  33. expect(vm.a).toBe(1)
  34. // recursively merge objects
  35. const WithObject = Vue.extend({
  36. data() {
  37. return {
  38. obj: {
  39. a: 1
  40. }
  41. }
  42. }
  43. })
  44. vm = new WithObject({
  45. data: {
  46. obj: {
  47. b: 2
  48. }
  49. }
  50. })
  51. expect(vm.obj.a).toBe(1)
  52. expect(vm.obj.b).toBe(2)
  53. })
  54. it('should warn non-function during extend', () => {
  55. Vue.extend({
  56. data: { msg: 'foo' }
  57. })
  58. expect('The "data" option should be a function').toHaveBeenWarned()
  59. })
  60. it('should warn non object return', () => {
  61. new Vue({
  62. data() {}
  63. })
  64. expect('data functions should return an object').toHaveBeenWarned()
  65. })
  66. it('should warn replacing root $data', () => {
  67. const vm = new Vue({
  68. data: {}
  69. })
  70. vm.$data = {}
  71. expect('Avoid replacing instance root $data').toHaveBeenWarned()
  72. })
  73. it('should have access to props', () => {
  74. const Test = {
  75. props: ['a'],
  76. render() {},
  77. data() {
  78. return {
  79. b: this.a
  80. }
  81. }
  82. }
  83. const vm = new Vue({
  84. template: `<test ref="test" :a="1"></test>`,
  85. components: { Test }
  86. }).$mount()
  87. expect(vm.$refs.test.b).toBe(1)
  88. })
  89. it('props should not be reactive', done => {
  90. let calls = 0
  91. const vm = new Vue({
  92. template: `<child :msg="msg"></child>`,
  93. data: {
  94. msg: 'hello'
  95. },
  96. beforeUpdate() {
  97. calls++
  98. },
  99. components: {
  100. child: {
  101. template: `<span>{{ localMsg }}</span>`,
  102. props: ['msg'],
  103. data() {
  104. return { localMsg: this.msg }
  105. },
  106. computed: {
  107. computedMsg() {
  108. return this.msg + ' world'
  109. }
  110. }
  111. }
  112. }
  113. }).$mount()
  114. const child = vm.$children[0]
  115. vm.msg = 'hi'
  116. waitForUpdate(() => {
  117. expect(child.localMsg).toBe('hello')
  118. expect(child.computedMsg).toBe('hi world')
  119. expect(calls).toBe(1)
  120. }).then(done)
  121. })
  122. it('should have access to methods', () => {
  123. const vm = new Vue({
  124. methods: {
  125. get() {
  126. return { a: 1 }
  127. }
  128. },
  129. data() {
  130. return this.get()
  131. }
  132. })
  133. expect(vm.a).toBe(1)
  134. })
  135. it('should be called with this', () => {
  136. const vm = new Vue({
  137. template: '<div><child></child></div>',
  138. provide: { foo: 1 },
  139. components: {
  140. child: {
  141. template: '<span>{{bar}}</span>',
  142. inject: ['foo'],
  143. data({ foo }) {
  144. return { bar: 'foo:' + foo }
  145. }
  146. }
  147. }
  148. }).$mount()
  149. expect(vm.$el.innerHTML).toBe('<span>foo:1</span>')
  150. })
  151. it('should be called with vm as first argument when merged', () => {
  152. const superComponent = {
  153. data: ({ foo }) => ({ ext: 'ext:' + foo })
  154. }
  155. const mixins = [
  156. {
  157. data: ({ foo }) => ({ mixin1: 'm1:' + foo })
  158. },
  159. {
  160. data: ({ foo }) => ({ mixin2: 'm2:' + foo })
  161. }
  162. ]
  163. const vm = new Vue({
  164. template: '<div><child></child></div>',
  165. provide: { foo: 1 },
  166. components: {
  167. child: {
  168. extends: superComponent,
  169. mixins,
  170. template: '<span>{{bar}}-{{ext}}-{{mixin1}}-{{mixin2}}</span>',
  171. inject: ['foo'],
  172. data: ({ foo }) => ({ bar: 'foo:' + foo })
  173. }
  174. }
  175. }).$mount()
  176. expect(vm.$el.innerHTML).toBe('<span>foo:1-ext:1-m1:1-m2:1</span>')
  177. })
  178. })