0e96c06c72a96b1955f95ed317a5df6a2bebe3a544f1c7196fd698f7c35e877029e9cf91363a8183b3aaf5c21c353bdb28cec282c1e4b8cb94d7bbd08926c1 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /* not type checking this file because flow doesn't play well with Proxy */
  2. import config from 'core/config'
  3. import { warn, makeMap, isNative } from '../util/index'
  4. let initProxy
  5. if (process.env.NODE_ENV !== 'production') {
  6. const allowedGlobals = makeMap(
  7. 'Infinity,undefined,NaN,isFinite,isNaN,' +
  8. 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
  9. 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
  10. 'require' // for Webpack/Browserify
  11. )
  12. const warnNonPresent = (target, key) => {
  13. warn(
  14. `Property or method "${key}" is not defined on the instance but ` +
  15. 'referenced during render. Make sure that this property is reactive, ' +
  16. 'either in the data option, or for class-based components, by ' +
  17. 'initializing the property. ' +
  18. 'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
  19. target
  20. )
  21. }
  22. const warnReservedPrefix = (target, key) => {
  23. warn(
  24. `Property "${key}" must be accessed with "$data.${key}" because ` +
  25. 'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
  26. 'prevent conflicts with Vue internals. ' +
  27. 'See: https://vuejs.org/v2/api/#data',
  28. target
  29. )
  30. }
  31. const hasProxy =
  32. typeof Proxy !== 'undefined' && isNative(Proxy)
  33. if (hasProxy) {
  34. const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact')
  35. config.keyCodes = new Proxy(config.keyCodes, {
  36. set (target, key, value) {
  37. if (isBuiltInModifier(key)) {
  38. warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`)
  39. return false
  40. } else {
  41. target[key] = value
  42. return true
  43. }
  44. }
  45. })
  46. }
  47. const hasHandler = {
  48. has (target, key) {
  49. const has = key in target
  50. const isAllowed = allowedGlobals(key) ||
  51. (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data))
  52. if (!has && !isAllowed) {
  53. if (key in target.$data) warnReservedPrefix(target, key)
  54. else warnNonPresent(target, key)
  55. }
  56. return has || !isAllowed
  57. }
  58. }
  59. const getHandler = {
  60. get (target, key) {
  61. if (typeof key === 'string' && !(key in target)) {
  62. if (key in target.$data) warnReservedPrefix(target, key)
  63. else warnNonPresent(target, key)
  64. }
  65. return target[key]
  66. }
  67. }
  68. initProxy = function initProxy (vm) {
  69. if (hasProxy) {
  70. // determine which proxy handler to use
  71. const options = vm.$options
  72. const handlers = options.render && options.render._withStripped
  73. ? getHandler
  74. : hasHandler
  75. vm._renderProxy = new Proxy(vm, handlers)
  76. } else {
  77. vm._renderProxy = vm
  78. }
  79. }
  80. }
  81. export { initProxy }