wip: custom directive compat
This commit is contained in:
parent
d619a770a8
commit
47b765d63a
49
packages/runtime-core/src/compat/customDirective.ts
Normal file
49
packages/runtime-core/src/compat/customDirective.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { isArray } from '@vue/shared/src'
|
||||
import { ObjectDirective, DirectiveHook } from '../directives'
|
||||
import { DeprecationTypes, warnDeprecation } from './deprecations'
|
||||
|
||||
export interface LegacyDirective {
|
||||
bind?: DirectiveHook
|
||||
inserted?: DirectiveHook
|
||||
update?: DirectiveHook
|
||||
componentUpdated?: DirectiveHook
|
||||
unbind?: DirectiveHook
|
||||
}
|
||||
|
||||
const legacyDirectiveHookMap: Partial<
|
||||
Record<
|
||||
keyof ObjectDirective,
|
||||
keyof LegacyDirective | (keyof LegacyDirective)[]
|
||||
>
|
||||
> = {
|
||||
beforeMount: 'bind',
|
||||
mounted: 'inserted',
|
||||
updated: ['update', 'componentUpdated'],
|
||||
unmounted: 'unbind'
|
||||
}
|
||||
|
||||
export function mapCompatDirectiveHook(
|
||||
name: keyof ObjectDirective,
|
||||
dir: ObjectDirective & LegacyDirective
|
||||
): DirectiveHook | DirectiveHook[] | undefined {
|
||||
const mappedName = legacyDirectiveHookMap[name]
|
||||
if (mappedName) {
|
||||
if (isArray(mappedName)) {
|
||||
const hook: DirectiveHook[] = []
|
||||
mappedName.forEach(name => {
|
||||
const mappedHook = dir[name]
|
||||
if (mappedHook) {
|
||||
__DEV__ &&
|
||||
warnDeprecation(DeprecationTypes.CUSTOM_DIR, mappedName, name)
|
||||
hook.push(mappedHook)
|
||||
}
|
||||
})
|
||||
return hook.length ? hook : undefined
|
||||
} else {
|
||||
if (__DEV__ && dir[mappedName]) {
|
||||
warnDeprecation(DeprecationTypes.CUSTOM_DIR, mappedName, name)
|
||||
}
|
||||
return dir[mappedName]
|
||||
}
|
||||
}
|
||||
}
|
@ -24,7 +24,9 @@ export const enum DeprecationTypes {
|
||||
OPTIONS_BEFORE_DESTROY,
|
||||
OPTIONS_DESTROYED,
|
||||
|
||||
PROPS_DEFAULT_THIS
|
||||
PROPS_DEFAULT_THIS,
|
||||
|
||||
CUSTOM_DIR
|
||||
}
|
||||
|
||||
type DeprecationData = {
|
||||
@ -157,6 +159,13 @@ const deprecations: Record<DeprecationTypes, DeprecationData> = {
|
||||
`props default value function no longer has access to "this". ` +
|
||||
`(found in prop "${key}")`,
|
||||
link: `https://v3.vuejs.org/guide/migration/props-default-this.html`
|
||||
},
|
||||
|
||||
[DeprecationTypes.CUSTOM_DIR]: {
|
||||
message: (legacyHook: string, newHook: string) =>
|
||||
`Custom directive hook "${legacyHook}" has been removed. ` +
|
||||
`Use "${newHook}" instead.`,
|
||||
link: `https://v3.vuejs.org/guide/migration/custom-directives.html`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ import { nextTick } from '../scheduler'
|
||||
import { warnDeprecation, DeprecationTypes } from './deprecations'
|
||||
import { version } from '..'
|
||||
import { LegacyConfig } from './globalConfig'
|
||||
import { LegacyDirective } from './customDirective'
|
||||
|
||||
/**
|
||||
* @deprecated the default `Vue` export has been removed in Vue 3. The type for
|
||||
@ -94,6 +95,12 @@ export function createCompatVue(
|
||||
function createCompatApp(options: ComponentOptions = {}, Ctor: any) {
|
||||
const app = createApp(options)
|
||||
|
||||
// copy over asset registries and deopt flag
|
||||
;['mixins', 'components', 'directives', 'deopt'].forEach(key => {
|
||||
// @ts-ignore
|
||||
app._context[key] = singletonApp._context[key]
|
||||
})
|
||||
|
||||
// copy over global config mutations
|
||||
isCopyingConfig = true
|
||||
for (const key in singletonApp.config) {
|
||||
@ -184,7 +191,7 @@ export function createCompatVue(
|
||||
return Vue
|
||||
}
|
||||
|
||||
Vue.component = ((name: string, comp: any) => {
|
||||
Vue.component = ((name: string, comp: Component) => {
|
||||
if (comp) {
|
||||
singletonApp.component(name, comp)
|
||||
return Vue
|
||||
@ -193,9 +200,9 @@ export function createCompatVue(
|
||||
}
|
||||
}) as any
|
||||
|
||||
Vue.directive = ((name: string, dir: any) => {
|
||||
Vue.directive = ((name: string, dir: Directive | LegacyDirective) => {
|
||||
if (dir) {
|
||||
singletonApp.directive(name, dir)
|
||||
singletonApp.directive(name, dir as Directive)
|
||||
return Vue
|
||||
} else {
|
||||
return singletonApp.directive(name)
|
||||
|
@ -18,6 +18,7 @@ import { ComponentInternalInstance, Data } from './component'
|
||||
import { currentRenderingInstance } from './componentRenderContext'
|
||||
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
|
||||
import { ComponentPublicInstance } from './componentPublicInstance'
|
||||
import { mapCompatDirectiveHook } from './compat/customDirective'
|
||||
|
||||
export interface DirectiveBinding<V = any> {
|
||||
instance: ComponentPublicInstance | null
|
||||
@ -124,7 +125,10 @@ export function invokeDirectiveHook(
|
||||
if (oldBindings) {
|
||||
binding.oldValue = oldBindings[i].value
|
||||
}
|
||||
const hook = binding.dir[name] as DirectiveHook | undefined
|
||||
let hook = binding.dir[name] as DirectiveHook | DirectiveHook[] | undefined
|
||||
if (__COMPAT__ && !hook) {
|
||||
hook = mapCompatDirectiveHook(name, binding.dir)
|
||||
}
|
||||
if (hook) {
|
||||
callWithAsyncErrorHandling(hook, instance, ErrorCodes.DIRECTIVE_HOOK, [
|
||||
vnode.el,
|
||||
|
Loading…
Reference in New Issue
Block a user