feat(runtime-vapor): setup helpers useAttrs & useSlots (#172)
This commit is contained in:
parent
9f8bf4fc82
commit
db140a1e37
|
@ -0,0 +1,87 @@
|
|||
import type { SetupContext } from '../src/component'
|
||||
import {
|
||||
createComponent,
|
||||
defineComponent,
|
||||
ref,
|
||||
template,
|
||||
useAttrs,
|
||||
useSlots,
|
||||
} from '../src'
|
||||
import { makeRender } from './_utils'
|
||||
|
||||
const define = makeRender<any>()
|
||||
|
||||
describe('SFC <script setup> helpers', () => {
|
||||
test.todo('should warn runtime usage', () => {})
|
||||
|
||||
test('useSlots / useAttrs (no args)', () => {
|
||||
let slots: SetupContext['slots'] | undefined
|
||||
let attrs: SetupContext['attrs'] | undefined
|
||||
|
||||
const Comp = {
|
||||
setup() {
|
||||
slots = useSlots()
|
||||
attrs = useAttrs()
|
||||
},
|
||||
}
|
||||
const count = ref(0)
|
||||
const passedAttrs = { id: () => count.value }
|
||||
const passedSlots = {
|
||||
default: () => template('')(),
|
||||
x: () => template('')(),
|
||||
}
|
||||
|
||||
const { render } = define({
|
||||
render: () => createComponent(Comp, passedAttrs, passedSlots),
|
||||
})
|
||||
render()
|
||||
|
||||
expect(typeof slots!.default).toBe('function')
|
||||
expect(typeof slots!.x).toBe('function')
|
||||
expect(attrs).toMatchObject({ id: 0 })
|
||||
|
||||
count.value++
|
||||
expect(attrs).toMatchObject({ id: 1 })
|
||||
})
|
||||
|
||||
test('useSlots / useAttrs (with args)', () => {
|
||||
let slots: SetupContext['slots'] | undefined
|
||||
let attrs: SetupContext['attrs'] | undefined
|
||||
let ctx: SetupContext | undefined
|
||||
const Comp = defineComponent({
|
||||
setup(_, _ctx) {
|
||||
slots = useSlots()
|
||||
attrs = useAttrs()
|
||||
ctx = _ctx
|
||||
},
|
||||
})
|
||||
const { render } = define({ render: () => createComponent(Comp) })
|
||||
render()
|
||||
expect(slots).toBe(ctx!.slots)
|
||||
expect(attrs).toBe(ctx!.attrs)
|
||||
})
|
||||
|
||||
describe.todo('mergeDefaults', () => {
|
||||
test.todo('object syntax', () => {})
|
||||
test.todo('array syntax', () => {})
|
||||
test.todo('merging with skipFactory', () => {})
|
||||
test.todo('should warn missing', () => {})
|
||||
})
|
||||
|
||||
describe('mergeModels', () => {
|
||||
test.todo('array syntax', () => {})
|
||||
test.todo('object syntax', () => {})
|
||||
test.todo('overwrite', () => {})
|
||||
})
|
||||
|
||||
test.todo('createPropsRestProxy', () => {})
|
||||
|
||||
describe.todo('withAsyncContext', () => {
|
||||
test.todo('basic', async () => {})
|
||||
test.todo('error handling', async () => {})
|
||||
test.todo('should not leak instance on multiple awaits', async () => {})
|
||||
test.todo('should not leak on multiple awaits + error', async () => {})
|
||||
test.todo('race conditions', async () => {})
|
||||
test.todo('should teardown in-scope effects', async () => {})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,24 @@
|
|||
import {
|
||||
type SetupContext,
|
||||
createSetupContext,
|
||||
getCurrentInstance,
|
||||
} from './component'
|
||||
import { warn } from './warning'
|
||||
|
||||
// TODO: warning compiler-macros runtime usages
|
||||
|
||||
export function useSlots(): SetupContext['slots'] {
|
||||
return getContext().slots
|
||||
}
|
||||
|
||||
export function useAttrs(): SetupContext['attrs'] {
|
||||
return getContext().attrs
|
||||
}
|
||||
|
||||
function getContext(): SetupContext {
|
||||
const i = getCurrentInstance()!
|
||||
if (__DEV__ && !i) {
|
||||
warn(`useContext() called without active instance.`)
|
||||
}
|
||||
return i.setupContext || (i.setupContext = createSetupContext(i))
|
||||
}
|
|
@ -110,6 +110,7 @@ export {
|
|||
onErrorCaptured,
|
||||
// onServerPrefetch,
|
||||
} from './apiLifecycle'
|
||||
export { useAttrs, useSlots } from './apiSetupHelpers'
|
||||
export {
|
||||
createVaporApp,
|
||||
type App,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
import {
|
||||
getCurrentInstance,
|
||||
onBeforeMount,
|
||||
onBeforeUnmount,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
useAttrs,
|
||||
watchEffect,
|
||||
} from 'vue/vapor'
|
||||
|
||||
|
@ -14,7 +14,7 @@ const props = defineProps<{
|
|||
baz: string
|
||||
}>()
|
||||
|
||||
const attrs = getCurrentInstance()?.attrs
|
||||
const attrs = useAttrs()
|
||||
|
||||
watchEffect(() => {
|
||||
console.log({ ...attrs })
|
||||
|
@ -29,8 +29,12 @@ onUnmounted(() => console.log('sub: unmounted'))
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>sub-comp</div>
|
||||
{{ props }}
|
||||
{{ attrs }}
|
||||
{{ keys(attrs) }}
|
||||
<h2>sub-comp</h2>
|
||||
<p>
|
||||
props: {{ props }}
|
||||
<br />
|
||||
attrs: {{ attrs }}
|
||||
<br />
|
||||
keys(attrs): {{ keys(attrs) }}
|
||||
</p>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue