Skip to content

Commit facd231

Browse files
committed
Handle member expressions in v-for statements
We currently support iterating over arrays in Vue statements, like `<a v-for="item in list">`, but this support is currently limited to data at the top-level of our template data object. Add support for member expressions in v-for statements so that we can handle statements like `<a v-for="item in list.data">`. While we do that, make sure that ':key' attributes in 'v-for' directives are not written out to the output. Bug: T398011
1 parent ba6b825 commit facd231

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/Component.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,9 @@ private function handleFor( DOMNode $node, array $data ) {
204204
if ( $node->hasAttribute( 'v-for' ) ) {
205205
list( $itemName, $listName ) = explode( ' in ', $node->getAttribute( 'v-for' ) );
206206
$node->removeAttribute( 'v-for' );
207+
$node->removeAttribute( ':key' );
207208

208-
foreach ( $data[$listName] as $item ) {
209+
foreach ( $this->app->evaluateExpression( $listName, $data ) as $item ) {
209210
$newNode = $node->cloneNode( true );
210211
$node->parentNode->insertBefore( $newNode, $node );
211212
$this->handleNode( $newNode, array_merge( $data, [ $itemName => $item ] ) );

tests/php/TemplatingTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,15 @@ public function testTemplateWithForLoopAndSingleElementInArrayToIterate_Rendered
207207
$this->assertSame( '<p><a></a></p>', $result );
208208
}
209209

210+
public function testTemplateWithForLoopAndMemberExpressionForData_RenderedOnce() {
211+
$result = $this->createAndRender(
212+
'<p><a v-for="item in list.data"></a></p>',
213+
[ 'list' => [ 'data' => [ 1 ] ] ]
214+
);
215+
216+
$this->assertSame( '<p><a></a></p>', $result );
217+
}
218+
210219
public function testTemplateWithForLoopAndMultipleElementsInArrayToIterate_RenderedMultipleTimes() {
211220
$result = $this->createAndRender(
212221
'<p><a v-for="item in list"></a></p>',
@@ -225,6 +234,15 @@ public function testTemplateWithForLoopMustache_RendersCorrectValues() {
225234
$this->assertSame( '<p><a>1</a><a>2</a></p>', $result );
226235
}
227236

237+
public function testTemplateWithForLoopAndKey_DropsKeyAttributeFromOutput() {
238+
$result = $this->createAndRender(
239+
'<p><a v-for="item in list" :key="item">{{item}}</a></p>',
240+
[ 'list' => [ 1, 2 ] ]
241+
);
242+
243+
$this->assertSame( '<p><a>1</a><a>2</a></p>', $result );
244+
}
245+
228246
public function testTemplateWithAttributeBinding_ConditionIsFalse_AttributeIsNotRendered() {
229247
$result = $this->createAndRender( '<p :attr1="condition"></p>', [ 'condition' => false ] );
230248

0 commit comments

Comments
 (0)