Explorar el Código

fix property reference proxy check for hand-written render functions

Evan You hace 9 años
padre
commit
b2b9d1c272
Se han modificado 2 ficheros con 28 adiciones y 6 borrados
  1. 16 5
      src/core/instance/proxy.js
  2. 12 1
      test/unit/features/instance/render-proxy.spec.js

+ 16 - 5
src/core/instance/proxy.js

@@ -2,7 +2,7 @@
 
 import { warn, makeMap } from '../util/index'
 
-let hasProxy, proxyHandlers, initProxy
+let initProxy
 
 if (process.env.NODE_ENV !== 'production') {
   const allowedGlobals = makeMap(
@@ -21,11 +21,11 @@ if (process.env.NODE_ENV !== 'production') {
     )
   }
 
-  hasProxy =
+  const hasProxy =
     typeof Proxy !== 'undefined' &&
     Proxy.toString().match(/native code/)
 
-  proxyHandlers = {
+  const hasHandler = {
     has (target, key) {
       const has = key in target
       const isAllowed = allowedGlobals(key) || key.charAt(0) === '_'
@@ -33,8 +33,10 @@ if (process.env.NODE_ENV !== 'production') {
         warnNonPresent(target, key)
       }
       return has || !isAllowed
-    },
+    }
+  }
 
+  const getHandler = {
     get (target, key) {
       if (typeof key === 'string' && !(key in target)) {
         warnNonPresent(target, key)
@@ -45,7 +47,16 @@ if (process.env.NODE_ENV !== 'production') {
 
   initProxy = function initProxy (vm) {
     if (hasProxy) {
-      vm._renderProxy = new Proxy(vm, proxyHandlers)
+      // determine which proxy handler to use
+      let handlers
+      const options = vm.$options
+      if (options.template || options.el) {
+        handlers = hasHandler
+      }
+      if (options.render) {
+        handlers = options.render._withStripped ? getHandler : hasHandler
+      }
+      vm._renderProxy = handlers ? new Proxy(vm, handlers) : vm
     } else {
       vm._renderProxy = vm
     }

+ 12 - 1
test/unit/features/instance/render-proxy.spec.js

@@ -10,12 +10,23 @@ if (typeof Proxy !== 'undefined') {
     })
 
     it('should warn missing property in render fns without `with`', () => {
+      const render = function (h) {
+        return h('div', [this.a])
+      }
+      render._withStripped = true
+      new Vue({
+        render
+      }).$mount()
+      expect(`Property or method "a" is not defined`).toHaveBeenWarned()
+    })
+
+    it('should not warn for hand-written render functions', () => {
       new Vue({
         render (h) {
           return h('div', [this.a])
         }
       }).$mount()
-      expect(`Property or method "a" is not defined`).toHaveBeenWarned()
+      expect(`Property or method "a" is not defined`).not.toHaveBeenWarned()
     })
   })
 }