forked from vuejs/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3401f6b
Showing
63 changed files
with
8,372 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
dist | ||
.DS_Store | ||
node_modules | ||
explorations | ||
TODOs.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
semi: false | ||
singleQuote: true | ||
printWidth: 80 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"typescript.tsdk": "node_modules/typescript/lib" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"packages": [ | ||
"packages/*" | ||
], | ||
"version": "3.0.0-alpha.1" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"private": true, | ||
"workspaces": [ | ||
"packages/*" | ||
], | ||
"scripts": { | ||
"dev": "node scripts/dev.js", | ||
"build": "node scripts/build.js", | ||
"lint": "prettier --write --parser typescript 'packages/*/src/**/*.ts'" | ||
}, | ||
"devDependencies": { | ||
"chalk": "^2.4.1", | ||
"dts-bundle": "^0.7.3", | ||
"execa": "^1.0.0", | ||
"fs-extra": "^7.0.0", | ||
"lerna": "^3.4.0", | ||
"minimist": "^1.2.0", | ||
"prettier": "^1.14.2", | ||
"rollup": "^0.65.0", | ||
"rollup-plugin-alias": "^1.4.0", | ||
"rollup-plugin-replace": "^2.0.0", | ||
"rollup-plugin-terser": "^2.0.2", | ||
"rollup-plugin-typescript2": "^0.17.0", | ||
"typescript": "^3.0.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
__tests__/ | ||
__mocks__/ | ||
dist/packages |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# @vue/core | ||
|
||
> This package is published only for typing and building custom renderers. It is NOT meant to be used in applications. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
'use strict' | ||
|
||
if (process.env.NODE_ENV === 'production') { | ||
module.exports = require('./dist/core.cjs.prod.js') | ||
} else { | ||
module.exports = require('./dist/core.cjs.js') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "@vue/core", | ||
"version": "3.0.0-alpha.1", | ||
"description": "@vue/core", | ||
"main": "index.js", | ||
"module": "dist/core.esm.js", | ||
"typings": "dist/index.d.ts", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/vuejs/vue.git" | ||
}, | ||
"keywords": [ | ||
"vue" | ||
], | ||
"author": "Evan You", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/vuejs/vue/issues" | ||
}, | ||
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/core#readme", | ||
"dependencies": { | ||
"@vue/observer": "3.0.0-alpha.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import { EMPTY_OBJ } from './utils' | ||
import { VNode, Slots, RenderNode, RenderFragment } from './vdom' | ||
import { | ||
Data, | ||
RenderFunction, | ||
ComponentOptions, | ||
ComponentPropsOptions | ||
} from './componentOptions' | ||
import { setupWatcher } from './componentWatch' | ||
import { Autorun, DebuggerEvent, ComputedGetter } from '@vue/observer' | ||
|
||
type Flatten<T> = { [K in keyof T]: T[K] } | ||
|
||
export interface ComponentClass extends Flatten<typeof Component> { | ||
new <D = Data, P = Data>(): MountedComponent<D, P> & D & P | ||
} | ||
|
||
export interface FunctionalComponent<P = Data> extends RenderFunction<P> { | ||
pure?: boolean | ||
props?: ComponentPropsOptions<P> | ||
} | ||
|
||
// this interface is merged with the class type | ||
// to represent a mounted component | ||
export interface MountedComponent<D = Data, P = Data> extends Component { | ||
$vnode: VNode | ||
$data: D | ||
$props: P | ||
$computed: Data | ||
$slots: Slots | ||
$root: MountedComponent | ||
$children: MountedComponent[] | ||
$options: ComponentOptions<D, P> | ||
|
||
render: RenderFunction<P> | ||
data?(): Partial<D> | ||
beforeCreate?(): void | ||
created?(): void | ||
beforeMount?(): void | ||
mounted?(): void | ||
beforeUpdate?(e: DebuggerEvent): void | ||
updated?(): void | ||
beforeDestroy?(): void | ||
destroyed?(): void | ||
|
||
_updateHandle: Autorun | ||
$forceUpdate: () => void | ||
|
||
_self: MountedComponent<D, P> // on proxies only | ||
} | ||
|
||
export class Component { | ||
public static options?: ComponentOptions | ||
|
||
public get $el(): RenderNode | RenderFragment | null { | ||
return this.$vnode && this.$vnode.el | ||
} | ||
|
||
public $vnode: VNode | null = null | ||
public $parentVNode: VNode | null = null | ||
public $data: Data | null = null | ||
public $props: Data | null = null | ||
public $computed: Data | null = null | ||
public $slots: Slots | null = null | ||
public $root: MountedComponent | null = null | ||
public $parent: MountedComponent | null = null | ||
public $children: MountedComponent[] = [] | ||
public $options: any | ||
public $proxy: any = null | ||
public $forceUpdate: (() => void) | null = null | ||
|
||
public _rawData: Data | null = null | ||
public _computedGetters: Record<string, ComputedGetter> | null = null | ||
public _watchHandles: Set<Autorun> | null = null | ||
public _mounted: boolean = false | ||
public _destroyed: boolean = false | ||
public _events: { [event: string]: Function[] | null } | null = null | ||
public _updateHandle: Autorun | null = null | ||
public _revokeProxy: () => void | ||
public _isVue: boolean = true | ||
|
||
constructor(options?: ComponentOptions) { | ||
this.$options = options || (this.constructor as any).options || EMPTY_OBJ | ||
// root instance | ||
if (options !== void 0) { | ||
// mount this | ||
} | ||
} | ||
|
||
$watch( | ||
this: MountedComponent, | ||
keyOrFn: string | (() => any), | ||
cb: () => void | ||
) { | ||
return setupWatcher(this, keyOrFn, cb) | ||
} | ||
|
||
// eventEmitter interface | ||
$on(event: string, fn: Function): Component { | ||
if (Array.isArray(event)) { | ||
for (let i = 0; i < event.length; i++) { | ||
this.$on(event[i], fn) | ||
} | ||
} else { | ||
const events = this._events || (this._events = Object.create(null)) | ||
;(events[event] || (events[event] = [])).push(fn) | ||
} | ||
return this | ||
} | ||
|
||
$once(event: string, fn: Function): Component { | ||
const onceFn = (...args: any[]) => { | ||
this.$off(event, onceFn) | ||
fn.apply(this, args) | ||
} | ||
;(onceFn as any).fn = fn | ||
return this.$on(event, onceFn) | ||
} | ||
|
||
$off(event?: string, fn?: Function) { | ||
if (this._events) { | ||
if (!event && !fn) { | ||
this._events = null | ||
} else if (Array.isArray(event)) { | ||
for (let i = 0; i < event.length; i++) { | ||
this.$off(event[i], fn) | ||
} | ||
} else if (!fn) { | ||
this._events[event as string] = null | ||
} else { | ||
const fns = this._events[event as string] | ||
if (fns) { | ||
for (let i = 0; i < fns.length; i++) { | ||
const f = fns[i] | ||
if (fn === f || fn === (f as any).fn) { | ||
fns.splice(i, 1) | ||
break | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return this | ||
} | ||
|
||
$emit(this: MountedComponent, name: string, ...payload: any[]) { | ||
const parentListener = | ||
this.$props['on' + name] || this.$props['on' + name.toLowerCase()] | ||
if (parentListener) { | ||
invokeListeners(parentListener, payload) | ||
} | ||
if (this._events) { | ||
const handlers = this._events[name] | ||
if (handlers) { | ||
invokeListeners(handlers, payload) | ||
} | ||
} | ||
return this | ||
} | ||
} | ||
|
||
function invokeListeners(value: Function | Function[], payload: any[]) { | ||
// TODO handle error | ||
if (Array.isArray(value)) { | ||
for (let i = 0; i < value.length; i++) { | ||
value[i](...payload) | ||
} | ||
} else { | ||
value(...payload) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { EMPTY_OBJ } from './utils' | ||
import { computed, ComputedGetter } from '@vue/observer' | ||
import { Component, ComponentClass } from './component' | ||
import { ComponentComputedOptions } from './componentOptions' | ||
|
||
const extractionCache: WeakMap< | ||
ComponentClass, | ||
ComponentComputedOptions | ||
> = new WeakMap() | ||
|
||
export function getComputedOptions( | ||
comp: ComponentClass | ||
): ComponentComputedOptions { | ||
let computedOptions = extractionCache.get(comp) | ||
if (computedOptions) { | ||
return computedOptions | ||
} | ||
computedOptions = {} | ||
const descriptors = Object.getOwnPropertyDescriptors(comp.prototype as any) | ||
for (const key in descriptors) { | ||
const d = descriptors[key] | ||
if (d.get) { | ||
computedOptions[key] = d.get | ||
// there's no need to do anything for the setter | ||
// as it's already defined on the prototype | ||
} | ||
} | ||
return computedOptions | ||
} | ||
|
||
export function initializeComputed( | ||
instance: Component, | ||
computedOptions: ComponentComputedOptions | undefined | ||
) { | ||
if (!computedOptions) { | ||
instance.$computed = EMPTY_OBJ | ||
return | ||
} | ||
const handles: Record< | ||
string, | ||
ComputedGetter | ||
> = (instance._computedGetters = {}) | ||
const proxy = instance.$proxy | ||
for (const key in computedOptions) { | ||
handles[key] = computed(computedOptions[key], proxy) | ||
} | ||
instance.$computed = new Proxy( | ||
{}, | ||
{ | ||
get(_, key: any) { | ||
return handles[key]() | ||
} | ||
// TODO should be readonly | ||
} | ||
) | ||
} | ||
|
||
export function teardownComputed(instance: Component) { | ||
const handles = instance._computedGetters | ||
if (handles !== null) { | ||
for (const key in handles) { | ||
handles[key].stop() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { Slots } from './vdom' | ||
import { MountedComponent } from './component' | ||
|
||
export type Data = Record<string, any> | ||
|
||
export interface RenderFunction<P = Data> { | ||
(props: P, slots: Slots): any | ||
} | ||
|
||
export interface ComponentOptions<D = Data, P = Data> { | ||
data?: () => Partial<D> | ||
props?: ComponentPropsOptions<P> | ||
computed?: ComponentComputedOptions<D, P> | ||
watch?: ComponentWatchOptions<D, P> | ||
render?: RenderFunction<P> | ||
// TODO other options | ||
readonly [key: string]: any | ||
} | ||
|
||
export type ComponentPropsOptions<P = Data> = { | ||
[K in keyof P]: PropValidator<P[K]> | ||
} | ||
|
||
export type NormalizedPropsOptions<P = Data> = { | ||
[K in keyof P]: PropOptions<P[K]> | ||
} | ||
|
||
export type Prop<T> = { (): T } | { new (...args: any[]): T & object } | ||
|
||
export type PropType<T> = Prop<T> | Prop<T>[] | ||
|
||
export type PropValidator<T> = PropOptions<T> | PropType<T> | ||
|
||
export interface PropOptions<T = any> { | ||
type?: PropType<T> | ||
required?: boolean | ||
default?: T | null | undefined | (() => T | null | undefined) | ||
validator?(value: T): boolean | ||
} | ||
|
||
export interface ComponentComputedOptions<D = Data, P = Data> { | ||
[key: string]: (this: MountedComponent<D, P> & D & P, c: any) => any | ||
} | ||
|
||
export interface ComponentWatchOptions<D = Data, P = Data> { | ||
[key: string]: ( | ||
this: MountedComponent<D, P> & D & P, | ||
oldValue: any, | ||
newValue: any | ||
) => void | ||
} |
Oops, something went wrong.