Skip to content

Commit

Permalink
Add vue/no-deprecated-destroyed-lifecycle rule (#1211)
Browse files Browse the repository at this point in the history
* Add `vue/no-deprecated-destroyed-lifecycle` rule

* Add testcases and fix bug
  • Loading branch information
ota-meshi committed Jun 26, 2020
1 parent b57a273 commit a12f2d9
Show file tree
Hide file tree
Showing 6 changed files with 524 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -42,6 +42,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
| [vue/no-arrow-functions-in-watch](./no-arrow-functions-in-watch.md) | disallow using arrow functions to define watcher | |
| [vue/no-async-in-computed-properties](./no-async-in-computed-properties.md) | disallow asynchronous actions in computed properties | |
| [vue/no-deprecated-data-object-declaration](./no-deprecated-data-object-declaration.md) | disallow using deprecated object declaration on data (in Vue.js 3.0.0+) | :wrench: |
| [vue/no-deprecated-destroyed-lifecycle](./no-deprecated-destroyed-lifecycle.md) | disallow using deprecated `destroyed` and `beforeDestroy` lifecycle hooks (in Vue.js 3.0.0+) | |
| [vue/no-deprecated-dollar-listeners-api](./no-deprecated-dollar-listeners-api.md) | disallow using deprecated `$listeners` (in Vue.js 3.0.0+) | |
| [vue/no-deprecated-dollar-scopedslots-api](./no-deprecated-dollar-scopedslots-api.md) | disallow using deprecated `$scopedSlots` (in Vue.js 3.0.0+) | :wrench: |
| [vue/no-deprecated-events-api](./no-deprecated-events-api.md) | disallow using deprecated events api (in Vue.js 3.0.0+) | |
Expand Down
43 changes: 43 additions & 0 deletions docs/rules/no-deprecated-destroyed-lifecycle.md
@@ -0,0 +1,43 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-deprecated-destroyed-lifecycle
description: disallow using deprecated `destroyed` and `beforeDestroy` lifecycle hooks (in Vue.js 3.0.0+)
---
# vue/no-deprecated-destroyed-lifecycle
> disallow using deprecated `destroyed` and `beforeDestroy` lifecycle hooks (in Vue.js 3.0.0+)
- :gear: This rule is included in all of `"plugin:vue/vue3-essential"`, `"plugin:vue/vue3-strongly-recommended"` and `"plugin:vue/vue3-recommended"`.

## :book: Rule Details

This rule reports use of deprecated `destroyed` and `beforeDestroy` lifecycle hooks. (in Vue.js 3.0.0+).

<eslint-code-block :rules="{'vue/no-deprecated-destroyed-lifecycle': ['error']}">

```vue
<script>
export default {
/* ✓ GOOD */
beforeMount () {},
mounted () {},
beforeUnmount () {},
unmounted () {},
/* ✗ BAD */
beforeDestroy () {},
destroyed () {}
}
</script>
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-deprecated-destroyed-lifecycle.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-deprecated-destroyed-lifecycle.js)
1 change: 1 addition & 0 deletions lib/configs/vue3-essential.js
Expand Up @@ -10,6 +10,7 @@ module.exports = {
'vue/no-arrow-functions-in-watch': 'error',
'vue/no-async-in-computed-properties': 'error',
'vue/no-deprecated-data-object-declaration': 'error',
'vue/no-deprecated-destroyed-lifecycle': 'error',
'vue/no-deprecated-dollar-listeners-api': 'error',
'vue/no-deprecated-dollar-scopedslots-api': 'error',
'vue/no-deprecated-events-api': 'error',
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Expand Up @@ -51,6 +51,7 @@ module.exports = {
'no-confusing-v-for-v-if': require('./rules/no-confusing-v-for-v-if'),
'no-custom-modifiers-on-v-model': require('./rules/no-custom-modifiers-on-v-model'),
'no-deprecated-data-object-declaration': require('./rules/no-deprecated-data-object-declaration'),
'no-deprecated-destroyed-lifecycle': require('./rules/no-deprecated-destroyed-lifecycle'),
'no-deprecated-dollar-listeners-api': require('./rules/no-deprecated-dollar-listeners-api'),
'no-deprecated-dollar-scopedslots-api': require('./rules/no-deprecated-dollar-scopedslots-api'),
'no-deprecated-events-api': require('./rules/no-deprecated-events-api'),
Expand Down
101 changes: 101 additions & 0 deletions lib/rules/no-deprecated-destroyed-lifecycle.js
@@ -0,0 +1,101 @@
/**
* @author Yosuke Ota
* See LICENSE file in root directory for full license.
*/
'use strict'

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const utils = require('../utils')

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = {
meta: {
type: 'problem',
docs: {
description:
'disallow using deprecated `destroyed` and `beforeDestroy` lifecycle hooks (in Vue.js 3.0.0+)',
categories: ['vue3-essential'],
url:
'https://eslint.vuejs.org/rules/no-deprecated-destroyed-lifecycle.html'
},
fixable: null,
schema: [],
messages: {
deprecatedDestroyed:
'The `destroyed` lifecycle hook is deprecated. Use `unmounted` instead.',
deprecatedBeforeDestroy:
'The `beforeDestroy` lifecycle hook is deprecated. Use `beforeUnmount` instead.',
insteadUnmounted: 'Instead, change to `unmounted`.',
insteadBeforeUnmount: 'Instead, change to `beforeUnmount`.'
}
},
/** @param {RuleContext} context */
create(context) {
return utils.executeOnVue(context, (obj) => {
const destroyed = utils.findProperty(obj, 'destroyed')

if (destroyed) {
context.report({
node: destroyed.key,
messageId: 'deprecatedDestroyed',
// I don't know if they have exactly the same function, so don't do autofix.
suggest: [
{
messageId: 'insteadUnmounted',
fix(fixer) {
return fix(fixer, destroyed, 'unmounted')
}
}
]
})
}

const beforeDestroy = utils.findProperty(obj, 'beforeDestroy')
if (beforeDestroy) {
context.report({
node: beforeDestroy.key,
messageId: 'deprecatedBeforeDestroy',
// I don't know if they have exactly the same function, so don't do autofix.
suggest: [
{
messageId: 'insteadBeforeUnmount',
fix(fixer) {
return fix(fixer, beforeDestroy, 'beforeUnmount')
}
}
]
})
}

/**
* @param {RuleFixer} fixer
* @param {Property} property
* @param {string} newName
*/
function fix(fixer, property, newName) {
if (property.computed) {
if (
property.key.type === 'Literal' ||
property.key.type === 'TemplateLiteral'
) {
return fixer.replaceTextRange(
[property.key.range[0] + 1, property.key.range[1] - 1],
newName
)
}
return null
}
if (property.shorthand) {
return fixer.insertTextBefore(property.key, `${newName}:`)
}
return fixer.replaceText(property.key, newName)
}
})
}
}

0 comments on commit a12f2d9

Please sign in to comment.