Skip to content

Commit 4585ae3

Browse files
michalsnikarmano2
authored andcommitted
Add getComputedProperties logic & refactor order-in-components
1 parent 90fa79d commit 4585ae3

File tree

2 files changed

+114
-50
lines changed

2 files changed

+114
-50
lines changed

lib/rules/order-in-components.js

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55
'use strict'
66

7+
const utils = require('../utils')
8+
79
const defaultOrder = [
810
['name', 'delimiters', 'functional', 'model'],
911
['components', 'directives', 'filters'],
@@ -36,38 +38,6 @@ const groups = {
3638
]
3739
}
3840

39-
function isComponentFile (node, path) {
40-
const isVueFile = path.endsWith('.vue') || path.endsWith('.jsx')
41-
return isVueFile && node.declaration.type === 'ObjectExpression'
42-
}
43-
44-
function isVueComponent (node) {
45-
const callee = node.callee
46-
47-
const isFullVueComponent = node.type === 'CallExpression' &&
48-
callee.type === 'MemberExpression' &&
49-
callee.object.type === 'Identifier' &&
50-
callee.object.name === 'Vue' &&
51-
callee.property.type === 'Identifier' &&
52-
callee.property.name === 'component' &&
53-
node.arguments.length &&
54-
node.arguments.slice(-1)[0].type === 'ObjectExpression'
55-
56-
const isDestructedVueComponent = callee.type === 'Identifier' &&
57-
callee.name === 'component'
58-
59-
return isFullVueComponent || isDestructedVueComponent
60-
}
61-
62-
function isVueInstance (node) {
63-
const callee = node.callee
64-
return node.type === 'NewExpression' &&
65-
callee.type === 'Identifier' &&
66-
callee.name === 'Vue' &&
67-
node.arguments.length &&
68-
node.arguments[0].type === 'ObjectExpression'
69-
}
70-
7141
function getOrderMap (order) {
7242
const orderMap = new Map()
7343

@@ -106,28 +76,13 @@ function checkOrder (propertiesNodes, orderMap, context) {
10676
function create (context) {
10777
const options = context.options[0] || {}
10878
const order = options.order || defaultOrder
109-
const filePath = context.getFilename()
11079

11180
const extendedOrder = order.map(property => groups[property] || property)
11281
const orderMap = getOrderMap(extendedOrder)
11382

114-
return {
115-
ExportDefaultDeclaration (node) {
116-
// export default {} in .vue || .jsx
117-
if (!isComponentFile(node, filePath)) return
118-
checkOrder(node.declaration.properties, orderMap, context)
119-
},
120-
CallExpression (node) {
121-
// Vue.component('xxx', {}) || component('xxx', {})
122-
if (!isVueComponent(node)) return
123-
checkOrder(node.arguments.slice(-1)[0].properties, orderMap, context)
124-
},
125-
NewExpression (node) {
126-
// new Vue({})
127-
if (!isVueInstance(node)) return
128-
checkOrder(node.arguments[0].properties, orderMap, context)
129-
}
130-
}
83+
return utils.executeOnVueComponent(context, (properties) => {
84+
checkOrder(properties, orderMap, context)
85+
})
13186
}
13287

13388
// ------------------------------------------------------------------------------

lib/utils/index.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,5 +241,114 @@ module.exports = {
241241
assert(typeof name === 'string')
242242

243243
return VOID_ELEMENT_NAMES.has(name.toLowerCase())
244+
},
245+
246+
/**
247+
* Check whether the given node is a Vue component based
248+
* on the filename and default export type
249+
* export default {} in .vue || .jsx
250+
* @param {ASTNode} node Node to check
251+
* @param {string} path File name with extension
252+
* @returns {boolean}
253+
*/
254+
isVueComponentFile (node, path) {
255+
const isVueFile = path.endsWith('.vue') || path.endsWith('.jsx')
256+
return isVueFile &&
257+
node.type === 'ExportDefaultDeclaration' &&
258+
node.declaration.type === 'ObjectExpression'
259+
},
260+
261+
/**
262+
* Check whether given node is Vue component
263+
* Vue.component('xxx', {}) || component('xxx', {})
264+
* @param {ASTNode} node Node to check
265+
* @returns {boolean}
266+
*/
267+
isVueComponent (node) {
268+
const callee = node.callee
269+
270+
const isFullVueComponent = node.type === 'CallExpression' &&
271+
callee.type === 'MemberExpression' &&
272+
callee.object.type === 'Identifier' &&
273+
callee.object.name === 'Vue' &&
274+
callee.property.type === 'Identifier' &&
275+
callee.property.name === 'component' &&
276+
node.arguments.length &&
277+
node.arguments.slice(-1)[0].type === 'ObjectExpression'
278+
279+
const isDestructedVueComponent = callee.type === 'Identifier' &&
280+
callee.name === 'component'
281+
282+
return isFullVueComponent || isDestructedVueComponent
283+
},
284+
285+
/**
286+
* Check whether given node is new Vue instance
287+
* new Vue({})
288+
* @param {ASTNode} node Node to check
289+
* @returns {boolean}
290+
*/
291+
isVueInstance (node) {
292+
const callee = node.callee
293+
return node.type === 'NewExpression' &&
294+
callee.type === 'Identifier' &&
295+
callee.name === 'Vue' &&
296+
node.arguments.length &&
297+
node.arguments[0].type === 'ObjectExpression'
298+
},
299+
300+
executeOnVueComponent (context, cb) {
301+
const filePath = context.getFilename()
302+
const _this = this
303+
304+
return {
305+
'ExportDefaultDeclaration:exit' (node) {
306+
// export default {} in .vue || .jsx
307+
if (!_this.isVueComponentFile(node, filePath)) return
308+
cb(node.declaration.properties)
309+
},
310+
'CallExpression:exit' (node) {
311+
// Vue.component('xxx', {}) || component('xxx', {})
312+
if (!_this.isVueComponent(node)) return
313+
cb(node.arguments.slice(-1)[0].properties)
314+
},
315+
'NewExpression:exit' (node) {
316+
// new Vue({})
317+
if (!_this.isVueInstance(node)) return
318+
cb(node.arguments[0].properties)
319+
}
320+
}
321+
},
322+
323+
getComputedProperties (componentProperties) {
324+
const computedPropertiesNode = componentProperties
325+
.filter(p =>
326+
p.key.type === 'Identifier' &&
327+
p.key.name === 'computed' &&
328+
p.value.type === 'ObjectExpression'
329+
)[0]
330+
331+
if (!computedPropertiesNode) { return [] }
332+
333+
const computedProperties = computedPropertiesNode.value.properties
334+
335+
return computedProperties.map(cp => {
336+
const key = cp.key.name
337+
let value
338+
339+
if (cp.value.type === 'FunctionExpression') {
340+
value = cp.value.body
341+
} else if (cp.value.type === 'ObjectExpression') {
342+
value = cp.value.properties
343+
.filter(p =>
344+
p.key.type === 'Identifier' &&
345+
p.key.name === 'get' &&
346+
p.value.type === 'FunctionExpression'
347+
)
348+
.map(p => p.value.body)[0]
349+
}
350+
351+
return { key, value }
352+
})
244353
}
245354
}

0 commit comments

Comments
 (0)