mirror of https://github.com/vuejs/core.git
wip(vapor): new impl + test for vapor custom directive
This commit is contained in:
parent
1b50febfe9
commit
c6fe9f9417
|
@ -2,11 +2,9 @@
|
|||
import {
|
||||
reactive,
|
||||
computed,
|
||||
watchEffect,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
next,
|
||||
nextTick,
|
||||
watchPostEffect,
|
||||
} from 'vue'
|
||||
|
||||
const STORAGE_KEY = 'todos-vuejs-3.x'
|
||||
|
@ -72,7 +70,7 @@ const state = reactive({
|
|||
}),
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
watchPostEffect(() => {
|
||||
todoStorage.save(state.todos)
|
||||
})
|
||||
|
||||
|
@ -138,8 +136,8 @@ function removeCompleted() {
|
|||
}
|
||||
|
||||
// vapor custom directive
|
||||
const vTodoFocus = (el, value) => () => {
|
||||
if (value()) nextTick(() => el.focus())
|
||||
const vTodoFocus = (el, value) => {
|
||||
watchPostEffect(() => value() && el.focus())
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import { effectScope, ref } from '@vue/reactivity'
|
||||
import { type VaporDirective, withVaporDirectives } from '../../src'
|
||||
import { nextTick, watchEffect } from '@vue/runtime-dom'
|
||||
|
||||
describe('custom directive', () => {
|
||||
it('should work', async () => {
|
||||
const teardown = vi.fn()
|
||||
const dir: VaporDirective = vi.fn((el, source) => {
|
||||
watchEffect(() => {
|
||||
el.textContent = source()
|
||||
})
|
||||
return teardown
|
||||
})
|
||||
const scope = effectScope()
|
||||
const el = document.createElement('div')
|
||||
const n = ref(1)
|
||||
const source = () => n.value
|
||||
const modifiers = { mod: true }
|
||||
scope.run(() => {
|
||||
withVaporDirectives(el, [[dir, source, undefined, modifiers]])
|
||||
})
|
||||
expect(dir).toHaveBeenCalledWith(el, source, undefined, modifiers)
|
||||
expect(teardown).not.toHaveBeenCalled()
|
||||
|
||||
expect(el.textContent).toBe('1')
|
||||
|
||||
n.value = 2
|
||||
await nextTick()
|
||||
expect(el.textContent).toBe('2')
|
||||
|
||||
scope.stop()
|
||||
expect(teardown).toHaveBeenCalled()
|
||||
|
||||
n.value = 3
|
||||
await nextTick()
|
||||
// should be stopped and not update
|
||||
expect(el.textContent).toBe('2')
|
||||
})
|
||||
})
|
|
@ -1,6 +1,5 @@
|
|||
import type { DirectiveModifiers } from '@vue/runtime-dom'
|
||||
import { type DirectiveModifiers, onScopeDispose } from '@vue/runtime-dom'
|
||||
import type { VaporComponentInstance } from '../component'
|
||||
import { renderEffect } from '../renderEffect'
|
||||
|
||||
// !! vapor directive is different from vdom directives
|
||||
export type VaporDirective = (
|
||||
|
@ -13,11 +12,11 @@ export type VaporDirective = (
|
|||
type VaporDirectiveArguments = Array<
|
||||
| [VaporDirective | undefined]
|
||||
| [VaporDirective | undefined, () => any]
|
||||
| [VaporDirective | undefined, () => any, argument: string]
|
||||
| [VaporDirective | undefined, (() => any) | undefined, argument: string]
|
||||
| [
|
||||
VaporDirective | undefined,
|
||||
value: () => any,
|
||||
argument: string,
|
||||
value: (() => any) | undefined,
|
||||
argument: string | undefined,
|
||||
modifiers: DirectiveModifiers,
|
||||
]
|
||||
>
|
||||
|
@ -30,7 +29,7 @@ export function withVaporDirectives(
|
|||
for (const [dir, value, argument, modifiers] of dirs) {
|
||||
if (dir) {
|
||||
const ret = dir(node, value, argument, modifiers)
|
||||
if (ret) renderEffect(ret)
|
||||
if (ret) onScopeDispose(ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue