【问题标题】:nested v-for loop not rendering嵌套的 v-for 循环不渲染
【发布时间】:2021-12-15 09:34:50
【问题描述】:

我正在尝试以类似行的方式显示一个充满订单的表格和相应的订单详细信息。但是,我遇到了一个难题。有高手吗?我已经尝试了各种方法来解决这个问题,但我被困住了。有人提到也许使用“计算”​​属性可以解决问题,但我无法让它工作>=/。一点帮助,也许是很多帮助,将不胜感激!

<div id="MyOrdersApp" class="table-responsive">
    <table class="table table-striped table-bordered table-condensed">
        <thead>
            <tr style="color:black;font-size:2em;">
                <th style="text-align:center;">Order Id</th>
                <th style="text-align:center;">ProductIdsAndQuantity</th>
                <th style="text-align:center;">Total Cost</th>
                <th style="text-align:center;">Order Status</th>
                <th style="text-align:center;">Shipment Tracking URL</th>
                <th style="text-align:center;">Created Date</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(order, i) in parsedOrders" style="background-color:snow;text-align:center;" class="align-content-center;">
                <td>{{order.OrderId}}</td>
                <td>
                    <ul>
                        <li v-if="order.CartLineItems != null" v-for="item in order.CartLineItems;" :key="uniqueKey">
                            <img :src="item.ProductImageUrl" />
                            <span>{{item.ProductName}} &nbsp;|&nbsp;</span>
                            <span>Quantity: {{item.Quantity}} &nbsp;|&nbsp;</span>
                        </li>
                    </ul>
                </td>
                <td style="color:black;font-size:1.5em;font-weight:bold;">{{order.TotalRevenue | currency }}</td>
                <td>{{order.OrderStatus}}</td>
                <td>{{order.ShipmentTrackingURL}}</td>
                <td>{{order.CreatedDate | formatDate }}</td>
            </tr>
        </tbody>
    </table>
</div>
<script>
        var MyOrdersApp = new Vue({
            el: '#MyOrdersApp',
            data: {
                parsedOrders: [],
                theOrders: [],
                uniqueKey: 0
            },
            computed: {
                cartLineItems: function () {
                    return this.parsedOrders[0].CartLineItems;
                }
            },
            methods: {
                getMyOrders: function () {
                    var scope = this;
                    this.$http.get("https://" + location.host + "/Home/GetMyOrders").then(resp => {
                        if (resp.status == 200) {
                            this.theOrders = resp.body;
                            scope.setCartLineItems();
                        }
                    });
                },
                setCartLineItems: function () {
                    var scope = this;
                    var cartLineItems = [];
                    var cartDict = {};

                    for (var i = 0; i < this.theOrders.length; i++) {
                        cartDict = {};
                        cartLineItems = [];

                        cartDict = JSON.parse(this.theOrders[i].ProductIdsAndQuantity).CartLineItems;

                        for (var key in cartDict) {
                            var lineItem = JSON.parse(cartDict[key]);
                            cartLineItems.push(lineItem);
                        }
                        //this.allorders[i].CartLineItems = cartLineItems;
                        //scope.$set(this.allorders[i], 'CartLineItems', cartLineItems);
                        //this.theOrders[i].CartLineItems = cartLineItems;
                        scope.$set(this.theOrders[i], 'CartLineItems', cartLineItems);
                    }

                    this.parsedOrders = this.theOrders;

                    console.log("~~ Parsed Cart! ~~ ");
                    console.log(this.parsedOrders);
                    console.log(this.parsedOrders[1].CartLineItems);
                }
            },
            mounted: function () {
                var scope = this;
                this.getMyOrders();
                setTimeout(x => { scope.$forceUpdate(); scope.uniqueKey++; }, 1000);
            }
        });
</script>

我应该如何修改它以正确显示“CartLineItems”中的值??

顺便说一句,parsedOrders 看起来像这样:

如果我注释掉内部 v-for,其他列显示正常,表格如下所示:

更多背景知识...当我通过 $http 调用获取订单并且服务器返回 JSON 数组时,需要将 ProductIdsAndQuantity 属性解析为 JSON 对象,然后将其设置为订单中的自己的属性题。这里棘手的部分是 Vue 组件似乎没有对订单对象数组数据的变化做出反应。因此,需要 parsedOrders 属性和/或使用 scope.$forceUpdate();或 scope.uniqueKey++;。这些是针对 Vue 组件无法重新渲染的问题提出的解决方案。但是,这些解决方案不起作用。所以我一直在挠头......

【问题讨论】:

  • 您目前看到的错误是什么?
  • 对了,能不能把parsedOrders里面的内容也加一下?
  • @Amaarrockz 感谢您的回复。使用 F12 打开开发人员工具时,我没有看到任何错误。它只是不呈现信息客户端。
  • @Amaarrockz 是的,等一下
  • 你能补充一下parsedOrders里面的内容吗?

标签: vue.js vue-component


【解决方案1】:

您不能在导致问题的同一语句中同时使用 v-for 和 v-if。所以在这种情况下尝试使用计算

<tbody>
            <tr v-for="(order, i) in parsedOrders" style="background-color:snow;text-align:center;" class="align-content-center;">
                <td>{{order.OrderId}}</td>
                <td>
                    <ul>
                        <li v-for="(item, index) in getCartLineItems(order)" :key="index">
                            <img :src="item.ProductImageUrl" />
                            <span>{{item.ProductName}} &nbsp;|&nbsp;</span>
                            <span>Quantity: {{item.Quantity}} &nbsp;|&nbsp;</span>
                        </li>
                    </ul>
                </td>
                <td style="color:black;font-size:1.5em;font-weight:bold;">{{order.TotalRevenue | currency }}</td>
                <td>{{order.OrderStatus}}</td>
                <td>{{order.ShipmentTrackingURL}}</td>
                <td>{{order.CreatedDate | formatDate }}</td>
            </tr>
        </tbody>

在计算中

computed: {
  getCartLineItems() {
   return order => {
    if(order?.CartLineItems && order.CartLineItems.length) return order.CartLineItems;
    return [];
   }
 }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 2018-09-08
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    相关资源
    最近更新 更多