Vue对象转换实现数据+对象外信息的循环对应渲染

【需求】实现三个(数字+文字)的页面效果

【场景】后端提供的数据格式为对象,其中有三个键名对应着所需数字,文字则不提供(需前端自行匹配)

【思路】

1. 最开始的做法是单独写出来

<div class="test">
    <div>
        <p class="figure">{{ obj.numA }}</p>
        <p>文字A</p>
    </div>
    <div>
        <p class="figure">{{ obj.numB }}</p>
        <p>文字B</p>
    </div>
    <div>
        <p class="figure">{{ obj.numC }}</p>
        <p>文字C</p>
    </div>
</div>

2. 考虑到后期万一增加了新的数据,写一大串很冗余也不美观,决定用v-for循环进行改造

3. 那么问题来了,后端给的格式是对象,怎么改造成数组进行循环呢?如果只是单纯把每个值push进新数组里,那文字应该怎么插入并对应呢?

    我只能循环一个数组:如果文字单独写,那么就不能使用循环(如1. );如果同时push进新数组里,又显得很奇怪

let arr = [1, "文字A", 2, "文字B", 3, "文字C"]

4. 思考过后决定使用提取键名的方式来改造:

    定义一个新的数组basicKey和一个新的对象basicText,一个用于存放键名,一个用于存放文字,加上原始对象(后端返回)basicInfo,这样所有需要的信息就已经备全了

    写法采取obj[key]的形式取值,而不是常用的obj.key,因为我需要在插值表达式{{}}中进行渲染,如果用常规方式,它会在obj中找"key"这个键名,而不是key所代表的键名了

<div class="number">
    <div v-for="(item, index) in basicKey" :key="index">
        <p class="figure">{{ basicInfo[item] }}</p>
        <p>{{ basicText[item] }}</p>
    </div>
</div>

5. 开发过程中还遇到一个小问题,原本我想在获取数据的地方用for in将键名提取出来,但后端告诉我不保证每次顺序都固定,这就导致可能会出现页面顺序混乱的情况,只好放弃这个写法,手动固定住basicKey的顺序(弊端:后端改字段时前端需要跟着一起改)

 

 

【以下是图示&全部代码】

<template>
    <div>
        <div class="number">
            <div v-for="(item, index) in basicKey" :key="index">
                <p class="figure">{{ basicInfo[item] }}</p>
                <p>{{ basicText[item] }}</p>
            </div>
        </div>
    </div>
</template>

<script>
import { xxxxxxxx } from '@/api/api';
export default {
  name: 'abc',
  data() {
    return {
        id: 1,
        basicInfo: {
            otherParams: '...',
            aaa: '--',
            bbb: '--',
            ccc: '--',
        },
        basicKey: ['aaa', 'bbb', 'ccc'],
        basicText: {
            aaa: '文字A',
            bbb: '文字B',
            ccc: '文字C',
        },
    };
  },
  created() {
    this.getBasis();
  },
  methods: {
    // 获取基本信息
    async getBasis() {
      const res = await xxxxxxxx({ id: this.id });
      if (res.data.retCode === '200') {
        this.basicInfo = res.data.data;
      }
    },
   }
};
</script>

<style lang='less' scoped>
    .number {
        display: flex;
        justify-content: space-between;
        width: 400px;
        margin-top: 15px;
        .figure {
            font-size: 40px;
            color: #1c93ff;
        }
    }
</style>

 

posted @ 2022-08-09 17:24  沐夏52Hz  阅读(264)  评论(0编辑  收藏  举报