vue 2.6.7 → 2.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +72 -52
  2. package/dist/README.md +1 -1
  3. package/dist/vue.common.dev.js +109 -51
  4. package/dist/vue.common.prod.js +2 -2
  5. package/dist/vue.esm.browser.js +109 -51
  6. package/dist/vue.esm.browser.min.js +2 -2
  7. package/dist/vue.esm.js +109 -51
  8. package/dist/vue.js +109 -51
  9. package/dist/vue.min.js +2 -2
  10. package/dist/vue.runtime.common.dev.js +80 -38
  11. package/dist/vue.runtime.common.prod.js +2 -2
  12. package/dist/vue.runtime.esm.js +80 -38
  13. package/dist/vue.runtime.js +80 -38
  14. package/dist/vue.runtime.min.js +2 -2
  15. package/package.json +4 -4
  16. package/src/compiler/codegen/events.js +1 -1
  17. package/src/compiler/codegen/index.js +1 -1
  18. package/src/compiler/error-detector.js +18 -3
  19. package/src/compiler/parser/html-parser.js +5 -5
  20. package/src/compiler/parser/index.js +7 -6
  21. package/src/core/instance/proxy.js +1 -1
  22. package/src/core/instance/render-helpers/bind-dynamic-keys.js +1 -1
  23. package/src/core/instance/render-helpers/bind-object-props.js +5 -3
  24. package/src/core/instance/render.js +1 -1
  25. package/src/core/observer/scheduler.js +17 -6
  26. package/src/core/util/env.js +1 -2
  27. package/src/core/util/error.js +4 -3
  28. package/src/core/util/lang.js +2 -2
  29. package/src/core/util/next-tick.js +1 -1
  30. package/src/core/util/options.js +2 -2
  31. package/src/core/vdom/create-element.js +6 -0
  32. package/src/core/vdom/helpers/normalize-scoped-slots.js +9 -4
  33. package/src/core/vdom/helpers/resolve-async-component.js +25 -8
  34. package/src/core/vdom/patch.js +4 -4
  35. package/src/platforms/web/compiler/modules/model.js +1 -1
  36. package/src/platforms/web/runtime/modules/dom-props.js +2 -1
  37. package/src/platforms/web/runtime/modules/events.js +4 -2
  38. package/src/platforms/web/runtime/modules/transition.js +1 -1
  39. package/src/server/template-renderer/create-async-file-mapper.js +2 -2
  40. package/src/server/write.js +1 -1
  41. package/types/index.d.ts +1 -2
  42. package/types/options.d.ts +3 -3
  43. package/types/umd.d.ts +48 -0
  44. package/types/vnode.d.ts +6 -2
  45. package/types/vue.d.ts +3 -3
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vue.js v2.6.7
2
+ * Vue.js v2.6.11
3
3
  * (c) 2014-2019 Evan You
4
4
  * Released under the MIT License.
5
5
  */
@@ -477,7 +477,7 @@ var config = ({
477
477
  * using https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname
478
478
  * skipping \u10000-\uEFFFF due to it freezing up PhantomJS
479
479
  */
480
- var unicodeLetters = 'a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD';
480
+ var unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/;
481
481
 
482
482
  /**
483
483
  * Check if a string starts with $ or _
@@ -502,7 +502,7 @@ function def (obj, key, val, enumerable) {
502
502
  /**
503
503
  * Parse simple path.
504
504
  */
505
- var bailRE = new RegExp(("[^" + unicodeLetters + ".$_\\d]"));
505
+ var bailRE = new RegExp(("[^" + (unicodeRegExp.source) + ".$_\\d]"));
506
506
  function parsePath (path) {
507
507
  if (bailRE.test(path)) {
508
508
  return
@@ -1406,7 +1406,7 @@ function checkComponents (options) {
1406
1406
  }
1407
1407
 
1408
1408
  function validateComponentName (name) {
1409
- if (!new RegExp(("^[a-zA-Z][\\-\\.0-9_" + unicodeLetters + "]*$")).test(name)) {
1409
+ if (!new RegExp(("^[a-zA-Z][\\-\\.0-9_" + (unicodeRegExp.source) + "]*$")).test(name)) {
1410
1410
  warn(
1411
1411
  'Invalid component name: "' + name + '". Component names ' +
1412
1412
  'should conform to valid custom element name in html5 specification.'
@@ -1857,10 +1857,11 @@ function invokeWithErrorHandling (
1857
1857
  var res;
1858
1858
  try {
1859
1859
  res = args ? handler.apply(context, args) : handler.call(context);
1860
- if (res && !res._isVue && isPromise(res)) {
1860
+ if (res && !res._isVue && isPromise(res) && !res._handled) {
1861
+ res.catch(function (e) { return handleError(e, vm, info + " (Promise/async)"); });
1861
1862
  // issue #9511
1862
- // reassign to res to avoid catch triggering multiple times when nested calls
1863
- res = res.catch(function (e) { return handleError(e, vm, info + " (Promise/async)"); });
1863
+ // avoid catch triggering multiple times when nested calls
1864
+ res._handled = true;
1864
1865
  }
1865
1866
  } catch (e) {
1866
1867
  handleError(e, vm, info);
@@ -1964,7 +1965,7 @@ if (typeof Promise !== 'undefined' && isNative(Promise)) {
1964
1965
  isUsingMicroTask = true;
1965
1966
  } else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
1966
1967
  // Fallback to setImmediate.
1967
- // Techinically it leverages the (macro) task queue,
1968
+ // Technically it leverages the (macro) task queue,
1968
1969
  // but it is still a better choice than setTimeout.
1969
1970
  timerFunc = function () {
1970
1971
  setImmediate(flushCallbacks);
@@ -2053,7 +2054,7 @@ var initProxy;
2053
2054
  warn(
2054
2055
  "Property \"" + key + "\" must be accessed with \"$data." + key + "\" because " +
2055
2056
  'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
2056
- 'prevent conflicts with Vue internals' +
2057
+ 'prevent conflicts with Vue internals. ' +
2057
2058
  'See: https://vuejs.org/v2/api/#data',
2058
2059
  target
2059
2060
  );
@@ -2543,7 +2544,8 @@ function normalizeScopedSlots (
2543
2544
  prevSlots
2544
2545
  ) {
2545
2546
  var res;
2546
- var isStable = slots ? !!slots.$stable : true;
2547
+ var hasNormalSlots = Object.keys(normalSlots).length > 0;
2548
+ var isStable = slots ? !!slots.$stable : !hasNormalSlots;
2547
2549
  var key = slots && slots.$key;
2548
2550
  if (!slots) {
2549
2551
  res = {};
@@ -2555,7 +2557,8 @@ function normalizeScopedSlots (
2555
2557
  prevSlots &&
2556
2558
  prevSlots !== emptyObject &&
2557
2559
  key === prevSlots.$key &&
2558
- Object.keys(normalSlots).length === 0
2560
+ !hasNormalSlots &&
2561
+ !prevSlots.$hasNormal
2559
2562
  ) {
2560
2563
  // fast path 2: stable scoped slots w/ no normal slots to proxy,
2561
2564
  // only need to normalize once
@@ -2581,6 +2584,7 @@ function normalizeScopedSlots (
2581
2584
  }
2582
2585
  def(res, '$stable', isStable);
2583
2586
  def(res, '$key', key);
2587
+ def(res, '$hasNormal', hasNormalSlots);
2584
2588
  return res
2585
2589
  }
2586
2590
 
@@ -2590,8 +2594,10 @@ function normalizeScopedSlot(normalSlots, key, fn) {
2590
2594
  res = res && typeof res === 'object' && !Array.isArray(res)
2591
2595
  ? [res] // single vnode
2592
2596
  : normalizeChildren(res);
2593
- return res && res.length === 0
2594
- ? undefined
2597
+ return res && (
2598
+ res.length === 0 ||
2599
+ (res.length === 1 && res[0].isComment) // #9658
2600
+ ) ? undefined
2595
2601
  : res
2596
2602
  };
2597
2603
  // this is a slot using the new v-slot syntax without scope. although it is
@@ -2771,12 +2777,13 @@ function bindObjectProps (
2771
2777
  : data.attrs || (data.attrs = {});
2772
2778
  }
2773
2779
  var camelizedKey = camelize(key);
2774
- if (!(key in hash) && !(camelizedKey in hash)) {
2780
+ var hyphenatedKey = hyphenate(key);
2781
+ if (!(camelizedKey in hash) && !(hyphenatedKey in hash)) {
2775
2782
  hash[key] = value[key];
2776
2783
 
2777
2784
  if (isSync) {
2778
2785
  var on = data.on || (data.on = {});
2779
- on[("update:" + camelizedKey)] = function ($event) {
2786
+ on[("update:" + key)] = function ($event) {
2780
2787
  value[key] = $event;
2781
2788
  };
2782
2789
  }
@@ -2907,7 +2914,7 @@ function bindDynamicKeys (baseObj, values) {
2907
2914
  if (typeof key === 'string' && key) {
2908
2915
  baseObj[values[i]] = values[i + 1];
2909
2916
  } else if (key !== '' && key !== null) {
2910
- // null is a speical value for explicitly removing a binding
2917
+ // null is a special value for explicitly removing a binding
2911
2918
  warn(
2912
2919
  ("Invalid value for dynamic directive argument (expected string or null): " + key),
2913
2920
  this
@@ -3402,6 +3409,12 @@ function _createElement (
3402
3409
  ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag);
3403
3410
  if (config.isReservedTag(tag)) {
3404
3411
  // platform built-in elements
3412
+ if (isDef(data) && isDef(data.nativeOn)) {
3413
+ warn(
3414
+ ("The .native modifier for v-on is only valid on components but it was used on <" + tag + ">."),
3415
+ context
3416
+ );
3417
+ }
3405
3418
  vnode = new VNode(
3406
3419
  config.parsePlatformTagName(tag), data, children,
3407
3420
  undefined, undefined, context
@@ -3527,7 +3540,7 @@ function renderMixin (Vue) {
3527
3540
  // render self
3528
3541
  var vnode;
3529
3542
  try {
3530
- // There's no need to maintain a stack becaues all render fns are called
3543
+ // There's no need to maintain a stack because all render fns are called
3531
3544
  // separately from one another. Nested component's render fns are called
3532
3545
  // when parent component is patched.
3533
3546
  currentRenderingInstance = vm;
@@ -3610,17 +3623,23 @@ function resolveAsyncComponent (
3610
3623
  return factory.resolved
3611
3624
  }
3612
3625
 
3626
+ var owner = currentRenderingInstance;
3627
+ if (owner && isDef(factory.owners) && factory.owners.indexOf(owner) === -1) {
3628
+ // already pending
3629
+ factory.owners.push(owner);
3630
+ }
3631
+
3613
3632
  if (isTrue(factory.loading) && isDef(factory.loadingComp)) {
3614
3633
  return factory.loadingComp
3615
3634
  }
3616
3635
 
3617
- var owner = currentRenderingInstance;
3618
- if (isDef(factory.owners)) {
3619
- // already pending
3620
- factory.owners.push(owner);
3621
- } else {
3636
+ if (owner && !isDef(factory.owners)) {
3622
3637
  var owners = factory.owners = [owner];
3623
3638
  var sync = true;
3639
+ var timerLoading = null;
3640
+ var timerTimeout = null
3641
+
3642
+ ;(owner).$on('hook:destroyed', function () { return remove(owners, owner); });
3624
3643
 
3625
3644
  var forceRender = function (renderCompleted) {
3626
3645
  for (var i = 0, l = owners.length; i < l; i++) {
@@ -3629,6 +3648,14 @@ function resolveAsyncComponent (
3629
3648
 
3630
3649
  if (renderCompleted) {
3631
3650
  owners.length = 0;
3651
+ if (timerLoading !== null) {
3652
+ clearTimeout(timerLoading);
3653
+ timerLoading = null;
3654
+ }
3655
+ if (timerTimeout !== null) {
3656
+ clearTimeout(timerTimeout);
3657
+ timerTimeout = null;
3658
+ }
3632
3659
  }
3633
3660
  };
3634
3661
 
@@ -3675,7 +3702,8 @@ function resolveAsyncComponent (
3675
3702
  if (res.delay === 0) {
3676
3703
  factory.loading = true;
3677
3704
  } else {
3678
- setTimeout(function () {
3705
+ timerLoading = setTimeout(function () {
3706
+ timerLoading = null;
3679
3707
  if (isUndef(factory.resolved) && isUndef(factory.error)) {
3680
3708
  factory.loading = true;
3681
3709
  forceRender(false);
@@ -3685,7 +3713,8 @@ function resolveAsyncComponent (
3685
3713
  }
3686
3714
 
3687
3715
  if (isDef(res.timeout)) {
3688
- setTimeout(function () {
3716
+ timerTimeout = setTimeout(function () {
3717
+ timerTimeout = null;
3689
3718
  if (isUndef(factory.resolved)) {
3690
3719
  reject(
3691
3720
  "timeout (" + (res.timeout) + "ms)"
@@ -4231,11 +4260,21 @@ var getNow = Date.now;
4231
4260
  // timestamp can either be hi-res (relative to page load) or low-res
4232
4261
  // (relative to UNIX epoch), so in order to compare time we have to use the
4233
4262
  // same timestamp type when saving the flush timestamp.
4234
- if (inBrowser && getNow() > document.createEvent('Event').timeStamp) {
4235
- // if the low-res timestamp which is bigger than the event timestamp
4236
- // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
4237
- // and we need to use the hi-res version for event listeners as well.
4238
- getNow = function () { return performance.now(); };
4263
+ // All IE versions use low-res event timestamps, and have problematic clock
4264
+ // implementations (#9632)
4265
+ if (inBrowser && !isIE) {
4266
+ var performance = window.performance;
4267
+ if (
4268
+ performance &&
4269
+ typeof performance.now === 'function' &&
4270
+ getNow() > document.createEvent('Event').timeStamp
4271
+ ) {
4272
+ // if the event timestamp, although evaluated AFTER the Date.now(), is
4273
+ // smaller than it, it means the event is using a hi-res timestamp,
4274
+ // and we need to use the hi-res version for event listener timestamps as
4275
+ // well.
4276
+ getNow = function () { return performance.now(); };
4277
+ }
4239
4278
  }
4240
4279
 
4241
4280
  /**
@@ -5400,7 +5439,7 @@ Object.defineProperty(Vue, 'FunctionalRenderContext', {
5400
5439
  value: FunctionalRenderContext
5401
5440
  });
5402
5441
 
5403
- Vue.version = '2.6.7';
5442
+ Vue.version = '2.6.11';
5404
5443
 
5405
5444
  /* */
5406
5445
 
@@ -6073,7 +6112,7 @@ function createPatchFunction (backend) {
6073
6112
  }
6074
6113
  }
6075
6114
 
6076
- function removeVnodes (parentElm, vnodes, startIdx, endIdx) {
6115
+ function removeVnodes (vnodes, startIdx, endIdx) {
6077
6116
  for (; startIdx <= endIdx; ++startIdx) {
6078
6117
  var ch = vnodes[startIdx];
6079
6118
  if (isDef(ch)) {
@@ -6184,7 +6223,7 @@ function createPatchFunction (backend) {
6184
6223
  refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm;
6185
6224
  addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
6186
6225
  } else if (newStartIdx > newEndIdx) {
6187
- removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
6226
+ removeVnodes(oldCh, oldStartIdx, oldEndIdx);
6188
6227
  }
6189
6228
  }
6190
6229
 
@@ -6276,7 +6315,7 @@ function createPatchFunction (backend) {
6276
6315
  if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); }
6277
6316
  addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
6278
6317
  } else if (isDef(oldCh)) {
6279
- removeVnodes(elm, oldCh, 0, oldCh.length - 1);
6318
+ removeVnodes(oldCh, 0, oldCh.length - 1);
6280
6319
  } else if (isDef(oldVnode.text)) {
6281
6320
  nodeOps.setTextContent(elm, '');
6282
6321
  }
@@ -6505,7 +6544,7 @@ function createPatchFunction (backend) {
6505
6544
 
6506
6545
  // destroy old node
6507
6546
  if (isDef(parentElm)) {
6508
- removeVnodes(parentElm, [oldVnode], 0, 0);
6547
+ removeVnodes([oldVnode], 0, 0);
6509
6548
  } else if (isDef(oldVnode.tag)) {
6510
6549
  invokeDestroyHook(oldVnode);
6511
6550
  }
@@ -7492,8 +7531,10 @@ function add$1 (
7492
7531
  e.target === e.currentTarget ||
7493
7532
  // event is fired after handler attachment
7494
7533
  e.timeStamp >= attachedTimestamp ||
7495
- // #9462 bail for iOS 9 bug: event.timeStamp is 0 after history.pushState
7496
- e.timeStamp === 0 ||
7534
+ // bail for environments that have buggy event.timeStamp implementations
7535
+ // #9462 iOS 9 bug: event.timeStamp is 0 after history.pushState
7536
+ // #9681 QtWebEngine event.timeStamp is negative value
7537
+ e.timeStamp <= 0 ||
7497
7538
  // #9448 bail if event is fired in another document in a multi-page
7498
7539
  // electron/nw.js app, since event.timeStamp will be using a different
7499
7540
  // starting reference
@@ -7560,10 +7601,11 @@ function updateDOMProps (oldVnode, vnode) {
7560
7601
  }
7561
7602
 
7562
7603
  for (key in oldProps) {
7563
- if (isUndef(props[key])) {
7604
+ if (!(key in props)) {
7564
7605
  elm[key] = '';
7565
7606
  }
7566
7607
  }
7608
+
7567
7609
  for (key in props) {
7568
7610
  cur = props[key];
7569
7611
  // ignore children if the node has textContent or innerHTML,
@@ -8111,8 +8153,8 @@ function enter (vnode, toggleDisplay) {
8111
8153
  var context = activeInstance;
8112
8154
  var transitionNode = activeInstance.$vnode;
8113
8155
  while (transitionNode && transitionNode.parent) {
8114
- transitionNode = transitionNode.parent;
8115
8156
  context = transitionNode.context;
8157
+ transitionNode = transitionNode.parent;
8116
8158
  }
8117
8159
 
8118
8160
  var isAppear = !context._isMounted || !vnode.isRootInsert;
@@ -9202,13 +9244,13 @@ var isNonPhrasingTag = makeMap(
9202
9244
  // Regular Expressions for parsing tags and attributes
9203
9245
  var attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
9204
9246
  var dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;
9205
- var ncname = "[a-zA-Z_][\\-\\.0-9_a-zA-Z" + unicodeLetters + "]*";
9247
+ var ncname = "[a-zA-Z_][\\-\\.0-9_a-zA-Z" + (unicodeRegExp.source) + "]*";
9206
9248
  var qnameCapture = "((?:" + ncname + "\\:)?" + ncname + ")";
9207
9249
  var startTagOpen = new RegExp(("^<" + qnameCapture));
9208
9250
  var startTagClose = /^\s*(\/?)>/;
9209
9251
  var endTag = new RegExp(("^<\\/" + qnameCapture + "[^>]*>"));
9210
9252
  var doctype = /^<!DOCTYPE [^>]+>/i;
9211
- // #7298: escape - to avoid being pased as HTML comment when inlined in page
9253
+ // #7298: escape - to avoid being passed as HTML comment when inlined in page
9212
9254
  var comment = /^<!\--/;
9213
9255
  var conditionalComment = /^<!\[/;
9214
9256
 
@@ -9464,7 +9506,7 @@ function parseHTML (html, options) {
9464
9506
  ) {
9465
9507
  options.warn(
9466
9508
  ("tag <" + (stack[i].tag) + "> has no matching end tag."),
9467
- { start: stack[i].start }
9509
+ { start: stack[i].start, end: stack[i].end }
9468
9510
  );
9469
9511
  }
9470
9512
  if (options.end) {
@@ -9493,7 +9535,7 @@ function parseHTML (html, options) {
9493
9535
  /* */
9494
9536
 
9495
9537
  var onRE = /^@|^v-on:/;
9496
- var dirRE = /^v-|^@|^:/;
9538
+ var dirRE = /^v-|^@|^:|^#/;
9497
9539
  var forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
9498
9540
  var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
9499
9541
  var stripParensRE = /^\(|\)$/g;
@@ -9501,7 +9543,7 @@ var dynamicArgRE = /^\[.*\]$/;
9501
9543
 
9502
9544
  var argRE = /:(.*)$/;
9503
9545
  var bindRE = /^:|^\.|^v-bind:/;
9504
- var modifierRE = /\.[^.]+/g;
9546
+ var modifierRE = /\.[^.\]]+(?=[^\]]*$)/g;
9505
9547
 
9506
9548
  var slotRE = /^v-slot(:|$)|^#/;
9507
9549
 
@@ -9678,7 +9720,7 @@ function parse (
9678
9720
  shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
9679
9721
  shouldKeepComment: options.comments,
9680
9722
  outputSourceRange: options.outputSourceRange,
9681
- start: function start (tag, attrs, unary, start$1) {
9723
+ start: function start (tag, attrs, unary, start$1, end) {
9682
9724
  // check namespace.
9683
9725
  // inherit parent ns if there is one
9684
9726
  var ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag);
@@ -9697,6 +9739,7 @@ function parse (
9697
9739
  {
9698
9740
  if (options.outputSourceRange) {
9699
9741
  element.start = start$1;
9742
+ element.end = end;
9700
9743
  element.rawAttrsMap = element.attrsList.reduce(function (cumulated, attr) {
9701
9744
  cumulated[attr.name] = attr;
9702
9745
  return cumulated
@@ -9818,7 +9861,7 @@ function parse (
9818
9861
  text = preserveWhitespace ? ' ' : '';
9819
9862
  }
9820
9863
  if (text) {
9821
- if (whitespaceOption === 'condense') {
9864
+ if (!inPre && whitespaceOption === 'condense') {
9822
9865
  // condense consecutive whitespaces into single space
9823
9866
  text = text.replace(whitespaceRE$1, ' ');
9824
9867
  }
@@ -10116,7 +10159,7 @@ function processSlotContent (el) {
10116
10159
  if (el.parent && !maybeComponent(el.parent)) {
10117
10160
  warn$2(
10118
10161
  "<template v-slot> can only appear at the root level inside " +
10119
- "the receiving the component",
10162
+ "the receiving component",
10120
10163
  el
10121
10164
  );
10122
10165
  }
@@ -10679,7 +10722,7 @@ function isDirectChildOfTemplateFor (node) {
10679
10722
 
10680
10723
  /* */
10681
10724
 
10682
- var fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/;
10725
+ var fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function(?:\s+[\w$]+)?\s*\(/;
10683
10726
  var fnInvokeRE = /\([^)]*?\);*$/;
10684
10727
  var simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/;
10685
10728
 
@@ -11181,7 +11224,7 @@ function genScopedSlots (
11181
11224
  // components with only scoped slots to skip forced updates from parent.
11182
11225
  // but in some cases we have to bail-out of this optimization
11183
11226
  // for example if the slot contains dynamic names, has v-if or v-for on them...
11184
- var needsForceUpdate = Object.keys(slots).some(function (key) {
11227
+ var needsForceUpdate = el.for || Object.keys(slots).some(function (key) {
11185
11228
  var slot = slots[key];
11186
11229
  return (
11187
11230
  slot.slotTargetDynamic ||
@@ -11448,6 +11491,8 @@ function checkNode (node, warn) {
11448
11491
  var range = node.rawAttrsMap[name];
11449
11492
  if (name === 'v-for') {
11450
11493
  checkFor(node, ("v-for=\"" + value + "\""), warn, range);
11494
+ } else if (name === 'v-slot' || name[0] === '#') {
11495
+ checkFunctionParameterExpression(value, (name + "=\"" + value + "\""), warn, range);
11451
11496
  } else if (onRE.test(name)) {
11452
11497
  checkEvent(value, (name + "=\"" + value + "\""), warn, range);
11453
11498
  } else {
@@ -11467,9 +11512,9 @@ function checkNode (node, warn) {
11467
11512
  }
11468
11513
 
11469
11514
  function checkEvent (exp, text, warn, range) {
11470
- var stipped = exp.replace(stripStringRE, '');
11471
- var keywordMatch = stipped.match(unaryOperatorsRE);
11472
- if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') {
11515
+ var stripped = exp.replace(stripStringRE, '');
11516
+ var keywordMatch = stripped.match(unaryOperatorsRE);
11517
+ if (keywordMatch && stripped.charAt(keywordMatch.index - 1) !== '$') {
11473
11518
  warn(
11474
11519
  "avoid using JavaScript unary operator as property name: " +
11475
11520
  "\"" + (keywordMatch[0]) + "\" in expression " + (text.trim()),
@@ -11524,6 +11569,19 @@ function checkExpression (exp, text, warn, range) {
11524
11569
  }
11525
11570
  }
11526
11571
 
11572
+ function checkFunctionParameterExpression (exp, text, warn, range) {
11573
+ try {
11574
+ new Function(exp, '');
11575
+ } catch (e) {
11576
+ warn(
11577
+ "invalid function parameter expression: " + (e.message) + " in\n\n" +
11578
+ " " + exp + "\n\n" +
11579
+ " Raw expression: " + (text.trim()) + "\n",
11580
+ range
11581
+ );
11582
+ }
11583
+ }
11584
+
11527
11585
  /* */
11528
11586
 
11529
11587
  var range = 2;