slot-scope-attribute.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /**
  2. * @author Yosuke Ota
  3. * See LICENSE file in root directory for full license.
  4. */
  5. 'use strict'
  6. module.exports = {
  7. deprecated: '2.6.0',
  8. supported: '2.5.0',
  9. createTemplateBodyVisitor (context, { fixToUpgrade } = {}) {
  10. const sourceCode = context.getSourceCode()
  11. /**
  12. * Checks whether the given node can convert to the `v-slot`.
  13. * @param {VStartTag} startTag node of `<element v-slot ... >`
  14. * @returns {boolean} `true` if the given node can convert to the `v-slot`
  15. */
  16. function canConvertToVSlot (startTag) {
  17. if (startTag.parent.name !== 'template') {
  18. return false
  19. }
  20. const slotAttr = startTag.attributes
  21. .find(attr => attr.directive === false && attr.key.name === 'slot')
  22. if (slotAttr) {
  23. // if the element have `slot` it can not be converted.
  24. // Conversion of `slot` is done with `vue/no-deprecated-slot-attribute`.
  25. return false
  26. }
  27. const vBindSlotAttr = startTag.attributes
  28. .find(attr =>
  29. attr.directive === true &&
  30. attr.key.name.name === 'bind' &&
  31. attr.key.argument &&
  32. attr.key.argument.name === 'slot')
  33. if (vBindSlotAttr) {
  34. // if the element have `v-bind:slot` it can not be converted.
  35. // Conversion of `v-bind:slot` is done with `vue/no-deprecated-slot-attribute`.
  36. return false
  37. }
  38. return true
  39. }
  40. /**
  41. * Convert to `v-slot`.
  42. * @param {object} fixer fixer
  43. * @param {VAttribute | null} scopeAttr node of `slot-scope`
  44. * @returns {*} fix data
  45. */
  46. function fixSlotScopeToVSlot (fixer, scopeAttr) {
  47. const scopeValue = scopeAttr && scopeAttr.value
  48. ? `=${sourceCode.getText(scopeAttr.value)}`
  49. : ''
  50. const replaceText = `v-slot${scopeValue}`
  51. return fixer.replaceText(scopeAttr, replaceText)
  52. }
  53. /**
  54. * Reports `slot-scope` node
  55. * @param {VAttribute} scopeAttr node of `slot-scope`
  56. * @returns {void}
  57. */
  58. function reportSlotScope (scopeAttr) {
  59. context.report({
  60. node: scopeAttr.key,
  61. messageId: 'forbiddenSlotScopeAttribute',
  62. fix: fixToUpgrade
  63. // fix to use `v-slot`
  64. ? (fixer) => {
  65. const startTag = scopeAttr.parent
  66. if (!canConvertToVSlot(startTag)) {
  67. return null
  68. }
  69. return fixSlotScopeToVSlot(fixer, scopeAttr)
  70. }
  71. : null
  72. })
  73. }
  74. return {
  75. "VAttribute[directive=true][key.name.name='slot-scope']": reportSlotScope
  76. }
  77. }
  78. }