+++ /dev/null
-__tests__/
-__mocks__/
-dist/packages
\ No newline at end of file
+++ /dev/null
-# @vue/decorators
\ No newline at end of file
+++ /dev/null
-'use strict'
-
-if (process.env.NODE_ENV === 'production') {
- module.exports = require('./dist/decorators.cjs.prod.js')
-} else {
- module.exports = require('./dist/decorators.cjs.js')
-}
+++ /dev/null
-{
- "name": "@vue/decorators",
- "version": "3.0.0-alpha.1",
- "description": "@vue/decorators",
- "main": "index.js",
- "module": "dist/decorators.esm-bundler.js",
- "types": "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/decorators#readme"
-}
\ No newline at end of file
-import { prop } from '../src/index'
+import { prop } from '../src/optional/propDecorator'
import { Component, createInstance } from '@vue/runtime-test'
test('without options', () => {
test('with options', () => {
let capturedThisValue
let capturedPropsValue
+ let capturedDataValue
class Foo extends Component<{ p: number }> {
@prop({
default: 1
})
p: number
+ // data property should be able to make use of prop
+ d: number = this.p + 1
created() {
capturedThisValue = this.p
capturedPropsValue = this.$props.p
+ capturedDataValue = this.d
}
}
createInstance(Foo)
expect(capturedThisValue).toBe(1)
expect(capturedPropsValue).toBe(1)
+ expect(capturedDataValue).toBe(2)
// explicit override
createInstance(Foo, {
})
expect(capturedThisValue).toBe(2)
expect(capturedPropsValue).toBe(2)
+ expect(capturedDataValue).toBe(3)
})
renderTriggered: 1
}
+export function isReservedKey(key: string): boolean {
+ return key[0] === '_' || key[0] === '$' || reservedMethods.hasOwnProperty(key)
+}
+
// This is a special marker from the @prop decorator.
// The decorator stores prop options on the Class' prototype as __prop_xxx
const propPrefixRE = /^__prop_/
PropOptions,
Prop,
PropType,
- ComponentPropsOptions
+ ComponentPropsOptions,
+ isReservedKey
} from './componentOptions'
import {
EMPTY_OBJ,
? immutable(attrs)
: attrs
: instance.$props
+ // expose initial props on the raw instance so that they can be accessed
+ // in the child class constructor by class field initializers.
+ if (options != null) {
+ for (const key in props) {
+ // it's okay to just set it here because props options are normalized
+ // and reserved keys should have been filtered away
+ ;(instance as any)[key] = props[key]
+ }
+ }
}
// resolve raw VNode data.
rawData: any,
_options: NormalizedPropsOptions | void
): [Data, Data] {
- const hasDeclaredProps = _options !== void 0
+ const hasDeclaredProps = _options != null
const options = _options as NormalizedPropsOptions
if (!rawData && !hasDeclaredProps) {
return EMPTY_PROPS
if (__DEV__ && !isString(raw[i])) {
warn(`props must be strings when using array syntax.`, raw[i])
}
- normalized[camelize(raw[i])] = EMPTY_OBJ
+ const normalizedKey = camelize(raw[i])
+ if (!isReservedKey(normalizedKey)) {
+ normalized[normalizedKey] = EMPTY_OBJ
+ } else if (__DEV__) {
+ warn(`Invalid prop name: "${normalizedKey}" is a reserved property.`)
+ }
}
} else {
if (__DEV__ && !isObject(raw)) {
warn(`invalid props options`, raw)
}
for (const key in raw) {
- const opt = raw[key]
- const prop = (normalized[camelize(key)] =
- isArray(opt) || isFunction(opt) ? { type: opt } : opt)
- if (prop) {
- const booleanIndex = getTypeIndex(Boolean, prop.type)
- const stringIndex = getTypeIndex(String, prop.type)
- ;(prop as NormalizedProp)[BooleanFlags.shouldCast] = booleanIndex > -1
- ;(prop as NormalizedProp)[BooleanFlags.shouldCastTrue] =
- booleanIndex < stringIndex
+ const normalizedKey = camelize(key)
+ if (!isReservedKey(normalizedKey)) {
+ const opt = raw[key]
+ const prop = (normalized[normalizedKey] =
+ isArray(opt) || isFunction(opt) ? { type: opt } : opt)
+ if (prop) {
+ const booleanIndex = getTypeIndex(Boolean, prop.type)
+ const stringIndex = getTypeIndex(String, prop.type)
+ ;(prop as NormalizedProp)[BooleanFlags.shouldCast] = booleanIndex > -1
+ ;(prop as NormalizedProp)[BooleanFlags.shouldCastTrue] =
+ booleanIndex < stringIndex
+ }
+ } else if (__DEV__) {
+ warn(`Invalid prop name: "${normalizedKey}" is a reserved property.`)
}
}
}
import { ComponentInstance } from './component'
-import { isFunction, isReservedKey } from '@vue/shared'
+import { isFunction } from '@vue/shared'
import { isRendering } from './componentRenderUtils'
-import { reservedMethods } from './componentOptions'
+import { isReservedKey, reservedMethods } from './componentOptions'
import { warn } from './warning'
const bindCache = new WeakMap()
import { ComponentInstance } from './component'
import { observable } from '@vue/observer'
-import { isReservedKey } from '@vue/shared'
-import { warn } from './warning'
+import { isReservedKey } from './componentOptions'
export function initializeState(
instance: ComponentInstance,
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
if (!isReservedKey(key)) {
- // it's possible for a prop to be present here when it's declared with
- // decorators and has a default value.
- if (props && props.hasOwnProperty(key)) {
- __DEV__ &&
- warn(
- `Class property "${key}" is declared as a prop but also has an initializer. ` +
- `If you are trying to provide a default value for the prop, use the ` +
- `prop's "default" option instead.`
- )
- } else {
+ // it's possible for a prop to be present here when it's declared
+ if (!props || !props.hasOwnProperty(key)) {
data[key] = (instance as any)[key]
}
}
export { mixins } from './optional/mixins'
export { EventEmitter } from './optional/eventEmitter'
export { memoize } from './optional/memoize'
+export { prop } from './optional/propDecorator'
// flags & types
export { ComponentType, ComponentClass, FunctionalComponent } from './component'
-import { PropValidator, Component } from '@vue/runtime-core'
+import { Component } from '../component'
+import { PropValidator } from '../componentOptions'
+import { camelize } from '@vue/shared'
export function prop(
target: Component | PropValidator<any>,
function applyProp(target: any, key: string, options: PropValidator<any> = {}) {
// here `target` is the prototype of the component class
- Object.defineProperty(target, `__prop_${key}`, {
+ Object.defineProperty(target, `__prop_${camelize(key)}`, {
value: options
})
}
export const reservedPropRE = /^(?:key|ref|slots)$|^vnode/
export const isOn = (key: string) => key[0] === 'o' && key[1] === 'n'
-export const isReservedKey = (key: string) => key[0] === '_' || key[0] === '$'
export const isArray = Array.isArray
export const isFunction = (val: any): val is Function =>