Skip to content

Commit ad6420d

Browse files
fix(kit): should access value on ObjectRefImpl and GetterRefImpl (#563)
1 parent ca630c7 commit ad6420d

File tree

3 files changed

+145
-1
lines changed

3 files changed

+145
-1
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { getObjectDetails } from '../../src/core/component/state/custom'
2+
3+
function omitKeysOnCustom(obj: { _custom: { [key: string]: unknown } } | undefined, keys: string[]) {
4+
return obj == null ? obj : { _custom: Object.fromEntries(Object.entries(obj._custom).filter(([key]) => !keys.includes(key))) }
5+
}
6+
7+
it.each([
8+
[
9+
'computed',
10+
() => {
11+
const a = computed(() => 'foo')
12+
a.value
13+
return a
14+
},
15+
{
16+
_custom: {
17+
stateTypeName: 'Computed',
18+
type: 'computed',
19+
value: 'foo',
20+
},
21+
},
22+
],
23+
[
24+
'ref',
25+
() => {
26+
const a = ref('foo')
27+
return a
28+
},
29+
{
30+
_custom: {
31+
stateTypeName: 'Ref',
32+
type: 'ref',
33+
value: 'foo',
34+
},
35+
},
36+
],
37+
[
38+
'reactive',
39+
() => {
40+
const a = reactive({ foo: 'foo' })
41+
return a
42+
},
43+
{
44+
_custom: {
45+
stateTypeName: 'Reactive',
46+
type: 'reactive',
47+
value: {
48+
foo: 'foo',
49+
},
50+
},
51+
},
52+
],
53+
[
54+
'toRef w/ ref',
55+
() => {
56+
const foo = ref('1')
57+
const a = toRef(foo)
58+
return a
59+
},
60+
{
61+
_custom: {
62+
stateTypeName: 'Ref',
63+
type: 'ref',
64+
value: '1',
65+
},
66+
},
67+
],
68+
[
69+
'toRef w/ getter',
70+
() => {
71+
const bar = computed(() => '1')
72+
const a = toRef(() => bar.value)
73+
return a
74+
},
75+
{
76+
_custom: {
77+
stateTypeName: 'Ref',
78+
type: 'ref',
79+
value: '1',
80+
},
81+
},
82+
],
83+
[
84+
'toRef w/ object',
85+
() => {
86+
const bar = reactive({ value: '1' })
87+
const a = toRef(bar, 'value')
88+
return a
89+
},
90+
{
91+
_custom: {
92+
stateTypeName: 'Ref',
93+
type: 'ref',
94+
value: '1',
95+
},
96+
},
97+
],
98+
[
99+
'toRefs',
100+
() => {
101+
const bar = reactive({ value: '1', value2: '2' })
102+
const a = toRefs(bar)
103+
return a.value
104+
},
105+
{
106+
_custom: {
107+
stateTypeName: 'Ref',
108+
type: 'ref',
109+
value: '1',
110+
},
111+
},
112+
],
113+
])('should getObjectDetail by passing %s state', (_, state, expected) => {
114+
expect(omitKeysOnCustom(getObjectDetails(state()), ['tooltipText'])).toEqual(expected)
115+
})

packages/devtools-kit/src/core/component/state/custom.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,27 @@ export function getHTMLElementDetails(value: HTMLElement) {
218218
}
219219
}
220220

221+
/**
222+
* - ObjectRefImpl, toRef({ foo: 'foo' }, 'foo'), `value` is the actual value
223+
* - GetterRefImpl, toRef(() => state.foo), `value` is the actual value
224+
* - RefImpl, ref('foo') / computed(() => 'foo'), `_value` is the actual value
225+
*/
226+
function tryGetRefValue(ref: { _value?: unknown } | { value?: unknown }) {
227+
if (ensurePropertyExists<{ _value?: unknown }>(ref, '_value', true)) {
228+
return ref._value
229+
}
230+
if (ensurePropertyExists(ref, 'value', true)) {
231+
return ref.value
232+
}
233+
}
234+
221235
export function getObjectDetails(object: Record<string, any>) {
222236
const info = getSetupStateType(object)
223237

224238
const isState = info.ref || info.computed || info.reactive
225239
if (isState) {
226240
const stateTypeName = info.computed ? 'Computed' : info.ref ? 'Ref' : info.reactive ? 'Reactive' : null
227-
const value = toRaw(info.reactive ? object : object._value)
241+
const value = toRaw(info.reactive ? object : tryGetRefValue(object))
228242

229243
const raw = ensurePropertyExists(object, 'effect')
230244
? object.effect?.raw?.toString() || object.effect?.fn?.toString()

packages/playground/basic/src/pages/Home.vue

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22
import Foo from '../components/Foo.vue'
33
44
const visible = ref(false)
5+
6+
const obj = reactive<{
7+
count: number
8+
foo?: number
9+
bar?: string
10+
}>({
11+
count: 0,
12+
})
13+
14+
// @ts-expect-error type guard
15+
obj.foo = toRef(obj, 'count')
16+
// @ts-expect-error type guard
17+
obj.bar = ref('bar')
18+
19+
const toRefObj = toRefs(obj)
520
</script>
621

722
<template>

0 commit comments

Comments
 (0)