diff --git a/packages/runtime-core/__tests__/debug.spec.ts b/packages/runtime-core/__tests__/debug.spec.ts new file mode 100644 index 000000000..3a4c4b56d --- /dev/null +++ b/packages/runtime-core/__tests__/debug.spec.ts @@ -0,0 +1,65 @@ +import { debug } from '../src/debug' +import { + type ComponentInternalInstance, + defineComponent, + getCurrentInstance, + h, + serializeInner as inner, + nodeOps, + ref, + render, +} from '@vue/runtime-test' + +describe('debug', () => { + test('watching states', () => { + const root = nodeOps.createElement('div') + let instance: ComponentInternalInstance + const Comp = defineComponent({ + setup() { + const name = ref('foo') + debug({ + name, + }) + return () => h('div', name.value) + }, + mounted() { + instance = getCurrentInstance()! + }, + }) + render(h(Comp), root) + expect(inner(root)).toBe('
foo
') + expect(instance!.setupState).toEqual({ + name: 'foo', + }) + }) + test('watching states with calling the debug function multiple times', () => { + const root = nodeOps.createElement('div') + let instance: ComponentInternalInstance + const Comp = defineComponent({ + setup() { + const name = ref('foo') + const age = ref(100) + debug({ + name, + }) + debug({ + age, + name, + }) + debug({ + name, + }) + return () => h('div', name.value) + }, + mounted() { + instance = getCurrentInstance()! + }, + }) + render(h(Comp), root) + expect(inner(root)).toBe('
foo
') + expect(instance!.setupState).toEqual({ + name: 'foo', + age: 100, + }) + }) +}) diff --git a/packages/runtime-core/src/debug.ts b/packages/runtime-core/src/debug.ts new file mode 100644 index 000000000..8ce522694 --- /dev/null +++ b/packages/runtime-core/src/debug.ts @@ -0,0 +1,30 @@ +import { reactive } from '@vue/reactivity' +import { getCurrentInstance } from './component' + +/** + * this debug function is a helper for watching states in the vue devtool (it runs only in dev mode) + * @example + * const Component = defineComponent({ + * setup() { + * const name = ref('foo') + * debug({ + * // watch states in the vue devtool + * name, + * }) + * return h('div', name.value) + * }, + * }) + * @param states any states you want to see in the vue devtool + */ +export const debug = __DEV__ + ? (states: Record) => { + const instance = getCurrentInstance() + if (instance) { + instance.setupState = reactive( + Object.assign({}, states, instance.setupState), + ) + } + } + : (states: Record) => { + // empty + } diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 9910f8210..f149dfec5 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -338,6 +338,7 @@ export type { AsyncComponentOptions, AsyncComponentLoader, } from './apiAsyncComponent' +export { debug } from './debug' export type { HydrationStrategy, HydrationStrategyFactory,