vue-test.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. import Vue, { VNode, defineComponent } from '../index'
  2. import { ComponentOptions } from '../options'
  3. class Test extends Vue {
  4. a: number = 0
  5. testProperties() {
  6. this.$data
  7. this.$el
  8. this.$options
  9. this.$parent
  10. this.$root
  11. this.$children
  12. this.$refs
  13. this.$slots
  14. this.$isServer
  15. this.$ssrContext
  16. this.$vnode
  17. this.$root.$children[0].$children[0]
  18. }
  19. // test property reification
  20. $el!: HTMLElement | SVGElement
  21. $refs!: {
  22. vue: Vue
  23. element: HTMLInputElement
  24. vues: Vue[]
  25. elements: HTMLInputElement[]
  26. }
  27. testReification() {
  28. this.$refs.vue.$data
  29. this.$refs.element.value
  30. this.$refs.vues[0].$data
  31. this.$refs.elements[0].value
  32. }
  33. testMethods() {
  34. this.$mount('#app', false)
  35. this.$forceUpdate()
  36. this.$destroy()
  37. this.$set({}, 'key', 'value')
  38. this.$delete({}, 'key')
  39. this.$watch('a', (val: number, oldVal: number) => {}, {
  40. immediate: true,
  41. deep: false
  42. })()
  43. this.$watch(
  44. () => this.a,
  45. (val: number) => {}
  46. )
  47. this.$on('', () => {})
  48. this.$once('', () => {})
  49. this.$off('', () => {})
  50. this.$emit('', 1, 2, 3)
  51. this.$nextTick(function () {
  52. this.$nextTick
  53. })
  54. this.$nextTick().then(() => {})
  55. this.$createElement('div', {}, 'message')
  56. }
  57. static testConfig() {
  58. const { config } = this
  59. config.silent
  60. config.optionMergeStrategies
  61. config.devtools
  62. config.errorHandler = (err, vm) => {
  63. if (vm instanceof Test) {
  64. vm.testProperties()
  65. vm.testMethods()
  66. }
  67. }
  68. config.warnHandler = (msg, vm) => {
  69. if (vm instanceof Test) {
  70. vm.testProperties()
  71. vm.testMethods()
  72. }
  73. }
  74. config.keyCodes = { esc: 27 }
  75. config.ignoredElements = ['foo', /^ion-/]
  76. config.async = false
  77. }
  78. static testMethods() {
  79. this.extend({
  80. data() {
  81. return {
  82. msg: ''
  83. }
  84. }
  85. })
  86. this.nextTick(() => {})
  87. this.nextTick(
  88. function () {
  89. console.log(this.text === 'test')
  90. },
  91. { text: 'test' }
  92. )
  93. this.nextTick().then(() => {})
  94. this.set({}, '', '')
  95. this.set({}, 1, '')
  96. this.set([true, false, true], 1, true)
  97. this.delete({}, '')
  98. this.delete({}, 1)
  99. this.delete([true, false], 0)
  100. this.directive('', { bind() {} })
  101. this.filter('', (value: number) => value)
  102. this.component('', { data: () => ({}) })
  103. this.component('', {
  104. functional: true,
  105. render(h) {
  106. return h('div', 'hello!')
  107. }
  108. })
  109. this.use
  110. this.mixin(Test)
  111. this.compile('<div>{{ message }}</div>')
  112. this.use(() => {})
  113. .use(() => {})
  114. .mixin({})
  115. .mixin({})
  116. }
  117. }
  118. const HelloWorldComponent = Vue.extend({
  119. props: ['name'],
  120. data() {
  121. return {
  122. message: 'Hello ' + this.name
  123. }
  124. },
  125. computed: {
  126. shouted(): string {
  127. return this.message.toUpperCase()
  128. }
  129. },
  130. methods: {
  131. getMoreExcited() {
  132. this.message += '!'
  133. }
  134. },
  135. watch: {
  136. message(a: string) {
  137. console.log(`Message ${this.message} was changed!`)
  138. }
  139. }
  140. })
  141. const FunctionalHelloWorldComponent = Vue.extend({
  142. functional: true,
  143. props: ['name'],
  144. render(createElement, ctxt) {
  145. return createElement('div', 'Hello ' + ctxt.props.name)
  146. }
  147. })
  148. const FunctionalScopedSlotsComponent = Vue.extend({
  149. functional: true,
  150. render(h, ctx) {
  151. return (
  152. (ctx.scopedSlots.default && ctx.scopedSlots.default({})) ||
  153. h('div', 'functional scoped slots')
  154. )
  155. }
  156. })
  157. const Parent = Vue.extend({
  158. data() {
  159. return { greeting: 'Hello' }
  160. }
  161. })
  162. const Child = Parent.extend({
  163. methods: {
  164. foo() {
  165. console.log(this.greeting.toLowerCase())
  166. }
  167. }
  168. })
  169. const GrandChild = Child.extend({
  170. computed: {
  171. lower(): string {
  172. return this.greeting.toLowerCase()
  173. }
  174. }
  175. })
  176. new GrandChild().lower.toUpperCase()
  177. for (let _ in new Test().$options) {
  178. }
  179. declare const options: ComponentOptions<Vue>
  180. Vue.extend(options)
  181. Vue.component('test-comp', options)
  182. new Vue(options)
  183. // cyclic example
  184. Vue.extend({
  185. props: {
  186. bar: {
  187. type: String
  188. }
  189. },
  190. methods: {
  191. foo() {}
  192. },
  193. mounted() {
  194. this.foo()
  195. },
  196. // manual annotation
  197. render(h): VNode {
  198. const a = this.bar
  199. return h('canvas', {}, [a])
  200. }
  201. })
  202. declare function decorate<VC extends typeof Vue>(v: VC): VC
  203. @decorate
  204. class Decorated extends Vue {
  205. a = 123
  206. }
  207. const obj = Vue.observable({ a: 1 })
  208. obj.a++
  209. // VNodeData style tests.
  210. const ComponentWithStyleInVNodeData = Vue.extend({
  211. render(h) {
  212. const elementWithStyleAsString = h('div', {
  213. style: '--theme-color: black;'
  214. })
  215. const elementWithStyleCSSProperties = h('div', {
  216. style: { ['--theme-color' as any]: 'black' }
  217. })
  218. const elementWithStyleAsArrayOfStyleValues = h('div', {
  219. style: [{ ['--theme-color' as any]: 'black' }]
  220. })
  221. return h('div', undefined, [
  222. elementWithStyleAsString,
  223. elementWithStyleCSSProperties,
  224. elementWithStyleAsArrayOfStyleValues
  225. ])
  226. }
  227. })
  228. // infer mixin type with new Vue() #12730
  229. new Vue({
  230. mixins: [
  231. defineComponent({
  232. props: {
  233. p1: String,
  234. p2: {
  235. type: Number,
  236. default: 0
  237. }
  238. },
  239. data() {
  240. return {
  241. foo: 123
  242. }
  243. },
  244. computed: {
  245. bar() {
  246. return 123
  247. }
  248. }
  249. }),
  250. {
  251. methods: {
  252. hello(n: number) {}
  253. }
  254. }
  255. ],
  256. created() {
  257. this.hello(this.foo)
  258. this.hello(this.bar)
  259. // @ts-expect-error
  260. this.hello(this.p1)
  261. this.hello(this.p2)
  262. }
  263. })