wip: filters compat
This commit is contained in:
@@ -17,6 +17,7 @@ import { isFunction, NO, isObject } from '@vue/shared'
|
||||
import { version } from '.'
|
||||
import { installCompatMount } from './compat/global'
|
||||
import { installLegacyConfigProperties } from './compat/globalConfig'
|
||||
import { installGlobalFilterMethod } from './compat/filter'
|
||||
|
||||
export interface App<HostElement = any> {
|
||||
version: string
|
||||
@@ -43,7 +44,13 @@ export interface App<HostElement = any> {
|
||||
_context: AppContext
|
||||
|
||||
/**
|
||||
* @internal 2.x compat only
|
||||
* v2 compat only
|
||||
*/
|
||||
filter?(name: string): Function | undefined
|
||||
filter?(name: string, filter: Function): this
|
||||
|
||||
/**
|
||||
* @internal v3 compat only
|
||||
*/
|
||||
_createRoot?(options: ComponentOptions): ComponentPublicInstance
|
||||
}
|
||||
@@ -92,6 +99,11 @@ export interface AppContext {
|
||||
* @internal
|
||||
*/
|
||||
reload?: () => void
|
||||
/**
|
||||
* v2 compat only
|
||||
* @internal
|
||||
*/
|
||||
filters?: Record<string, Function>
|
||||
}
|
||||
|
||||
type PluginInstallFunction = (app: App, ...options: any[]) => any
|
||||
@@ -307,6 +319,7 @@ export function createAppAPI<HostElement>(
|
||||
|
||||
if (__COMPAT__) {
|
||||
installCompatMount(app, context, render, hydrate)
|
||||
installGlobalFilterMethod(app, context)
|
||||
if (__DEV__) installLegacyConfigProperties(app.config)
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,9 @@ export const enum DeprecationTypes {
|
||||
COMPONENT_FUNCTIONAL = 'COMPONENT_FUNCTIONAL',
|
||||
COMPONENT_V_MODEL = 'COMPONENT_V_MODEL',
|
||||
|
||||
RENDER_FUNCTION = 'RENDER_FUNCTION'
|
||||
RENDER_FUNCTION = 'RENDER_FUNCTION',
|
||||
|
||||
FILTERS = 'FILTERS'
|
||||
}
|
||||
|
||||
type DeprecationData = {
|
||||
@@ -392,6 +394,14 @@ const deprecationData: Record<DeprecationTypes, DeprecationData> = {
|
||||
}: false })\n` +
|
||||
`\n (This can also be done per-component via the "compatConfig" option.)`,
|
||||
link: `https://v3.vuejs.org/guide/migration/render-function-api.html`
|
||||
},
|
||||
|
||||
[DeprecationTypes.FILTERS]: {
|
||||
message:
|
||||
`filters have been removed in Vue 3. ` +
|
||||
`The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
|
||||
`Use method calls or computed properties instead.`,
|
||||
link: `https://v3.vuejs.org/guide/migration/filters.html`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
18
packages/runtime-core/src/compat/filter.ts
Normal file
18
packages/runtime-core/src/compat/filter.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { App, AppContext } from '../apiCreateApp'
|
||||
import { warn } from '../warning'
|
||||
import { assertCompatEnabled, DeprecationTypes } from './compatConfig'
|
||||
|
||||
export function installGlobalFilterMethod(app: App, context: AppContext) {
|
||||
context.filters = {}
|
||||
app.filter = (name: string, filter?: Function): any => {
|
||||
assertCompatEnabled(DeprecationTypes.FILTERS, null)
|
||||
if (!filter) {
|
||||
return context.filters![name]
|
||||
}
|
||||
if (__DEV__ && context.filters![name]) {
|
||||
warn(`Filter "${name}" has already been registered.`)
|
||||
}
|
||||
context.filters![name] = filter
|
||||
return app
|
||||
}
|
||||
}
|
||||
@@ -268,6 +268,11 @@ export interface ComponentInternalInstance {
|
||||
* @internal
|
||||
*/
|
||||
directives: Record<string, Directive> | null
|
||||
/**
|
||||
* Resolved filters registry, v2 compat only
|
||||
* @internal
|
||||
*/
|
||||
filters?: Record<string, Function>
|
||||
/**
|
||||
* resolved props options
|
||||
* @internal
|
||||
|
||||
@@ -72,6 +72,12 @@ import {
|
||||
isCompatEnabled,
|
||||
softAssertCompatEnabled
|
||||
} from './compat/compatConfig'
|
||||
import {
|
||||
AssetTypes,
|
||||
COMPONENTS,
|
||||
DIRECTIVES,
|
||||
FILTERS
|
||||
} from './helpers/resolveAssets'
|
||||
|
||||
/**
|
||||
* Interface for declaring custom options.
|
||||
@@ -413,6 +419,9 @@ interface LegacyOptions<
|
||||
provide?: Data | Function
|
||||
inject?: ComponentInjectOptions
|
||||
|
||||
// assets
|
||||
filters?: Record<string, Function>
|
||||
|
||||
// composition
|
||||
mixins?: Mixin[]
|
||||
extends?: Extends
|
||||
@@ -510,9 +519,6 @@ export function applyOptions(
|
||||
watch: watchOptions,
|
||||
provide: provideOptions,
|
||||
inject: injectOptions,
|
||||
// assets
|
||||
components,
|
||||
directives,
|
||||
// lifecycle
|
||||
beforeMount,
|
||||
mounted,
|
||||
@@ -721,25 +727,10 @@ export function applyOptions(
|
||||
// To reduce memory usage, only components with mixins or extends will have
|
||||
// resolved asset registry attached to instance.
|
||||
if (asMixin) {
|
||||
if (components) {
|
||||
extend(
|
||||
instance.components ||
|
||||
(instance.components = extend(
|
||||
{},
|
||||
(instance.type as ComponentOptions).components
|
||||
) as Record<string, ConcreteComponent>),
|
||||
components
|
||||
)
|
||||
}
|
||||
if (directives) {
|
||||
extend(
|
||||
instance.directives ||
|
||||
(instance.directives = extend(
|
||||
{},
|
||||
(instance.type as ComponentOptions).directives
|
||||
)),
|
||||
directives
|
||||
)
|
||||
resolveInstanceAssets(instance, options, COMPONENTS)
|
||||
resolveInstanceAssets(instance, options, DIRECTIVES)
|
||||
if (__COMPAT__ && isCompatEnabled(DeprecationTypes.FILTERS, instance)) {
|
||||
resolveInstanceAssets(instance, options, FILTERS)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,6 +809,23 @@ export function applyOptions(
|
||||
}
|
||||
}
|
||||
|
||||
function resolveInstanceAssets(
|
||||
instance: ComponentInternalInstance,
|
||||
mixin: ComponentOptions,
|
||||
type: AssetTypes
|
||||
) {
|
||||
if (mixin[type]) {
|
||||
extend(
|
||||
instance[type] ||
|
||||
(instance[type] = extend(
|
||||
{},
|
||||
(instance.type as ComponentOptions)[type]
|
||||
) as any),
|
||||
mixin[type]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveInjections(
|
||||
injectOptions: ComponentInjectOptions,
|
||||
ctx: any,
|
||||
|
||||
@@ -10,8 +10,11 @@ import { camelize, capitalize, isString } from '@vue/shared'
|
||||
import { warn } from '../warning'
|
||||
import { VNodeTypes } from '../vnode'
|
||||
|
||||
const COMPONENTS = 'components'
|
||||
const DIRECTIVES = 'directives'
|
||||
export const COMPONENTS = 'components'
|
||||
export const DIRECTIVES = 'directives'
|
||||
export const FILTERS = 'filters'
|
||||
|
||||
export type AssetTypes = typeof COMPONENTS | typeof DIRECTIVES | typeof FILTERS
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -44,6 +47,14 @@ export function resolveDirective(name: string): Directive | undefined {
|
||||
return resolveAsset(DIRECTIVES, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* v2 compat only
|
||||
* @internal
|
||||
*/
|
||||
export function resolveFilter(name: string): Function | undefined {
|
||||
return resolveAsset(FILTERS, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* overload 1: components
|
||||
@@ -60,8 +71,11 @@ function resolveAsset(
|
||||
name: string
|
||||
): Directive | undefined
|
||||
// implementation
|
||||
// overload 3: filters (compat only)
|
||||
function resolveAsset(type: typeof FILTERS, name: string): Function | undefined
|
||||
// implementation
|
||||
function resolveAsset(
|
||||
type: typeof COMPONENTS | typeof DIRECTIVES,
|
||||
type: AssetTypes,
|
||||
name: string,
|
||||
warnMissing = true,
|
||||
maybeSelfReference = false
|
||||
|
||||
@@ -293,6 +293,12 @@ import {
|
||||
checkCompatEnabled,
|
||||
softAssertCompatEnabled
|
||||
} from './compat/compatConfig'
|
||||
import { resolveFilter as _resolveFilter } from './helpers/resolveAssets'
|
||||
|
||||
/**
|
||||
* @internal only exposed in compat builds
|
||||
*/
|
||||
export const resolveFilter = __COMPAT__ ? _resolveFilter : null
|
||||
|
||||
const _compatUtils = {
|
||||
warnDeprecation,
|
||||
|
||||
Reference in New Issue
Block a user