Vuejs iterate complex object by data key

82 Views Asked by At

I'm using Vuejs3 to build a simple article configurator.

Let's define a complex object:

const article = reactive({
  code: 'code',
  specs: {
    type: { text: 'description type', value:'mytype'} ,
    prop1: { text: 'description prop1', value: 'myprop1' },        
    prop2: { text: 'description prop1', value: 'myprop1' },                
  },
  dimensions: { base: 10, height: 20}
})

Let's see every article.spec:

<li v-for="(value, propertyName, index) in article.specs">
  {{ propertyName }}:  {{ value }} ({{ index }})
</li>   

result:

type: { "text": "description type", "value": "mytype" } (0)
prop1: { "text": "description prop1", "value": "myprop1" } (1)
prop2: { "text": "description prop1", "value": "myprop1" } (2)

But how do I extract property "value" only to get.

type: description type
prop1: description prop1
prop2: description prop1

I'v tried with:

  {{ propertyName }}:  {{ value[text] }}  ({{ index }})

but result in empty values:

type: (0)
prop1: (1)
prop2: (2)
4

There are 4 best solutions below

0
On BEST ANSWER

Another approach to minimize template code could be to define a computed:

    const article_specs = computed(() => {
      let result = '';
      Object.keys(article.specs).forEach((item) => {
    
        result +=  article.specs[item].value + 'todo'
        console.log("item", article.specs[item])
    
      })

  return result;
})

And template code became:

{{article_specs}}
0
On

If you want to use brackets [] to access into a propery name, use an string inside brackets ["text"]

<template>
  <li v-for="(value, propertyName, index) in article.specs">
    {{ propertyName }}:  {{ value["text"] }} ({{ index }})
  </li>   
</template>
0
On

Solution # 1

Can call prop of object by name.

value.text

// or

value["text"]

Can call property of object by dynamically variable.

const name = "text"
value[name]

Solution # 2

Can use for loop.

<span v-for="propValue of value">{{ propValue }}</span>

Example

const { createApp, reactive } = Vue

const app = createApp({
  setup() {
    const article = reactive({
      code: 'code',
      specs: {
        type: { text: 'description type', value:'mytype'} ,
        prop1: { text: 'description prop1', value: 'myprop1' },        
        prop2: { text: 'description prop1', value: 'myprop1' },                
      },
      dimensions: { base: 10, height: 20}
    })

    return { article }
  }
}).mount('#app')
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>

<div id="app">
  <h2>Your code</h2>
  <ul>
    <li v-for="(value, propertyName, index) in article.specs">
      {{ propertyName }}:  {{ value }} ({{ index }})
    </li>
  </ul>
  
  <h2>Solution # 1</h2>
  <ul>
    <li v-for="(value, propertyName, index) in article.specs">
      <div style="display: flex; gap: 8px;">
        <span>{{ propertyName }}:</span>
        
        <!-- can use object.name or object[name] formats -->
        <!-- can add dynamically name if use object[name] format -->
        <span>{{ value.text }}</span> <!-- or value["text"] -->
        <span>{{ value["value"] }}</span> <!-- or value.value -->
        
        <span>{{ index }}</span>
    </li>
  </ul>
  
  <h2>Solution # 2</h2>
  <ul>
    <li v-for="(value, propertyName, index) in article.specs">
      <div style="display: flex; gap: 8px;">
        <span>{{ propertyName }}:</span>

        <!-- can use for loop -->
        <span v-for="propValue of value">{{ propValue }}</span>

        <span>{{ index }}</span>
      </div>
    </li>
  </ul>
</div>

1
On

Use correct separator: not [] but . !

  {{ propertyName }}:  {{ value.text }} ({{ index }})