So I have this array item :
[
{
"name": "user language check dates in different language",
"tag": "@DHRD-52484",
"status": "passed",
"refimages": [
"/captures/ref_01_03_2022_17_05_21/@DHRD-52484/user language check dates in different language/1.png",
"/captures/ref_01_03_2022_17_05_21/@DHRD-52484/user language check dates in different language/2.png",
"/captures/ref_01_03_2022_17_05_21/@DHRD-52484/user language check dates in different language/3.png",
"/captures/ref_01_03_2022_17_05_21/@DHRD-52484/user language check dates in different language/4.png"
],
"testimages": [
"/captures/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/1.png",
"/captures/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/2.png",
"/captures/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/3.png",
"/captures/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/4.png"
],
"resultimages": [
"/VisualTests/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/1.png",
"/VisualTests/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/2.png",
"/VisualTests/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/3.png",
"/VisualTests/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/4.png"
]
}
]
and I've been trying to have a table using vuetify with each row representing the index of the image,the refimage, testimage and result image this is my code so far :
<template>
<v-app>
<app-navbar />
<v-main>
<h3>
test {{ $route.params.name }}, {{ $route.query.status }},{{
$route.query.tag
}}
</h3>
<h3>{{ imagesref }}</h3>
<v-data-table
:headers="headers"
:items="items"
:items-per-page="5"
></v-data-table>
</v-main>
</v-app>
</template>
<script>
import appNavbar from "../../../components/appNavbar.vue"
import axios from "axios"
export default {
components: { appNavbar },
name: "App",
data() {
return {
items: [],
imagesref: [],
imagestest: [],
imagesresult: [],
headers: [
{
text: "index",
align: "start",
sortable: false,
value: "index",
},
{ text: "reference image", value: "refimages" },
{ text: "test image", value: "test" },
{ text: "result image", value: "result" },
],
}
},
async created() {
try {
const res = await axios.get(`http://localhost:3004/tests`, {
params: { name: this.$route.params.name },
})
this.items = res.data
this.imagesref = res.data[0].refimages
this.imagestest = res.data[0].testimages
this.imagesresult = res.data[0].resultimages
} catch (error) {
console.log(error)
}
},
}
</script>
<style lang="scss" scoped>
</style>
I tried saving the refimages,testimages and resultimages array in 3 variables but I still don't know how can i iterate over these 3 arrays in parallel and use the img tag to display the image from the path
CodePudding user response:
I found a solution for your problem that for better explaining that, I separate it to some steps:
step1: Test the img urls
First of all put an <img>
tag to the component to test that the urls you defined in your data actually works or not:
<img width="50" src="../assets/images/1.png">
Here I have 1.png
image in my assets
directory. If that does not show the image, that means your url address (for example /captures/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language/1.png
) have some problem. Try to fix that to continue.
step2: Store data in "json" file
After that if you do not have any problems with your images urls
, you must paste your data in a json file that is saved in your public
directory. Here I called it dataMe.json
and put these sample data on it. you can put your own data:
[
{
"name": "user1",
"tag": "@DHRD-52484-1",
"status": "passed",
"imgUrl": "1.png"
},
{
"name": "user2",
"tag": "@DHRD-52484-2",
"status": "passed",
"imgUrl": "2.png"
},
{
"name": "user3",
"tag": "@DHRD-52484-3",
"status": "passed",
"imgUrl": "5.png"
}
]
At this point, if you paste http://localhost:8080/dataMe.json
(instead of 8080, use your own port number) in your browser address bar, you should see the data that is in the file in your browser.
step3: Change your
template
andscript
codes
If you want to iterate over your data in vuetify table, you should not separate the data. All the data comes from your axios request must be in items
data of your vue component. Here is the code of my component:
<template>
<v-app>
<v-main>
<v-data-table
:headers="headers"
:items="items"
>
<!-- This template is used to have custom html elements in your specific column of the table -->
<template v-slot:item.imgUrl="{ item }">
<!-- You can uncomment the line below to see the actual item data. Also you can use 'v-for' or 'v-if' or other vue capabilities, if your item data is more complex. -->
<!-- <span>{{item}}</span>-->
<img width="50" :src="require(`../assets/images/${item.imgUrl}`)">
</template>
</v-data-table>
</v-main>
</v-app>
</template>
<script>
import axios from "axios"
export default {
name: "DataView",
data() {
return {
items: [],
// imagesref: [],
// imagestest: [],
// imagesresult: [],
headers: [
{ text: "name", value: "name" },
{ text: "tag", value: "tag" },
{ text: "status", value: "status" },
{ text: "image", value: "imgUrl" },
],
}
},
async created() {
try {
// replace the port number with your own port number
const res = await axios.get('http://localhost:8080/dataMe.json');
console.log(res.data);
this.items = res.data;
// this.imagesref = res.data[0].refimages
// this.imagestest = res.data[0].testimages
// this.imagesresult = res.data[0].resultimages
} catch (error) {
console.log(error)
}
},
}
</script>
<style scoped>
</style>
As you can see I used v-data-table
Slots capability to handle the image problem. With this capability of vuetify you can add or replace custom html elements to built-in vuetify components. Also see this example to better understand the usage of Slots in v-data-table
component.
The last tip that I think is necessary to mention is that do not put the whole address of your images in the json data file. Put only the variable part (for example 1.png
and 2.png
and so on) and for the repeated part (for example /captures/test_07_03_2022_10_13_48/@DHRD-52484/user language check dates in different language
) put that in :src="require(...
part of your vue template code.
That is the solution that works with my sample data. You may need to add more columns or change your headers
or items
part of your table to have the desired table that you want with your own data.
CodePudding user response:
Thanks @hamid-davodi for your solution ! I have also tried finding my own and here's what I came up with
<template>
<v-app>
<app-navbar />
<v-main>
<h3>
test {{ $route.params.name }}, {{ $route.query.status }},{{
$route.query.tag
}}
</h3>
<h3>{{ imagesref }}</h3>
<v-data-table
:headers="headers"
:items="imagesref"
:items-per-page="5"
>
<template v-slot:[`item.index`]="{ index }">
{{index 1}}
</template>
<template v-slot:[`item.ref`]="{ index }">
<v-img :src="imagesref[index]" max-width="750" max-height="750" @click="expand" />
</template>
<template v-slot:[`item.test`]="{ index }">
<v-img :src="imagestest[index]" max-width="750" max-height="750" />
</template>
<template v-slot:[`item.res`]="{ index }">
<v-img :src="imagesresult[index]" max-width="750" max-height="750" />
</template>
</v-data-table>
</v-main>
</v-app>
</template>
<script>
import appNavbar from "../../../components/appNavbar.vue"
import axios from "axios"
export default {
components: { appNavbar },
name: "App",
data() {
return {
exp:false,
items: [],
imagesref: [],
imagestest: [],
imagesresult: [],
headers: [
{ text: 'index',value: 'index',sortable:false},
{ text: 'Imagesref', value: 'ref',sortable:false },
{ text: 'Imagestest', value: 'test',sortable:false },
{ text: 'Imagesresult', value: 'res',sortable:false },
{ text: 'Scrubber', value: '',sortable:false },
]
}
},
async created() {
try {
const res = await axios.get(`http://localhost:3004/tests`, {
params: { name: this.$route.params.name },
})
this.items = res.data
this.imagesref = res.data[0].refimages
this.imagestest = res.data[0].testimages
this.imagesresult = res.data[0].resultimages
} catch (error) {
console.log(error)
}
},
methods:{
expand(){
this.exp= !this.exp;
}
}
}
</script>
<style scoped>
</style>
Since the paths of the images are ordered in the array, I used v-slot with the index object to display each image in the correct row. I'm using nuxtjs so I saved the images in the static folder so that I wouldn't need to change the path.
I hope this can help a fellow beginner in vue/vuetify.