Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Rod2rick's avatar

Can't display image on Bootstrap-vue Datable

Hello, i can't display the image on my Bootstrap-vue Datable here is my code

<b-table
                      :striped="striped"
                      :bordered="bordered"
                      :borderless="borderless"
                      :outlined="outlined"
                      :sort-by.sync="sortBy"
                      :sort-desc.sync="sortDesc"
                      :current-page="currentPage"
                      :per-page="perPage"
                      :filter="filter"
                      :small="small"
                      :hover="hover"
                      :dark="dark"
                      :fixed="fixed"
                      :foot-clone="footClone"
                      :no-border-collapse="noCollapse"
                      :items="items"
                      :fields="fields"
                      :head-variant="headVariant"
                      :table-variant="tableVariant"
                    >
                      <template #cell(image)="row">
                        <div>
                          <b-img
                            v-on:click="info(row.item, row.index, $event.target)"
                            v-bind="mainProps"
                            center
                            :src="'/uploads/produits/' + fields.image"
                            alt="Center image"
                          ></b-img>
                        </div>
                      </template>
                      <template #cell(edit)="row">
                        <button
                          class="btn btn-sm btn-outline-info"
                          v-on:click="info(row.item, row.index, $event.target)"
                        >
                          <i class="fas fa-pen"></i>
                        </button>
                      </template>
                      <template #cell(delete)="row">
                        <button
                          class="btn btn-sm btn-outline-danger"
                          v-on:click="info(row.item, row.index, $event.target)"
                        >
                          <i class="fas fa-trash"></i>
                        </button>
                      </template>
                    </b-table>

<script>
import Vue from "vue";
import { BootstrapVue, IconsPlugin } from "bootstrap-vue";

// Install BootstrapVue
Vue.use(BootstrapVue);
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin);

export default {
  data() {
    return {
      filter: "",
      fields: [
        { key: "image", label: "" },
        { key: "nom", label: "Nom", sortable: true },
        {
          key: "description",
          label: "Description",
          sortable: true,
          sortDirection: "desc",
        },
        { key: "prix", label: "Prix", sortable: true },
        { key: "edit", label: "" },
        { key: "delete", label: "" },
      ],
      items: [],
      mainProps: {
          width: 55,
          height: 55,
          class: 'my-5'
        },
      tableVariants: [
        "primary",
        "secondary",
        "info",
        "danger",
        "warning",
        "success",
        "light",
        "dark",
      ],
      striped: false,
      bordered: false,
      borderless: false,
      outlined: false,
      small: false,
      hover: false,
      dark: false,
      fixed: false,
      footClone: false,
      headVariant: null,
      tableVariant: "",
      noCollapse: false,
      totalRows: 1,
      currentPage: 1,
      perPage: 5,
      pageOptions: [5, 10, 15, 25, 100, { value: 1000, text: "Tout" }],
      sortBy: "",
      sortDesc: false,
      sortDirection: "asc",
      filterOn: [],
    };
  },
  computed: {
    sortOptions() {
      // Create an options list from our fields
      return this.fields
        .filter((f) => f.sortable)
        .map((f) => {
          return { text: f.label, value: f.key };
        });
    },
  },
  mounted() {
    // Set the initial number of items
    this.totalRows = this.items.length;
  },
  methods: {
    getProduits: function () {
      axios.get("/api/listproduits").then(
        function (response) {
          this.items = response.data.data;
        }.bind(this)
      );
    },
    onFiltered(filteredItems) {
      // Trigger pagination to update the number of buttons/pages due to filtering
      this.totalRows = filteredItems.length;
      this.currentPage = 1;
    },
  },
  created: function () {
    this.getProduits();
  },
  mounted() {
    // Set the initial number of items
    this.totalRows = this.items.length;
  },
};
</script>

What did i make wrong so that the image can't be dislay. Thank you for the help.

0 likes
6 replies
MarianoMoreyra's avatar

Hi @rod2rick

According to documentation, the <b-img> component doesn't works with relative paths:

The src prop (and blank-src prop of ), out of the box, works only with absolute or fully-qualified-domain-name URLs

And, although you are fulling a full path, I'd try with the fully qualified URL within the :src prop. (including http:// or https://) to see if it works.

As an alternative, I guess you could try with a simple <img> tag which it seems to allow relative paths inside other bootstrap-vue components.

For a detailed explain and more complex workaround, check this link:

https://bootstrap-vue.org/docs/reference/images

Hope this helps!

MarianoMoreyra's avatar

@rod2rick I've just realized something else...

If you are using Laravel as the backend, you probably have to add 'storage' to your url:

:src="'/storage/uploads/produits/' + fields.image"

Anyway, just in case, check the url in a browser to be sure you can access the image there and be sure of what to use for the :src prop.

Rod2rick's avatar

@marianomoreyra when i use this code

<div
	v-for="produit in items"
	class="card"
	v-bind:key="produit.id"
>
<img
	 v-on:click="info(row.item, row.index, $event.target)"
	 v-bind="mainProps"
	 center
	 :src="'/storage/uploads/produits/' + fields.image"
	 alt="Center image"
/>

</div>

the system loads the images, but do it slowly and reloads the page every 30s. I know this is not the right method so I had to give up this route. I am very new to Vuejs and have never rowed so much to learn a framework. Otherwise from my code how can you help me correct it to improve and finally display the images. Thank you in advance

MarianoMoreyra's avatar

@rod2rick

the system loads the images, but not slowly

I don't understand what you mean with that. What do you mean by "not slowly"?

Also, the entire page reloads every 30s just because you've replaced the <b-img> with a <img>?

I don't think that page reloading could have anything to do with that change...maybe another place in code is triggering that reload?

Rod2rick's avatar

@marianomoreyra , the system loads the page but slowly and many times. Indeed,after putting the v-for="produit in items" , the system becomes slow and continuously reloads the same page.

Rod2rick's avatar
Rod2rick
OP
Best Answer
Level 1

I found the solution and this how i manage it : the table code

<template #cell(image)="data">
   <div>
     <center>
       <button
       v-on:click="getProduit(data.item.id)"
       data-target="#modalShow">
       <img class="c-avatar-prod" center
       :src="'/uploads/produits/' + data.item.image"
        alt="Produit image" />
       </button>
     </center>
   </div>
</template>

Please or to participate in this conversation.