]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: move prop decorator into core, expose initial props to initialziers
authorEvan You <yyx990803@gmail.com>
Wed, 27 Feb 2019 02:33:50 +0000 (21:33 -0500)
committerEvan You <yyx990803@gmail.com>
Wed, 27 Feb 2019 02:33:50 +0000 (21:33 -0500)
12 files changed:
packages/decorators/.npmignore [deleted file]
packages/decorators/README.md [deleted file]
packages/decorators/index.js [deleted file]
packages/decorators/package.json [deleted file]
packages/runtime-core/__tests__/propDecorator.spec.ts [moved from packages/decorators/__tests__/prop.spec.ts with 80% similarity]
packages/runtime-core/src/componentOptions.ts
packages/runtime-core/src/componentProps.ts
packages/runtime-core/src/componentProxy.ts
packages/runtime-core/src/componentState.ts
packages/runtime-core/src/index.ts
packages/runtime-core/src/optional/propDecorator.ts [moved from packages/decorators/src/index.ts with 69% similarity]
packages/shared/src/index.ts

diff --git a/packages/decorators/.npmignore b/packages/decorators/.npmignore
deleted file mode 100644 (file)
index bb5c8a5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-__tests__/
-__mocks__/
-dist/packages
\ No newline at end of file
diff --git a/packages/decorators/README.md b/packages/decorators/README.md
deleted file mode 100644 (file)
index d06feab..0000000
+++ /dev/null
@@ -1 +0,0 @@
-# @vue/decorators
\ No newline at end of file
diff --git a/packages/decorators/index.js b/packages/decorators/index.js
deleted file mode 100644 (file)
index 6817e44..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-'use strict'
-
-if (process.env.NODE_ENV === 'production') {
-  module.exports = require('./dist/decorators.cjs.prod.js')
-} else {
-  module.exports = require('./dist/decorators.cjs.js')
-}
diff --git a/packages/decorators/package.json b/packages/decorators/package.json
deleted file mode 100644 (file)
index e88e438..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "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
similarity index 80%
rename from packages/decorators/__tests__/prop.spec.ts
rename to packages/runtime-core/__tests__/propDecorator.spec.ts
index b2714f3fdd527e949f9157062e21cc9835904b3d..1ea33c60639ee38e53c55075b502ea03a130d807 100644 (file)
@@ -1,4 +1,4 @@
-import { prop } from '../src/index'
+import { prop } from '../src/optional/propDecorator'
 import { Component, createInstance } from '@vue/runtime-test'
 
 test('without options', () => {
@@ -32,16 +32,20 @@ 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
     }
   }
 
@@ -49,6 +53,7 @@ test('with options', () => {
   createInstance(Foo)
   expect(capturedThisValue).toBe(1)
   expect(capturedPropsValue).toBe(1)
+  expect(capturedDataValue).toBe(2)
 
   // explicit override
   createInstance(Foo, {
@@ -56,4 +61,5 @@ test('with options', () => {
   })
   expect(capturedThisValue).toBe(2)
   expect(capturedPropsValue).toBe(2)
+  expect(capturedDataValue).toBe(3)
 })
index 08112569e90d8773bc5050eaf44d4976e7f55286..6ce1092b6a4323ae824ba68e8dd4d55db1ce96b0 100644 (file)
@@ -105,6 +105,10 @@ export const reservedMethods: ReservedKeys = {
   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_/
index 01e17922ca02fc0f1d5f75350ff2046c3a75a8c4..91defca4e39f2943f92ced3513d299527b9598fb 100644 (file)
@@ -5,7 +5,8 @@ import {
   PropOptions,
   Prop,
   PropType,
-  ComponentPropsOptions
+  ComponentPropsOptions,
+  isReservedKey
 } from './componentOptions'
 import {
   EMPTY_OBJ,
@@ -43,6 +44,15 @@ export function initializeProps(
       ? 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.
@@ -59,7 +69,7 @@ export function resolveProps(
   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
@@ -129,22 +139,32 @@ export function normalizePropsOptions(
       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.`)
       }
     }
   }
index 01871522e45e32293576ec554c5fda6548c1af69..b5855409ef7064a2d8f6bbd5dc640451a6e92ff2 100644 (file)
@@ -1,7 +1,7 @@
 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()
index 8b6035c9a24a10b9caba64408bf12b1695ca6023..b5ed9d4da96671b314b5932667b52fba5fc890e9 100644 (file)
@@ -1,7 +1,6 @@
 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,
@@ -25,16 +24,8 @@ export function extractInitializers(
   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]
       }
     }
index 078e319591a1386636bd725d5c813493b59b32c7..0760f609dc5fefd77117abf1e003d826c0928291 100644 (file)
@@ -31,6 +31,7 @@ export { KeepAlive } from './optional/keepAlive'
 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'
similarity index 69%
rename from packages/decorators/src/index.ts
rename to packages/runtime-core/src/optional/propDecorator.ts
index 0989910529c7b7da10cb4d722881632a82a2020c..8cdb088f95c256e811767513fa25cfe407ab5035 100644 (file)
@@ -1,4 +1,6 @@
-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>,
@@ -16,7 +18,7 @@ export function prop(
 
 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
   })
 }
index 769343dd7030cffcb2d87363b519b3f0413832c0..1f23bf403ca922de943868c408043da940eb656d 100644 (file)
@@ -5,7 +5,6 @@ export const NOOP = () => {}
 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 =>