Skip to content

Commit d261cca

Browse files
committed
feat: implement v-bind-order-sensitive transformation
1 parent a37a996 commit d261cca

File tree

5 files changed

+69
-0
lines changed

5 files changed

+69
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { runTest } from '../../src/testUtils'
2+
3+
runTest(
4+
'Fix v-bind Merge Behavior',
5+
'v-bind-order-sensitive',
6+
'v-bind-object',
7+
'vue',
8+
'vue'
9+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<template>
2+
<div id='red' v-bind="{id:'blue'}"></div>
3+
</template>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<template>
2+
<div v-bind="{id:'blue'}" id='red' ></div>
3+
</template>

vue-transformations/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const transformationMap: {
1212
'v-for-template-key': require('./v-for-template-key'),
1313
'v-else-if-key': require('./v-else-if-key'),
1414
'transition-group-root': require('./transition-group-root'),
15+
'v-bind-order-sensitive': require('./v-bind-order-sensitive.spec')
1516
}
1617

1718
export default transformationMap
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Node } from 'vue-eslint-parser/ast/nodes'
2+
import * as OperationUtils from '../src/operationUtils'
3+
import type { Operation } from '../src/operationUtils'
4+
import type { VueASTTransformation } from '../src/wrapVueTransformation'
5+
import * as parser from 'vue-eslint-parser'
6+
import wrap from '../src/wrapVueTransformation'
7+
8+
export const transformAST: VueASTTransformation = (context) => {
9+
let fixOperations: Operation[] = []
10+
const { file } = context
11+
const source = file.source
12+
const toFixNodes: Node[] = findNodes(source)
13+
toFixNodes.forEach((node) => {
14+
fixOperations = fixOperations.concat(fix(node, source))
15+
})
16+
return fixOperations
17+
}
18+
19+
export default wrap(transformAST)
20+
21+
function findNodes(source: string): Node[] {
22+
const options = { sourceType: 'module' }
23+
const ast = parser.parse(source, options)
24+
let toFixNodes: Node[] = []
25+
let root: Node = <Node>ast.templateBody
26+
parser.AST.traverseNodes(root, {
27+
enterNode(node: Node) {
28+
if (
29+
node.type === 'VAttribute' &&
30+
node.directive &&
31+
node.key.name.name === 'bind' &&
32+
node.parent.attributes.length > 1
33+
) {
34+
toFixNodes.push(node)
35+
}
36+
},
37+
leaveNode(node: Node) {},
38+
})
39+
return toFixNodes
40+
}
41+
42+
function fix(node: Node, source: string): Operation[] {
43+
let fixOperations: Operation[] = []
44+
// get parent node
45+
const target: any = node!.parent;
46+
// get the value of v-bind according to the range
47+
const bindValue:string = source.slice(node.range[0], node.range[1]) + ' ';
48+
// remove node
49+
fixOperations.push(OperationUtils.remove(node));
50+
// add node to the first
51+
fixOperations.push(OperationUtils.insertTextBefore(target.attributes[0],bindValue));
52+
return fixOperations
53+
}

0 commit comments

Comments
 (0)