diff --git a/src/core/component/engines/vue3/component.ts b/src/core/component/engines/vue3/component.ts index 37cfc96134..2cee24ee5f 100644 --- a/src/core/component/engines/vue3/component.ts +++ b/src/core/component/engines/vue3/component.ts @@ -45,15 +45,17 @@ export function getComponent(meta: ComponentMeta): ComponentOptions { - // eslint-disable-next-line @v4fire/unbound-method - const {unwatch} = watch(ctx.$fields, {deep: true, immediate: true}, handler); - return unwatch; - }; - - ctx.$async.on(emitter, 'mutation', watcher, { - group: 'watchers:suspend' - }); + if (meta.hasForceUpdateFields) { + const emitter: Function = (_: unknown, handler: WatchHandler) => { + // eslint-disable-next-line @v4fire/unbound-method + const {unwatch} = watch(ctx.$fields, {deep: true, immediate: true}, handler); + return unwatch; + }; + + ctx.$async.on(emitter, 'mutation', watcher, { + group: 'watchers:suspend' + }); + } return SSR ? {} : ctx.$fields; diff --git a/src/core/component/meta/create.ts b/src/core/component/meta/create.ts index b900798319..c30624101c 100644 --- a/src/core/component/meta/create.ts +++ b/src/core/component/meta/create.ts @@ -35,6 +35,7 @@ export function createMeta(component: ComponentConstructorInfo): ComponentMeta { tiedFields: {}, systemFields: {}, computedFields: {}, + hasForceUpdateFields: false, methods: {}, accessors: {}, diff --git a/src/core/component/meta/fill.ts b/src/core/component/meta/fill.ts index 64f81bf178..10ef7d3224 100644 --- a/src/core/component/meta/fill.ts +++ b/src/core/component/meta/fill.ts @@ -157,6 +157,10 @@ export function fillMeta( [meta.systemFields, meta.fields].forEach((field) => { Object.entries(field).forEach(([key, field]) => { + if (field?.forceUpdate === true) { + meta.hasForceUpdateFields = true; + } + field?.watchers?.forEach((watcher) => { if (isFunctional && watcher.functional === false) { return; diff --git a/src/core/component/meta/interface/index.ts b/src/core/component/meta/interface/index.ts index 3076cbbde9..791599fdf9 100644 --- a/src/core/component/meta/interface/index.ts +++ b/src/core/component/meta/interface/index.ts @@ -104,6 +104,11 @@ export interface ComponentMeta { */ tiedFields: Dictionary; + /** + * True, if the component has fields with force update option + */ + hasForceUpdateFields: boolean; + /** * A dictionary that contains the accessor methods of the component that support caching or watching */ diff --git a/src/core/component/watch/bind.ts b/src/core/component/watch/bind.ts index b766312c48..3295521b3d 100644 --- a/src/core/component/watch/bind.ts +++ b/src/core/component/watch/bind.ts @@ -53,7 +53,7 @@ export function bindRemoteWatchers(component: ComponentInterface, params?: BindR // True if the method has been invoked with passing the custom async instance as a property customAsync = $a !== unsafe.$async; - // Iterate over all registered watchers and listeners and initialize their + // Iterate over all registered watchers and listeners and initialize them Object.entries(watchersMap).forEach(([watchPath, watchers]) => { if (watchers == null) { return; @@ -139,7 +139,7 @@ export function bindRemoteWatchers(component: ComponentInterface, params?: BindR // Currently, we need to create a wrapper for our handler because there // are some conditions associated with the watcher: // - // 1. It may or may doesn't provide arguments from the listened event. + // 1. It may or may not provide arguments from the listened event. // 2. The handler can be specified either as a function or as a component method name. // // Additionally, we have two different scenarios: diff --git a/src/core/component/watch/component-api.ts b/src/core/component/watch/component-api.ts index 8f2b699c11..2985d42cdb 100644 --- a/src/core/component/watch/component-api.ts +++ b/src/core/component/watch/component-api.ts @@ -47,7 +47,7 @@ import type { ComponentInterface, RawWatchHandler } from 'core/component/interfa export function implementComponentWatchAPI(component: ComponentInterface): void { const { unsafe, - unsafe: {$async: $a, meta: {computedFields, watchDependencies, watchPropDependencies, params}}, + unsafe: {$async: $a, meta: {computedFields, watchDependencies, watchPropDependencies, params, hasForceUpdateFields}}, $renderEngine: {proxyGetters} } = component; @@ -171,7 +171,7 @@ export function implementComponentWatchAPI(component: ComponentInterface): void let fieldsWatcher; - if (isFunctional) { + if (isFunctional || !hasForceUpdateFields) { // Don't force watching of fields until it becomes necessary fieldsInfo.value[watcherInitializer] = () => { delete fieldsInfo.value[watcherInitializer];