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 {
|
import {
|
||||||
reactive,
|
reactive,
|
||||||
computed,
|
computed,
|
||||||
watchEffect,
|
|
||||||
onMounted,
|
onMounted,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
next,
|
watchPostEffect,
|
||||||
nextTick,
|
|
||||||
} from 'vue'
|
} from 'vue'
|
||||||
|
|
||||||
const STORAGE_KEY = 'todos-vuejs-3.x'
|
const STORAGE_KEY = 'todos-vuejs-3.x'
|
||||||
|
@ -72,7 +70,7 @@ const state = reactive({
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
watchEffect(() => {
|
watchPostEffect(() => {
|
||||||
todoStorage.save(state.todos)
|
todoStorage.save(state.todos)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -138,8 +136,8 @@ function removeCompleted() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// vapor custom directive
|
// vapor custom directive
|
||||||
const vTodoFocus = (el, value) => () => {
|
const vTodoFocus = (el, value) => {
|
||||||
if (value()) nextTick(() => el.focus())
|
watchPostEffect(() => value() && el.focus())
|
||||||
}
|
}
|
||||||
</script>
|
</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 type { VaporComponentInstance } from '../component'
|
||||||
import { renderEffect } from '../renderEffect'
|
|
||||||
|
|
||||||
// !! vapor directive is different from vdom directives
|
// !! vapor directive is different from vdom directives
|
||||||
export type VaporDirective = (
|
export type VaporDirective = (
|
||||||
|
@ -13,11 +12,11 @@ export type VaporDirective = (
|
||||||
type VaporDirectiveArguments = Array<
|
type VaporDirectiveArguments = Array<
|
||||||
| [VaporDirective | undefined]
|
| [VaporDirective | undefined]
|
||||||
| [VaporDirective | undefined, () => any]
|
| [VaporDirective | undefined, () => any]
|
||||||
| [VaporDirective | undefined, () => any, argument: string]
|
| [VaporDirective | undefined, (() => any) | undefined, argument: string]
|
||||||
| [
|
| [
|
||||||
VaporDirective | undefined,
|
VaporDirective | undefined,
|
||||||
value: () => any,
|
value: (() => any) | undefined,
|
||||||
argument: string,
|
argument: string | undefined,
|
||||||
modifiers: DirectiveModifiers,
|
modifiers: DirectiveModifiers,
|
||||||
]
|
]
|
||||||
>
|
>
|
||||||
|
@ -30,7 +29,7 @@ export function withVaporDirectives(
|
||||||
for (const [dir, value, argument, modifiers] of dirs) {
|
for (const [dir, value, argument, modifiers] of dirs) {
|
||||||
if (dir) {
|
if (dir) {
|
||||||
const ret = dir(node, value, argument, modifiers)
|
const ret = dir(node, value, argument, modifiers)
|
||||||
if (ret) renderEffect(ret)
|
if (ret) onScopeDispose(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue