diff --git a/.vscode/settings.json b/.vscode/settings.json index 25fa6215..dcd05e74 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,29 @@ { - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "cSpell.enabledLanguageIds": [ + "asciidoc", + "c", + "cpp", + "csharp", + "css", + "go", + "handlebars", + "html", + "jade", + "javascriptreact", + "json", + "latex", + "less", + "markdown", + "php", + "plaintext", + "pub", + "python", + "restructuredtext", + "rust", + "scss", + "text", + "typescriptreact", + "yml" + ] } diff --git a/packages/core/package.json b/packages/core/package.json index 29e9e086..17d243c2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -20,6 +20,7 @@ }, "homepage": "https://github.com/vuejs/vue/tree/dev/packages/core#readme", "dependencies": { - "@vue/observer": "3.0.0-alpha.1" + "@vue/observer": "3.0.0-alpha.1", + "@vue/scheduler": "3.0.0-alpha.1" } } diff --git a/packages/core/src/component.ts b/packages/core/src/component.ts index 865c992e..09650c99 100644 --- a/packages/core/src/component.ts +++ b/packages/core/src/component.ts @@ -8,6 +8,7 @@ import { } from './componentOptions' import { setupWatcher } from './componentWatch' import { Autorun, DebuggerEvent, ComputedGetter } from '@vue/observer' +import { nextTick } from '@vue/scheduler' type Flatten = { [K in keyof T]: T[K] } @@ -70,7 +71,6 @@ export class Component { public $options: any public $proxy: any = null public $forceUpdate: (() => void) | null = null - public $nextTick: ((fn: () => void) => Promise) | null = null public _rawData: Data | null = null public _computedGetters: Record | null = null @@ -91,6 +91,10 @@ export class Component { } } + $nextTick(fn: () => any): Promise { + return nextTick(fn) + } + $watch( this: MountedComponent, keyOrFn: string | (() => any), diff --git a/packages/core/src/componentWatch.ts b/packages/core/src/componentWatch.ts index c18ff9ad..fe33c3f8 100644 --- a/packages/core/src/componentWatch.ts +++ b/packages/core/src/componentWatch.ts @@ -1,6 +1,7 @@ import { MountedComponent } from './component' import { ComponentWatchOptions } from './componentOptions' import { autorun, stop } from '@vue/observer' +import { queueJob } from '@vue/scheduler' export function initializeWatch( instance: MountedComponent, @@ -40,8 +41,9 @@ export function setupWatcher( const runner = autorun(rawGetter, { scheduler: () => { - // defer watch callback using the scheduler injected defer. - instance._queueJob(applyCb) + // defer watch callback using the scheduler so that multiple mutations + // result in one call only. + queueJob(applyCb) } }) diff --git a/packages/core/src/createRenderer.ts b/packages/core/src/createRenderer.ts index ca4962ca..b01f9750 100644 --- a/packages/core/src/createRenderer.ts +++ b/packages/core/src/createRenderer.ts @@ -1,4 +1,5 @@ import { autorun, stop } from '@vue/observer' +import { queueJob } from '@vue/scheduler' import { VNodeFlags, ChildrenFlags } from './flags' import { EMPTY_OBJ, isReservedProp } from './utils' import { @@ -56,10 +57,6 @@ interface PatchDataFunction { } interface RendererOptions { - scheduler: { - nextTick: (fn: () => void) => Promise - queueJob: (fn: () => void, postFlushJob?: () => void) => void - } nodeOps: NodeOps patchData: PatchDataFunction teardownVNode?: (vnode: VNode) => void @@ -71,7 +68,6 @@ interface RendererOptions { // renderer alongside an actual renderer. export function createRenderer(options: RendererOptions) { const { - scheduler: { queueJob, nextTick }, nodeOps: { createElement: platformCreateElement, createText: platformCreateText, @@ -1189,10 +1185,6 @@ export function createRenderer(options: RendererOptions) { (__COMPAT__ && (parentVNode.children as MountedComponent)) || createComponentInstance(parentVNode, Component, parentComponent) - // renderer-injected scheduler methods - instance.$nextTick = nextTick - instance._queueJob = queueJob - const queueUpdate = (instance.$forceUpdate = () => { queueJob(instance._updateHandle, flushHooks) }) @@ -1318,6 +1310,9 @@ export function createRenderer(options: RendererOptions) { } } flushHooks() + return vnode && vnode.flags & VNodeFlags.COMPONENT_STATEFUL + ? (vnode.children as MountedComponent).$proxy + : null } return { render } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 6cd5decc..e838d806 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -10,6 +10,9 @@ export const Component = InternalComponent as ComponentClass // observer api export * from '@vue/observer' +// scheduler api +export { nextTick } from '@vue/scheduler' + // internal api export { createComponentInstance } from './componentUtils' diff --git a/packages/observer/README.md b/packages/observer/README.md index db173a91..30e92587 100644 --- a/packages/observer/README.md +++ b/packages/observer/README.md @@ -11,3 +11,8 @@ The implementation of this module is inspired by the following prior art in the - [Meteor Tracker](https://docs.meteor.com/api/tracker.html) - [nx-js/observer-util](https://github.com/nx-js/observer-util) - [salesforce/observable-membrane](https://github.com/salesforce/observable-membrane) + + +## Caveats + +- Built-in objects are not observed except for `Map`, `WeakMap`, `Set` and `WeakSet`. diff --git a/packages/observer/__tests__/collections/Map.spec.ts b/packages/observer/__tests__/collections/Map.spec.ts index 20f97874..52e4a91d 100644 --- a/packages/observer/__tests__/collections/Map.spec.ts +++ b/packages/observer/__tests__/collections/Map.spec.ts @@ -235,5 +235,15 @@ describe('observer/collections', () => { observed.get('key').a = 2 expect(dummy).toBe(2) }) + + it('should observe iterated values (forEach)', () => {}) + + it('should observe iterated values (values)', () => {}) + + it('should observe iterated values (keys)', () => {}) + + it('should observe iterated values (entries)', () => {}) + + it('should observe iterated values (for...of)', () => {}) }) }) diff --git a/packages/observer/src/collectionHandlers.ts b/packages/observer/src/collectionHandlers.ts index 3946faf6..48cb7dd7 100644 --- a/packages/observer/src/collectionHandlers.ts +++ b/packages/observer/src/collectionHandlers.ts @@ -158,6 +158,7 @@ const immutableInstrumentations: any = { const target = unwrap(this) const proto: any = Reflect.getPrototypeOf(target) track(target, OperationTypes.ITERATE) + // TODO values retrived from iterations should also be observables return proto[method].apply(target, args) } }) diff --git a/packages/renderer-dom/package.json b/packages/renderer-dom/package.json index d4402b5c..b5a33ed9 100644 --- a/packages/renderer-dom/package.json +++ b/packages/renderer-dom/package.json @@ -25,7 +25,6 @@ }, "homepage": "https://github.com/vuejs/vue/tree/dev/packages/renderer-dom#readme", "dependencies": { - "@vue/core": "3.0.0-alpha.1", - "@vue/scheduler": "3.0.0-alpha.1" + "@vue/core": "3.0.0-alpha.1" } } diff --git a/packages/renderer-dom/src/index.ts b/packages/renderer-dom/src/index.ts index e1057c3f..7d5bd465 100644 --- a/packages/renderer-dom/src/index.ts +++ b/packages/renderer-dom/src/index.ts @@ -1,15 +1,9 @@ import { createRenderer, VNode } from '@vue/core' -import { queueJob, nextTick } from '@vue/scheduler' - import { nodeOps } from './nodeOps' import { patchData } from './patchData' import { teardownVNode } from './teardownVNode' const { render: _render } = createRenderer({ - scheduler: { - queueJob, - nextTick - }, nodeOps, patchData, teardownVNode @@ -18,9 +12,6 @@ const { render: _render } = createRenderer({ type publicRender = (node: VNode | null, container: HTMLElement) => void export const render = _render as publicRender -// nextTick from scheduler -export { nextTick } from '@vue/scheduler' - // re-export everything from core -// h, Component, observer API, flags & types +// h, Component, observer API, nextTick, flags & types export * from '@vue/core'