使用 Vue JS Typescript 迭代一个对象 -> 数组 -> 对象

Posted

技术标签:

【中文标题】使用 Vue JS Typescript 迭代一个对象 -> 数组 -> 对象【英文标题】:Iterate an object -> array -> object with Vue JS Typescript 【发布时间】:2019-05-01 00:26:42 【问题描述】:

所以我有一个包含对象数组的对象。我需要抓取数组每个对象中的数据来显示营业时间。

我已成功检索到 sn-p 内 for 循环中的每个键值。但我不确定如何在我的 .vue 视图页面中显示它。

我是否使用字符串插值?我应该在 .vue 页面中使用 v-for 指令来显示数据吗?

对于 Vue JS 来说还是相当新的,所以任何帮助都将不胜感激!

import 
  Vue,
  Component
 from 'vue-property-decorator';
import 
  namespace
 from 'vuex-class';
import FoodMerchant from '../../models/FoodMerchant';

export default class MerchantProfilePage extends Vue 
  @namespace('merchant').State('foodMerchant') foodMerchant!: FoodMerchant;

  openingHours() 
    for (let i = 0; i < this.foodMerchant.opening_hours.data.length; i++) 
      console.log(this.foodMerchant.opening_hours.data[i].startHour);
    
  
<button @click="openingHours()">show opening hours</button>

<div class="openingHours d-flex flex-wrap mb-10">
  <div class="d-flex justify-content-between mb-10 w-100">
    <h5 class="font-italic text-black font-12">
      Wednesday
    </h5>

    <h5 class="font-italic text-black font-12 font-weight-light">
      5:00pm - 11:00pm
    </h5>
  </div>
</div>

<div class="openingHours d-flex flex-wrap mb-10">
  <div class="d-flex justify-content-between mb-10 w-100">
    <h5 class="font-italic text-black font-12">
      Thursday
    </h5>

    <h5 class="font-italic text-black font-12 font-weight-light">
      5:00pm - 11:00pm
    </h5>
  </div>
</div>

<div class="openingHours d-flex flex-wrap mb-10">
  <div class="d-flex justify-content-between mb-10 w-100">
    <h5 class="font-italic text-black font-12">
      Friday
    </h5>

    <h5 class="font-italic text-black font-12 font-weight-light">
      5:00pm - 11:00pm
    </h5>
  </div>
</div>

<div class="openingHours d-flex flex-wrap mb-10">
  <div class="d-flex justify-content-between mb-10 w-100">
    <h5 class="font-italic text-black font-12">
      Saturday
    </h5>

    <h5 class="font-italic text-black font-12 font-weight-light">
      5:00pm - 11:00pm
    </h5>
  </div>
</div>

<div class="openingHours d-flex flex-wrap mb-10">
  <div class="d-flex justify-content-between mb-10 w-100">
    <h5 class="font-italic text-black font-12">
      Sunday
    </h5>

    <h5 class="font-italic text-black font-12 font-weight-light">
      5:00pm - 11:00pm
    </h5>
  </div>
</div>

【问题讨论】:

【参考方案1】:

这是我如何解决它的草图(我没有测试过代码,抱歉):

模板:

显示营业时间

<div class="openingHours d-flex flex-wrap mb-10"
     v-if="showOpeningHours"
     v-for="item in foodMerchant.opening_hours.data">
  <div class="d-flex justify-content-between mb-10 w-100">
    <h5 class="font-italic text-black font-12">
       formatDay(item.day) 
    </h5>

    <h5 class="font-italic text-black font-12 font-weight-light">
       formatTime(item.startHour, item.startMinute, item.startSecond) 
      -
       formatTime(item.endHour, item.endMinute, item.endSecond) 
    </h5>
  </div>
</div>

组件:

import 
  Vue,
  Component
 from 'vue-property-decorator';
import 
  namespace
 from 'vuex-class';
import FoodMerchant from '../../models/FoodMerchant';

const WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
                  'Friday', 'Saturday'];

export default class MerchantProfilePage extends Vue 
  @namespace('merchant').State('foodMerchant') foodMerchant!: FoodMerchant;
  private showOpeningHours: boolean = false;

  private formatDay(day: number): string 
    return WEEKDAYS[Math.trunc(day) % 7]
  

  private formatTime(h: number; m: number, s: number): string 
    // It's better to use a library for this
    // The Date constructor needs a full date, but we'll only use the time
    const date = new Date(`2000-01-01 $h:$m:$s`)
    return date.toLocaleTimeString('en-us');
  

您的问题是:

我是否使用字符串插值? 我是否应该在 .vue 页面中使用 v-for 指令来显示数据?

我认为您已经正确地确定了您面临的主要问题:如何显示所有项目,以及如何设置它们的格式。

如您所见,v-for 是一种无需重复即可显示不同类型列表的简洁方式。

格式化是一个更大的话题,有很多方法可以做到。我在上面包含的代码是可行的,但它主要是作为示例。您可能需要考虑以下事项:

Vue filters 可以让您在一个地方定义格式并编写像这样的代码 item.startTime | formatTime 使用库来帮助您格式化内容。日期可能很棘手,尤其是当您需要支持不同的语言环境等时。其中有很多——我用过date-fns、luxon 和Moment。它们都有不同的优缺点。 如果您控制数据的格式,您可以确保它易于格式化,即可以使用您选择的库进行解析和格式化,而无需先修改它。

最后,我认为您的问题对于 Stack Overflow 格式来说有点过于宽泛,因为除了您之外,答案可能对任何人都没有帮助。另一方面,您已经做出了很大的努力来展示您尝试过的内容以及您的想法。查看您的代码,您似乎知道自己在做什么,但您只是缺少一些工具。如果您还没有,不妨浏览一下Vue Guide 的主要部分。有很多例子。即使您不能一下子了解所有内容,但最好了解一下可能发生的事情。

【讨论】:

【参考方案2】:
<div class="openingHours d-flex flex-wrap mb-10" v-for="(item, index) in foodMerchant.opening_hours.data" :key="index">
  <div class="d-flex justify-content-between mb-10 w-100">
    <h5 class="font-italic text-black font-12">
       weeks[item.day - 1] 
    </h5>

    <h5 class="font-italic text-black font-12 font-weight-light">
       item.startTime  -  item.endTime 
    </h5>
  </div>
</div>
<script>
    export default 
        data() 
            return 
                weeks: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
            
        
    
</script>

希望对你有帮助

【讨论】:

谢谢!是的,这种帮助。虽然如果我想将“星期一”显示为 day: 1,我该怎么做?如果例如 day: 7 不存在,我怎样才能在视图页面中显示“星期日”? 你可以像这样创建一个数组:['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']。那么 Array[item.day - 1] 是你的需要

以上是关于使用 Vue JS Typescript 迭代一个对象 -> 数组 -> 对象的主要内容,如果未能解决你的问题,请参考以下文章

Webpack 4,Vue 同时使用 Typescript 类和 JS 代码。

Vue + Typescript + Webpack:模块构建失败 - 找不到 vue.esm.js

如何将 TypeScript 与 Vue.js 和单文件组件一起使用?

Vue js,使用 TypeScript 从 Vue 中的表单获取数据

typescript 使用Typescript将属性添加到Vue.js中的数组

(如何)我应该在 Vue.js 组件(TypeScript)中使用访问修饰符(公共、私有等)吗?