I'm trying to create a component in vuepress to display an image with its caption. When I hardcode the image path, the image appears but this way I will not have a reusable component. I already try with props, but it doesn't work either.
Here is how I already tried:
<template>
<figure>
<!-- <img src="../../guides/contribute/images/typora-tela1.png" alt=""/> -->
<img :src="imagesrc" alt=""/>
<figcaption>Legenda: {{ caption }} - {{ src }}</figcaption>
</figure>
</template>
<script>
...
props: ['src'],
computed: {
imagesrc () {
return '../../guides/contribute/images/' + this.src // this.image
}
}
...
</script>
On my README.md I call the component like this: <captioned-image src="filename.png" caption="Caption Example" /> but the image doesn't appear.
How can I fix this issue? Is it possible to do this with markdown only?
In markdown (without a Vue component) you can use html,
<figure>
<img src='../../guides/contribute/images/typora-tela1.png'>
<figcaption>Caption Example</figcaption>
</figure>
To make the CaptionedImage.vue component work I think you need to put the images in the /.vuepress/public/ folder.
The difference (as I understand it) is that within the markdown the image path is handled at compile time, but for the component the image path is resolved at runtime.
Anything placed in /.vuepress/public/ is available at runtime referenced from the page root.
This works for me:
project structure
<project root folder>
docs
.vuepress
components
CaptionedImage.vue
public
images
myImage.jpg
ReadMe.md
CaptionedImage.vue
<template>
<figure>
<img :src="imagesrc" alt=""/>
<figcaption>Legenda: {{ caption }} - {{ src }}</figcaption>
</figure>
</template>
<script>
export default {
props: ['src', 'caption'],
computed: {
imagesrc () {
return './images/' + this.src
}
}
}
</script>
ReadMe.md
<CaptionedImage src="myImage.jpg" caption="Caption Example"></CaptionedImage>
Thanks to Richard. Based on what he did, I changed a little. So that
image shows in the center.
width can be changed very easily.
caption show in small size and italic font.
Cimg.vue
<template>
<figure align='center'>
<img :src="imagesrc" :width="width" alt=""/>
<figcaption><i><small>{{ caption }}</small></i></figcaption>
</figure>
</template>
<script>
export default {
props: ['src', 'caption', 'width'],
computed: {
imagesrc () {
return this.src
}
}
}
</script>
ReadMe.md
For example:
<Cimg src='/images/ml/GAN/永野芽郁.jpg' width='100%' caption="《半分、青い》 玲爱"/>
Here is the final effect.
Related
I am practicing for a vue TestDome test this week. One of the practice questions is as follows :
An image gallery is a set of images with corresponding remove buttons. This is the HTML code for a gallery with two images:
<div>
<div class="image">
<img src="https://www.testdome.com/files/resources/12362/aff5c408-79f8-4220-9769-8b4cde774c98.jpg">
<button class="remove">X</button>
</div>
<div class="image">
<img src="https://www.testdome.com/files/resources/12362/dbd97d8f-cc11-48bd-bf21-b8762a39a55e.jpg">
<button class="remove">X</button>
</div>
</div>
Implement the image-gallery component that accepts a links prop and renders the gallery described above so that the first item in the links prop is the src attribute of the first image in the gallery. It should also implement the following logic: When the button is clicked, the image that is in the same div as the button should be removed from the gallery.
The component should be usable with any root Vue instance.
For example, after the first image has been removed from the gallery above, it's HTML code should look like this:
<div>
<div class="image">
<img src="https://www.testdome.com/files/resources/12362/dbd97d8f-cc11-48bd-bf21-b8762a39a55e.jpg">
<button class="remove">X</button>
</div>
</div>
Here is my solution, which when run locally, renders the two images and buttons, as well as deletes them when clicked.
<!DOCTYPE html>
<html>
<head>
<title>Image Gallery</title>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.min.js"></script>
</head>
<body>
<div id="app">
<image-gallery :links="links" #remove-link="removeLink"/>
</div>
<script>
// Create image-gallery component that accepts link prop
Vue.component('image-gallery', {
props: ['links'],
template: `
<div>
<div v-for="link in links" class="image">
<img :src="link" />
<button #click="removeLink(link)" class="remove">X</button>
</div>
</div>
`,
methods: {
removeLink (link) {
this.$emit('remove-link', link)
}
}}
);
var vm = new Vue({
el: "#app",
data () {
return {
links: ['https://www.testdome.com/files/resources/12362/aff5c408-79f8-4220-9769-8b4cde774c98.jpg', 'https://www.testdome.com/files/resources/12362/dbd97d8f-cc11-48bd-bf21-b8762a39a55e.jpg']
}
},
methods: {
removeLink(link) {
this.links = this.links.filter(l => l !== link)
}
}
}
);
// Example case
let firstButton = document.querySelectorAll("div.image > button")[0];
if(firstButton) {
firstButton.click();
}
setTimeout(() => console.log(document.getElementById("app").innerHTML));
</script>
</body>
</html>
The results according to testdome:
Example case: Wrong answer
ImageGallery will render the correct list: Correct answer
Remove a single image: Wrong answer
Remove multiple images: Wrong answer
Run OK, but 3 out of 4 test cases failed.
Output:
<div><div class="image"><img src="https://www.testdome.com/files/resources/12362/dbd97d8f-cc11-48bd-bf21-b8762a39a55e.jpg"> <button class="remove">X</button></div></div>
Unless I am reading the question wrong, the result is correct. What am I missing?
Haven't touched Vue in a while, now I'm building a <HeroImage> component in Vue and Vuetify which takes an src attributes, put the image, and combine it a certain way with the slot and other props.
Usually, the answer is wrapping the src string in a request(). But now it throws this message at compile time:
Critical dependency: the request of a dependency is an expression
Here's what I'm trying to do:
<!--
src/views/Home.vue
-->
<template>
<!-- This does not work -->
<HeroImage src="#/assets/hero-image.png" />
<!-- As comparison, this somehow works -->
<img :src="require('#/assets/hero-image.png')" />
</template>
<script>
import HeroImage from "#/components/HeroImage"
export default {
components: { HeroImage }
}
</script>
<!--
src/components/HeroImage.vue
-->
<template>
<img alt="Hero Image" class="align-center justify-center" :src="require(src)" />
</template>
<script>
export default {
name: "HeroImage",
props: {
src: String
}
}
</script>
I have a React component that maps data from a .js file, containing objects in the array. How can I link my title and images from within this function to access respective pages?
In this file, I am getting errors for every [x] used for linking img src to the info.js file
Is there a different way to link an img from a js array?
import React from "react";
import Header from "./Header";
import Footer from "./Footer";
import Card from "./Card";
import Btt from "./BackToTop";
import info from "../info";
function Bolt() {
return(
<div>
<Header />
<div>
<h1 className="projHead">Bolt</h1>
<div className="card-img-top"><img src={info.[1].src} alt="" className="banner"></img>
</div>
</div>
<div className="text1">
<h3>Mind Map</h3>
</div>
<div className="card-img-top"><img src={info.[1].pic1} alt="" className="isoimg"></img></div>
<div className="card-img-top"><img src={info.[1].pic2} alt="" className="isoimg"></img></div>
<div className="card-img-top"><img src={info.[1].pic3} alt="" className="isoimg"></img></div>
<div className="card-img-top"><img src={info.[1].pic4} alt="" className="isoimg"></img></div>
<div className="text1">
<h3>Screen Layouts</h3>
</div>
<div className="card-img-top"><img src={info.[1].pic5} alt="" className="isoimg"></img></div>
<div className="text1">
<h3>Mockups</h3>
</div>
<div className="card-img-top"><img src={info.[1].pic6} alt="" className="smallisoimg"></img></div>
<Btt />
<Footer />
</div>
);
}
export default Bolt;
this is the JS file for content
const info = [
{
id: 1,
title: "AR mirror",
about: "Smart Exercise Mirror is an IOT product. It helps the user to have a gym-like experience at their home with the help of AR and image recognition technology. ",
src: "images/AR_Mirror/AR_mirror.png",
tag1: "UX & Product design",
link: "/ARmirror",
targ: "_self",
pic1: "images/AR_Mirror/ar1.jpg",
pic2: "images/AR_Mirror/ar2.png",
pic3: "images/AR_Mirror/ar3.png",
pic4: "images/AR_Mirror/ar4.png",
pic5: "images/AR_Mirror/ar5.gif",
pic6: "images/AR_Mirror/ar6.png",
vid: "images/AR_Mirror/AR_mirror.MOV",
},
{
id: 2,
title: "Bolt",
about: "Bolt is an app for electric bikes which allows user to monitor the bike from remote distance and functions as a control panel.",
src: "images/Bolt/Bolt.jpg",
tag1: "UX design",
link: "/Bolt",
targ: "_self",
pic1: "images/Bolt/bs1.png",
pic2: "images/Bolt/bs2.png",
pic3: "images/Bolt/bs3.png",
pic4: "images/Bolt/bs4.png",
pic5: "images/Bolt/bs5.png",
pic6: "images/Bolt/bs6.gif",
}
];
export default info;
I believe, this syntax (info.[1]) is wrong. That's why you have errors.
You should change it to info[1]. Thats orthodox way of accessing array elements by their indices.
Other than this, you should better use map or foreach iterating over array.
In that case just replace
info.[1].pic1
to
info?.[1]?.pic1
If you doing it static then its fine.
But in future if you are using more data it will be better to use For-loop or Map because it's better way to use array data
import React from 'react';
import '../styles/animation.css';
const Animation = ({ name, gif, description, link }) => {
return (
<div className="block">
<div className="naslov-link">
<h3>{name}</h3>
<span className="animation-link-header">
Visit
</span>
</div>
<img src={require(gif)} alt={name}/>
<p>{description}</p>
</div>
);
}
export default Animation;
gif is location of the image that is taken from database, I tried logging it and it works, but image
can't be loaded. I get:
Error: Cannot find module '../images/placeholder.jfif'
on line :
<img src={require(gif)} alt={name}/>
also tried
<img src={gif} alt={name}/>
Then I don't get error but image can't be loaded, I get the alt text
I've created a component, and in that component is an audio tag. I've been trying to pass the file path of the mp3 to the component from its parent, but the audio element doesn't seem to be able to load the file successfully for some reason. The element just ends up greyed out, and I don't get any kind of error. I know the properties are being passed successfully because I'm also passing in the title of the track, and that loads just fine in the component. However, if I hardcode the same path in for the source, then it works fine. Which isn't a big deal, but I have 11 tracks to do and it would be much easier with a v-for statement.
Here's my parent component:
<template>
<div container>
<div class=banner>
<img src="../assets/CryptoLogo2.svg"/>
</div>
<div class="albumcontainer">
<div class="covercontainer"><img src="../assets/TIADCover(Final).png"/></div>
<div class="arrow"></div>
<div class="tracklistcontainer">
<table class="tracklist">
<tr class="track" v-for="track in tracks" :key="track.file" style="padding: 20px;">
<td>
<player :name="track.name" :file="track.file" />
</td>
</tr>
</table>
</div>
</div>
<div class="bio">
<p>
</p>
</div>
<div class="footer">
<div class="footericons">
<img src="../assets/icons/Facebook.svg" />
<img src="../assets/icons/Instagram.svg" />
<img src="../assets/icons/Twitter.svg" />
</div>
</div>
</div>
</template>
<script>
import player from './player'
export default {
name: "Album1",
data() {
return {
tracks: [
{
name: '5G',
file: '../assets/tracks/5G.mp3'
}
]
}
},
components:{
player
}
};
</script>
And then the component with the audio tag:
<template>
<div>
<h3>{{ name }}</h3>
<audio controls controlsList="nodownload">
<source ref="player" v-bind:src="file" type="audio/mpeg">
</audio>
</div>
</template>
<script>
export default{
name: "player",
props: {
name: {
type: String,
default: null
},
file:{
type: String,
default: null
}
}
}
</script>
Here you can see that my data is being passed successfully.
And you see that the source attribute is being loaded correctly as well.
This is what I get, and you can see the h3 loads fine, so I know the data is being passed. But the element is greyed out.
To test it out, I tried just hard coding the file path:
<source src="../assets/tracks/5G.mp3">
And that works just fine:
But I don't want to do it like that because I have about 11 tracks to do, so I would like for it to load from the data being passed so that I can reuse the component. Any ideas?
try using something like this in your Vue v-for I use this when src is not loading on the img tag.
:src="getSrc(x.src)"
methods: {
getSrc(src) {
return require("../assets/" + src);
}
}
Your watch function on file prop is never triggered because your file name is static, it never triggers a change on the watcher, before mounting the component, at least in the code you provided it is that way.
From Vue.js API vm.$watch
Watch an expression or a computed function on the Vue instance for changes. The callback gets called with the new value and the old value.