refactor: layout optional features
This commit is contained in:
0
packages/core/src/optional/asyncComponent.ts
Normal file
0
packages/core/src/optional/asyncComponent.ts
Normal file
0
packages/core/src/optional/await.ts
Normal file
0
packages/core/src/optional/await.ts
Normal file
57
packages/core/src/optional/context.ts
Normal file
57
packages/core/src/optional/context.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { observable } from '@vue/observer'
|
||||
import { Component } from '../component'
|
||||
import { Slots } from '../vdom'
|
||||
|
||||
const contextStore = observable() as Record<string, any>
|
||||
|
||||
export class Provide extends Component {
|
||||
updateValue() {
|
||||
contextStore[this.$props.id] = this.$props.value
|
||||
}
|
||||
created() {
|
||||
if (__DEV__) {
|
||||
if (contextStore.hasOwnProperty(this.$props.id)) {
|
||||
console.warn(
|
||||
`A context provider with id ${this.$props.id} already exists.`
|
||||
)
|
||||
}
|
||||
this.$watch(
|
||||
() => this.$props.id,
|
||||
(id: string, oldId: string) => {
|
||||
console.warn(
|
||||
`Context provider id change detected (from "${oldId}" to "${id}"). ` +
|
||||
`This is not supported and should be avoided.`
|
||||
)
|
||||
},
|
||||
{ sync: true }
|
||||
)
|
||||
}
|
||||
this.updateValue()
|
||||
}
|
||||
beforeUpdate() {
|
||||
this.updateValue()
|
||||
}
|
||||
render(_: any, slots: Slots) {
|
||||
return slots.default && slots.default()
|
||||
}
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
Provide.options = {
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Inject extends Component {
|
||||
render(props: any, slots: Slots) {
|
||||
return slots.default && slots.default(contextStore[props.id])
|
||||
}
|
||||
}
|
||||
58
packages/core/src/optional/directive.ts
Normal file
58
packages/core/src/optional/directive.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { VNode } from '../vdom'
|
||||
import { MountedComponent } from '../component'
|
||||
|
||||
export interface DirectiveBinding {
|
||||
instance: MountedComponent
|
||||
value?: any
|
||||
arg?: string
|
||||
modifiers?: DirectiveModifiers
|
||||
}
|
||||
|
||||
export type DirectiveHook = (
|
||||
el: any,
|
||||
binding: DirectiveBinding,
|
||||
vnode: VNode,
|
||||
prevVNode: VNode | void
|
||||
) => void
|
||||
|
||||
export interface Directive {
|
||||
beforeMount: DirectiveHook
|
||||
mounted: DirectiveHook
|
||||
beforeUpdate: DirectiveHook
|
||||
updated: DirectiveHook
|
||||
beforeUnmount: DirectiveHook
|
||||
unmounted: DirectiveHook
|
||||
}
|
||||
|
||||
type DirectiveModifiers = Record<string, boolean>
|
||||
|
||||
export function applyDirective(
|
||||
vnode: VNode,
|
||||
directive: Directive,
|
||||
instance: MountedComponent,
|
||||
value?: any,
|
||||
arg?: string,
|
||||
modifiers?: DirectiveModifiers
|
||||
): VNode {
|
||||
const data = vnode.data || (vnode.data = {})
|
||||
for (const key in directive) {
|
||||
const hook = directive[key as keyof Directive]
|
||||
const hookKey = `vnode` + key[0].toUpperCase() + key.slice(1)
|
||||
const vnodeHook = (vnode: VNode, prevVNode?: VNode) => {
|
||||
hook(
|
||||
vnode.el,
|
||||
{
|
||||
instance,
|
||||
value,
|
||||
arg,
|
||||
modifiers
|
||||
},
|
||||
vnode,
|
||||
prevVNode
|
||||
)
|
||||
}
|
||||
const existing = data[hookKey]
|
||||
data[hookKey] = existing ? [].concat(existing, vnodeHook as any) : vnodeHook
|
||||
}
|
||||
return vnode
|
||||
}
|
||||
0
packages/core/src/optional/keepAlive.ts
Normal file
0
packages/core/src/optional/keepAlive.ts
Normal file
Reference in New Issue
Block a user