fix: make sure v-if and v-for work together
This commit is contained in:
		
							parent
							
								
									3415bbd823
								
							
						
					
					
						commit
						0af0febfc2
					
				@ -54,7 +54,7 @@ export interface TransformContext extends Required<TransformOptions> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export function transform(root: RootNode, options: TransformOptions) {
 | 
					export function transform(root: RootNode, options: TransformOptions) {
 | 
				
			||||||
  const context = createTransformContext(root, options)
 | 
					  const context = createTransformContext(root, options)
 | 
				
			||||||
  traverseChildren(root, context, context.ancestors)
 | 
					  traverseChildren(root, context)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createTransformContext(
 | 
					function createTransformContext(
 | 
				
			||||||
@ -103,12 +103,11 @@ function createTransformContext(
 | 
				
			|||||||
  return context
 | 
					  return context
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function traverseChildren(
 | 
					export function traverseChildren(
 | 
				
			||||||
  parent: ParentNode,
 | 
					  parent: ParentNode,
 | 
				
			||||||
  context: TransformContext,
 | 
					  context: TransformContext
 | 
				
			||||||
  ancestors: ParentNode[]
 | 
					 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  ancestors = ancestors.concat(parent)
 | 
					  const ancestors = context.ancestors.concat(parent)
 | 
				
			||||||
  let i = 0
 | 
					  let i = 0
 | 
				
			||||||
  const nodeRemoved = () => {
 | 
					  const nodeRemoved = () => {
 | 
				
			||||||
    i--
 | 
					    i--
 | 
				
			||||||
@ -118,39 +117,35 @@ function traverseChildren(
 | 
				
			|||||||
    context.ancestors = ancestors
 | 
					    context.ancestors = ancestors
 | 
				
			||||||
    context.childIndex = i
 | 
					    context.childIndex = i
 | 
				
			||||||
    context.onNodeRemoved = nodeRemoved
 | 
					    context.onNodeRemoved = nodeRemoved
 | 
				
			||||||
    traverseNode((context.currentNode = parent.children[i]), context, ancestors)
 | 
					    traverseNode((context.currentNode = parent.children[i]), context)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function traverseNode(
 | 
					export function traverseNode(node: ChildNode, context: TransformContext) {
 | 
				
			||||||
  node: ChildNode,
 | 
					 | 
				
			||||||
  context: TransformContext,
 | 
					 | 
				
			||||||
  ancestors: ParentNode[]
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
  // apply transform plugins
 | 
					  // apply transform plugins
 | 
				
			||||||
  const { nodeTransforms } = context
 | 
					  const { nodeTransforms } = context
 | 
				
			||||||
  for (let i = 0; i < nodeTransforms.length; i++) {
 | 
					  for (let i = 0; i < nodeTransforms.length; i++) {
 | 
				
			||||||
    const plugin = nodeTransforms[i]
 | 
					    const plugin = nodeTransforms[i]
 | 
				
			||||||
    plugin(node, context)
 | 
					    plugin(node, context)
 | 
				
			||||||
    // node may have been replaced
 | 
					    if (!context.currentNode) {
 | 
				
			||||||
    node = context.currentNode || node
 | 
					      // node was removed
 | 
				
			||||||
  }
 | 
					      return
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
  if (!context.currentNode) {
 | 
					      // node may have been replaced
 | 
				
			||||||
    // node was removed
 | 
					      node = context.currentNode
 | 
				
			||||||
    return
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // further traverse downwards
 | 
					  // further traverse downwards
 | 
				
			||||||
  switch (node.type) {
 | 
					  switch (node.type) {
 | 
				
			||||||
    case NodeTypes.IF:
 | 
					    case NodeTypes.IF:
 | 
				
			||||||
      for (let i = 0; i < node.branches.length; i++) {
 | 
					      for (let i = 0; i < node.branches.length; i++) {
 | 
				
			||||||
        traverseChildren(node.branches[i], context, ancestors)
 | 
					        traverseChildren(node.branches[i], context)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      break
 | 
					      break
 | 
				
			||||||
    case NodeTypes.FOR:
 | 
					    case NodeTypes.FOR:
 | 
				
			||||||
    case NodeTypes.ELEMENT:
 | 
					    case NodeTypes.ELEMENT:
 | 
				
			||||||
      traverseChildren(node, context, ancestors)
 | 
					      traverseChildren(node, context)
 | 
				
			||||||
      break
 | 
					      break
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -169,11 +164,12 @@ export function createStructuralDirectiveTransform(
 | 
				
			|||||||
      for (let i = 0; i < props.length; i++) {
 | 
					      for (let i = 0; i < props.length; i++) {
 | 
				
			||||||
        const prop = props[i]
 | 
					        const prop = props[i]
 | 
				
			||||||
        if (prop.type === NodeTypes.DIRECTIVE && matches(prop.name)) {
 | 
					        if (prop.type === NodeTypes.DIRECTIVE && matches(prop.name)) {
 | 
				
			||||||
          fn(node, prop, context)
 | 
					          // structural directives are removed to avoid infinite recursion
 | 
				
			||||||
          // structural directives are removed after being processed
 | 
					          // also we remove them *before* applying so that it can further
 | 
				
			||||||
          // to avoid infinite recursion
 | 
					          // traverse itself in case it moves the node around
 | 
				
			||||||
          props.splice(i, 1)
 | 
					          props.splice(i, 1)
 | 
				
			||||||
          i--
 | 
					          i--
 | 
				
			||||||
 | 
					          fn(node, prop, context)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,7 @@
 | 
				
			|||||||
import { createStructuralDirectiveTransform } from '../transform'
 | 
					import {
 | 
				
			||||||
 | 
					  createStructuralDirectiveTransform,
 | 
				
			||||||
 | 
					  traverseChildren
 | 
				
			||||||
 | 
					} from '../transform'
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  NodeTypes,
 | 
					  NodeTypes,
 | 
				
			||||||
  ElementTypes,
 | 
					  ElementTypes,
 | 
				
			||||||
@ -37,6 +40,9 @@ export const transformIf = createStructuralDirectiveTransform(
 | 
				
			|||||||
            branch.children = [...comments, ...branch.children]
 | 
					            branch.children = [...comments, ...branch.children]
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          sibling.branches.push(branch)
 | 
					          sibling.branches.push(branch)
 | 
				
			||||||
 | 
					          // since the branch was removed, it will not be traversed.
 | 
				
			||||||
 | 
					          // make sure to traverse here.
 | 
				
			||||||
 | 
					          traverseChildren(branch, context)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          context.onError(
 | 
					          context.onError(
 | 
				
			||||||
            createCompilerError(
 | 
					            createCompilerError(
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user