Как отобразить привязанные данные в раскрывающемся списке в Vue

#javascript #vue.js #vuejs2 #dropdown

Вопрос:

Я получаю данные из API и хочу показать их в раскрывающемся списке.

 "data": [
    {
      "type": "products",
      "id": "2021-01-04.1.1",
      "attributes": {
        "name": "product 1",
        "descriptions": "some description",
        "image": null,
        "date": "2021-01-04",
        "valid_from": null,
        "valig_untill": null,
        "xparc_paid_product_id": 1,
        "xparc_unpaid_product_id": 1,
        "xparc_access_id": 1,
        "stock": null,
        "variations": [
          {
            "id": 1,
            "product_template_id": "1",
            "name": "child ticket",
            "description": "Only for children!",
            "price_excl_vat": 1,
            "created_at": "2021-09-15T13:16:00.000000Z",
            "updated_at": "2021-09-15T13:16:00.000000Z"
          },
          {
            "id": 2,
            "product_template_id": "1",
            "name": "Adults",
            "description": "Not for children!",
            "price_excl_vat": 2,
            "created_at": "2021-09-15T13:16:10.000000Z",
            "updated_at": "2021-09-15T13:16:10.000000Z"
          },
          {
            "id": 3,
            "product_template_id": "1",
            "name": "Test",
            "description": "Test",
            "price_excl_vat": 10,
            "created_at": "2021-09-30T11:29:44.000000Z",
            "updated_at": "2021-09-30T11:29:44.000000Z"
          }
        ]
      },
    }
]
 

Итак, я хочу отобразить имена вариантов в своем раскрывающемся списке. А позже в соответствии с выбранным значением я хочу показать цену вариаций.
Вот мой выпадающий список:

 <Dropdown
  :options="[product.attributes.variations.name]"
  :default="'Choose an option'"
  class="select"
/>
 

И вот мой раскрывающийся компонент:

 <template>
    <div class="custom-select" :tabindex="tabindex" @blur="open = false">
        <div class="selected" :class="{ open: open }" @click="open = !open">
            {{ selected }}
        </div>
        <div class="items" :class="{ selectHide: !open }">
            <div
                v-for="(option, i) of options"
                :key="i"
                @click="
          selected = option;
          open = false;
          $emit('input', option);
        "
            >
                {{ option }}
            </div>
        </div>
    </div>
</template>

<script>
export default {
    props: {
        options: {
            type: Array,
            required: true,
        },
        default: {
            type: String,
            required: false,
            default: null,
        },
        tabindex: {
            type: Number,
            required: false,
            default: 0,
        },
    },
    data() {
        return {
            selected: this.default
                ? this.default
                : this.options.length > 0
                    ? this.options[0]
                    : null,
            open: false,
        };
    },
    mounted() {
        this.$emit("input", this.selected);
    },
};
</script>
 

В настоящее время выпадающий список пуст. Я попытался положить его внутрь для, но это тоже не помогло. Не могли бы вы, пожалуйста, взглянуть?
Спасибо

Комментарии:

1. Эй, приятель, Выпадающий список-это твой компонент или?

2. Эй, да, это так, и я просто отредактировал свой вопрос.

Ответ №1:

Попробуйте сопоставить изменения в вычисленных :

 Vue.component('Dropdown', {
  template: `
    <div class="custom-select" :tabindex="tabindex" @blur="open = false">
        <div class="selected" :class="{ open: open }" @click="open = !open">
            {{ selected }}
        </div>
        <div class="items" :class="{ selectHide: !open }">
            <div
                v-for="(option, i) of options"
                :key="i"
                @click="
          selected = option;
          open = false;
          $emit('input', option);
        "
            >
                {{ option }}
            </div>
        </div>
    </div>
  `,
   props: {
        options: {
            type: Array,
            required: true,
        },
        default: {
            type: String,
            required: false,
            default: null,
        },
        tabindex: {
            type: Number,
            required: false,
            default: 0,
        },
    },
    data() {
        return {
            selected: this.default
                ? this.default
                : this.options.length > 0
                    ? this.options[0]
                    : null,
            open: false,
        };
    },
    mounted() {
        this.$emit("input", this.selected);
    },
})
new Vue({
  el: '#demo',
  data(){
    return {
      "data": 
          {
            "type": "products",
            "id": "2021-01-04.1.1",
            "attributes": {
              "name": "product 1",
              "descriptions": "some description",
              "image": null,
              "date": "2021-01-04",
              "valid_from": null,
              "valig_untill": null,
              "xparc_paid_product_id": 1,
              "xparc_unpaid_product_id": 1,
              "xparc_access_id": 1,
              "stock": null,
              "variations": [
                {
                  "id": 1,
                  "product_template_id": "1",
                  "name": "child ticket",
                  "description": "Only for children!",
                  "price_excl_vat": 1,
                  "created_at": "2021-09-15T13:16:00.000000Z",
                  "updated_at": "2021-09-15T13:16:00.000000Z"
                },
                {
                  "id": 2,
                  "product_template_id": "1",
                  "name": "Adults",
                  "description": "Not for children!",
                  "price_excl_vat": 2,
                  "created_at": "2021-09-15T13:16:10.000000Z",
                  "updated_at": "2021-09-15T13:16:10.000000Z"
                },
                {
                  "id": 3,
                  "product_template_id": "1",
                  "name": "Test",
                  "description": "Test",
                  "price_excl_vat": 10,
                  "created_at": "2021-09-30T11:29:44.000000Z",
                  "updated_at": "2021-09-30T11:29:44.000000Z"
                }
              ]
            },
          }
        
    }
  },
  computed: {
    variations() {
      return this.data.attributes.variations.map(m => m.name)
    }
  }
}) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<Dropdown
  :options="variations"
  :default="'Choose an option'"
  class="select"
/>
</div> 

Комментарии:

1. Спасибо за ваш ответ. Во-первых, я получаю эту ошибку: Ошибка при рендеринге: «Ошибка типа: this.data.map не является функцией», а во-вторых, для чего используется flat ()?

2. Эй, приятель, данные должны быть массивом , как в моем фрагменте, так что это ошибка, и результат сопоставления-массив с массивом, поэтому нам нужна функция flat() для выравнивания массива

3. Но на самом деле в моем примере данные являются объектом, поэтому я не уверен, что делать

4. Проверьте сейчас, я обновил ответ, теперь вам не нужна квартира()

5. Спасибо, это сработало!