no-side-effects-in-computed-properties.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /**
  2. * @fileoverview Don't introduce side effects in computed properties
  3. * @author Michał Sajnóg
  4. */
  5. 'use strict'
  6. const utils = require('../utils')
  7. // ------------------------------------------------------------------------------
  8. // Rule Definition
  9. // ------------------------------------------------------------------------------
  10. module.exports = {
  11. meta: {
  12. docs: {
  13. description: 'disallow side effects in computed properties',
  14. category: 'essential',
  15. url: 'https://github.com/vuejs/eslint-plugin-vue/blob/v4.7.1/docs/rules/no-side-effects-in-computed-properties.md'
  16. },
  17. fixable: null,
  18. schema: []
  19. },
  20. create (context) {
  21. const forbiddenNodes = []
  22. return Object.assign({},
  23. {
  24. // this.xxx <=|+=|-=>
  25. 'AssignmentExpression' (node) {
  26. if (node.left.type !== 'MemberExpression') return
  27. if (utils.parseMemberExpression(node.left)[0] === 'this') {
  28. forbiddenNodes.push(node)
  29. }
  30. },
  31. // this.xxx <++|-->
  32. 'UpdateExpression > MemberExpression' (node) {
  33. if (utils.parseMemberExpression(node)[0] === 'this') {
  34. forbiddenNodes.push(node)
  35. }
  36. },
  37. // this.xxx.func()
  38. 'CallExpression' (node) {
  39. const code = utils.parseMemberOrCallExpression(node)
  40. const MUTATION_REGEX = /(this.)((?!(concat|slice|map|filter)\().)[^\)]*((push|pop|shift|unshift|reverse|splice|sort|copyWithin|fill)\()/g
  41. if (MUTATION_REGEX.test(code)) {
  42. forbiddenNodes.push(node)
  43. }
  44. }
  45. },
  46. utils.executeOnVue(context, (obj) => {
  47. const computedProperties = utils.getComputedProperties(obj)
  48. computedProperties.forEach(cp => {
  49. forbiddenNodes.forEach(node => {
  50. if (
  51. cp.value &&
  52. node.loc.start.line >= cp.value.loc.start.line &&
  53. node.loc.end.line <= cp.value.loc.end.line
  54. ) {
  55. context.report({
  56. node: node,
  57. message: 'Unexpected side effect in "{{key}}" computed property.',
  58. data: { key: cp.key }
  59. })
  60. }
  61. })
  62. })
  63. })
  64. )
  65. }
  66. }