فهرست منبع

wip: allow compatConfig mode to be a function

Evan You 5 سال پیش
والد
کامیت
37ee2959fc
2فایلهای تغییر یافته به همراه35 افزوده شده و 3 حذف شده
  1. 9 3
      packages/runtime-core/src/compat/compatConfig.ts
  2. 26 0
      packages/vue-compat/__tests__/misc.spec.ts

+ 9 - 3
packages/runtime-core/src/compat/compatConfig.ts

@@ -1,5 +1,6 @@
-import { extend, hasOwn, isArray } from '@vue/shared'
+import { extend, hasOwn, isArray, isFunction } from '@vue/shared'
 import {
+  Component,
   ComponentInternalInstance,
   ComponentOptions,
   formatComponentName,
@@ -505,7 +506,7 @@ export function warnDeprecation(
 export type CompatConfig = Partial<
   Record<DeprecationTypes, boolean | 'suppress-warning'>
 > & {
-  MODE?: 2 | 3
+  MODE?: 2 | 3 | ((comp: Component | null) => 2 | 3)
 }
 
 export const globalCompatConfig: CompatConfig = {
@@ -574,8 +575,13 @@ export function isCompatEnabled(
     return false
   }
 
-  const mode = getCompatConfigForKey('MODE', instance) || 2
+  const rawMode = getCompatConfigForKey('MODE', instance) || 2
   const val = getCompatConfigForKey(key, instance)
+
+  const mode = isFunction(rawMode)
+    ? rawMode(instance && instance.type)
+    : rawMode
+
   if (mode === 2) {
     return val !== false
   } else {

+ 26 - 0
packages/vue-compat/__tests__/misc.spec.ts

@@ -6,6 +6,7 @@ import {
   toggleDeprecationWarning
 } from '../../runtime-core/src/compat/compatConfig'
 import { triggerEvent } from './utils'
+import { h } from '@vue/runtime-core'
 
 beforeEach(() => {
   toggleDeprecationWarning(true)
@@ -20,6 +21,31 @@ afterEach(() => {
   Vue.configureCompat({ MODE: 3 })
 })
 
+test('mode as function', () => {
+  const Foo = {
+    name: 'Foo',
+    render: (h: any) => h('div', 'foo')
+  }
+
+  const Bar = {
+    name: 'Bar',
+    data: () => ({ msg: 'bar' }),
+    render: (ctx: any) => h('div', ctx.msg)
+  }
+
+  toggleDeprecationWarning(false)
+  Vue.configureCompat({
+    MODE: comp => (comp && comp.name === 'Bar' ? 3 : 2)
+  })
+
+  const vm = new Vue({
+    components: { Foo, Bar },
+    template: `<div><foo/><bar/></div>`
+  }).$mount()
+
+  expect(vm.$el.innerHTML).toBe(`<div>foo</div><div>bar</div>`)
+})
+
 test('WATCH_ARRAY', async () => {
   const spy = jest.fn()
   const vm = new Vue({