diff --git a/packages/reactivity/__tests__/readonly.spec.ts b/packages/reactivity/__tests__/readonly.spec.ts index 0c4ee153..c2dbb3a8 100644 --- a/packages/reactivity/__tests__/readonly.spec.ts +++ b/packages/reactivity/__tests__/readonly.spec.ts @@ -86,6 +86,7 @@ describe('reactivity/readonly', () => { observed.a = 2 expect(observed.a).toBe(1) expect(dummy).toBe(1) + expect(`target is readonly`).toHaveBeenWarned() }) it('should trigger effects when unlocked', () => { @@ -178,9 +179,11 @@ describe('reactivity/readonly', () => { observed[0].a = 2 expect(observed[0].a).toBe(1) expect(dummy).toBe(1) + expect(`target is readonly`).toHaveBeenWarnedTimes(1) observed[0] = { a: 2 } expect(observed[0].a).toBe(1) expect(dummy).toBe(1) + expect(`target is readonly`).toHaveBeenWarnedTimes(2) }) it('should trigger effects when unlocked', () => { diff --git a/packages/runtime-core/__tests__/apiApp.spec.ts b/packages/runtime-core/__tests__/apiApp.spec.ts new file mode 100644 index 00000000..de66cfef --- /dev/null +++ b/packages/runtime-core/__tests__/apiApp.spec.ts @@ -0,0 +1,206 @@ +import { + createApp, + h, + nodeOps, + serializeInner, + mockWarn, + provide, + inject, + resolveComponent, + resolveDirective, + applyDirectives, + Plugin, + ref +} from '@vue/runtime-test' + +describe('api: createApp', () => { + mockWarn() + + test('mount', () => { + const Comp = { + props: { + count: { + default: 0 + } + }, + render() { + return this.count + } + } + + const root1 = nodeOps.createElement('div') + createApp().mount(Comp, root1) + expect(serializeInner(root1)).toBe(`0`) + + // mount with props + const root2 = nodeOps.createElement('div') + const app2 = createApp() + app2.mount(Comp, root2, { count: 1 }) + expect(serializeInner(root2)).toBe(`1`) + + // remount warning + const root3 = nodeOps.createElement('div') + app2.mount(Comp, root3) + expect(serializeInner(root3)).toBe(``) + expect(`already been mounted`).toHaveBeenWarned() + }) + + test('provide', () => { + const app = createApp() + app.provide('foo', 1) + app.provide('bar', 2) + + const Root = { + setup() { + // test override + provide('foo', 3) + return () => h(Child) + } + } + + const Child = { + setup() { + const foo = inject('foo') + const bar = inject('bar') + return () => `${foo},${bar}` + } + } + + const root = nodeOps.createElement('div') + app.mount(Root, root) + expect(serializeInner(root)).toBe(`3,2`) + }) + + test('component', () => { + const app = createApp() + app.component('FooBar', () => 'foobar!') + app.component('BarBaz', () => 'barbaz!') + + const Root = { + // local override + components: { + BarBaz: () => 'barbaz-local!' + }, + setup() { + // resolve in setup + const FooBar = resolveComponent('foo-bar') as any + return () => { + // resolve in render + const BarBaz = resolveComponent('bar-baz') as any + return h('div', [h(FooBar), h(BarBaz)]) + } + } + } + + const root = nodeOps.createElement('div') + app.mount(Root, root) + expect(serializeInner(root)).toBe(`
= {
} & P &
S
-type SetupFunction = {
+export type ComponentInstance = {
type: FunctionalComponent | ComponentOptions
parent: ComponentInstance | null
appContext: AppContext
@@ -193,12 +195,13 @@ export function createComponentInstance(
vnode: VNode,
parent: ComponentInstance | null
): ComponentInstance {
+ // inherit parent app context - or - if root, adopt from root vnode
+ const appContext =
+ (parent ? parent.appContext : vnode.appContext) || emptyAppContext
const instance = {
vnode,
parent,
- // inherit parent app context - or - if root, adopt from root vnode
- appContext:
- (parent ? parent.appContext : vnode.appContext) || emptyAppContext,
+ appContext,
type: vnode.type as any,
root: null as any, // set later so it can point to itself
next: null,
@@ -209,7 +212,7 @@ export function createComponentInstance(
propsProxy: null,
setupContext: null,
effects: null,
- provides: parent ? parent.provides : {},
+ provides: parent ? parent.provides : Object.create(appContext.provides),
// setup context properties
data: EMPTY_OBJ,
diff --git a/packages/runtime-core/src/directives.ts b/packages/runtime-core/src/directives.ts
index 065f7bbd..1c901de8 100644
--- a/packages/runtime-core/src/directives.ts
+++ b/packages/runtime-core/src/directives.ts
@@ -5,11 +5,10 @@ const comp = resolveComponent('comp')
const foo = resolveDirective('foo')
const bar = resolveDirective('bar')
-return applyDirectives(
- h(comp),
+return applyDirectives(h(comp), [
[foo, this.x],
[bar, this.y]
-)
+])
*/
import { VNode, cloneVNode } from './vnode'
@@ -22,7 +21,7 @@ import {
} from './component'
import { callWithAsyncErrorHandling, ErrorTypes } from './errorHandling'
import { HostNode } from './createRenderer'
-import { resolveAsset } from './apiCreateApp'
+import { resolveAsset } from './apiApp'
export interface DirectiveBinding {
instance: ComponentRenderProxy | null
@@ -103,10 +102,7 @@ type DirectiveArguments = Array<
| [Directive, any, string, DirectiveModifiers]
>
-export function applyDirectives(
- vnode: VNode,
- ...directives: DirectiveArguments
-) {
+export function applyDirectives(vnode: VNode, directives: DirectiveArguments) {
const instance = currentRenderingInstance
if (instance !== null) {
vnode = cloneVNode(vnode)
diff --git a/packages/runtime-core/src/errorHandling.ts b/packages/runtime-core/src/errorHandling.ts
index 53cadc48..42cc356d 100644
--- a/packages/runtime-core/src/errorHandling.ts
+++ b/packages/runtime-core/src/errorHandling.ts
@@ -13,6 +13,8 @@ export const enum ErrorTypes {
NATIVE_EVENT_HANDLER,
COMPONENT_EVENT_HANDLER,
DIRECTIVE_HOOK,
+ APP_ERROR_HANDLER,
+ APP_WARN_HANDLER,
SCHEDULER
}
@@ -38,6 +40,8 @@ export const ErrorTypeStrings: Record