no-this-in-before-route-enter.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /**
  2. * @fileoverview Don't use this in a beforeRouteEnter method
  3. * @author Przemyslaw Jan Beigert
  4. */
  5. 'use strict'
  6. // ------------------------------------------------------------------------------
  7. // Requirements
  8. // ------------------------------------------------------------------------------
  9. const utils = require('../utils')
  10. // ------------------------------------------------------------------------------
  11. // Rule Definition
  12. // ------------------------------------------------------------------------------
  13. module.exports = {
  14. meta: {
  15. type: 'problem',
  16. docs: {
  17. description: 'disallow `this` usage in a `beforeRouteEnter` method',
  18. categories: null,
  19. url: 'https://eslint.vuejs.org/rules/no-this-in-before-route-enter.html'
  20. },
  21. fixable: null,
  22. schema: [],
  23. messages: {
  24. disallow:
  25. "'beforeRouteEnter' does NOT have access to `this` component instance. https://router.vuejs.org/guide/advanced/navigation-guards.html#in-component-guards."
  26. }
  27. },
  28. /** @param {RuleContext} context */
  29. create(context) {
  30. /**
  31. * @typedef {object} ScopeStack
  32. * @property {ScopeStack | null} upper
  33. * @property {FunctionExpression | FunctionDeclaration} node
  34. * @property {boolean} beforeRouteEnter
  35. */
  36. /** @type {Set<FunctionExpression>} */
  37. const beforeRouteEnterFunctions = new Set()
  38. /** @type {ScopeStack | null} */
  39. let scopeStack = null
  40. /**
  41. * @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
  42. */
  43. function onFunctionEnter(node) {
  44. if (node.type === 'ArrowFunctionExpression') {
  45. return
  46. }
  47. scopeStack = {
  48. upper: scopeStack,
  49. node,
  50. beforeRouteEnter: beforeRouteEnterFunctions.has(
  51. /** @type {never} */ (node)
  52. )
  53. }
  54. }
  55. /**
  56. * @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
  57. */
  58. function onFunctionExit(node) {
  59. if (scopeStack && scopeStack.node === node) {
  60. scopeStack = scopeStack.upper
  61. }
  62. }
  63. return utils.defineVueVisitor(context, {
  64. onVueObjectEnter(node) {
  65. const beforeRouteEnter = utils.findProperty(node, 'beforeRouteEnter')
  66. if (
  67. beforeRouteEnter &&
  68. beforeRouteEnter.value.type === 'FunctionExpression'
  69. ) {
  70. beforeRouteEnterFunctions.add(beforeRouteEnter.value)
  71. }
  72. },
  73. ':function': onFunctionEnter,
  74. ':function:exit': onFunctionExit,
  75. ThisExpression(node) {
  76. if (scopeStack && scopeStack.beforeRouteEnter) {
  77. context.report({
  78. node,
  79. messageId: 'disallow'
  80. })
  81. }
  82. }
  83. })
  84. }
  85. }