Use dynamic image src as prop Vue - javascript

I am trying to send a dynamic src as prop to imageComponent, but i am doing it wrong. fileName = about.gsx$imagesrc.$t does not work. The images are stored in asset/Pictures and about.gsx$imagesrc.$t is the same value as the image name.
<template>
<div class="timeline">
<div class="timeline-content" v-for="about in state.aboutData" :key="about.index">
<div class="fill-circle">
<h2 class="timeline-year" > {{about.gsx$year.$t}}</h2>
</div>
<p class="timeline-text" > {{about.gsx$happening.$t}} </p>
<ImageComponent
//Filename is the problem
fileName= about.gsx$imagesrc.$t
leftPosition="200px"
activeColor="#132766"
/>
</div>
</div>
</template>
<script>
import { state } from '#/store/index.js'
import ImageComponent from "#/components/UI-kit/PictureModules/Sko.vue"
export default {
name:"Timeline",
components: {ImageComponent},
}
The Image component
<template>
<div class="ImageComponent" v-bind:style="{ left: leftPosition}">
<img class="image" :src="require(`#/assets/Pictures/${fileName}`)">
<div class="shadow" v-bind:style="{ backgroundColor: activeColor}"></div>
</div>
</template>
<script>
export default {
name:"ImageComponent",
props: {
activeColor: [String],
leftPosition: [String],
fileName: [String],
}
}
</script>
This is the error i get
Error in render: "Error: Cannot find module './about.gsx$imagesrc.$t'"

Related

Vue CLI: Project list with component

I'm completely new to VueJS and am trying to create a project tile list with different data values per tile. I use Vue CLI. I created a component which is my template for one project tile.
component TheProjectTile.vue :
<template>
<router-link to="{{ project.url }}">
<div
class="row project-container"
style="background-color: {{ project.backgroundcolor }};"
v-scrollanimation
>
<div class="column column-60">
<h2>{{ project.title }}</h2>
<div class="button">view</div>
</div>
<div class="column">
<img src="#/assets/img/{{ project.image }}" alt="{{ project.title }}" />
</div>
</div>
</router-link>
</template>
<script type="text/javascript">
export default {
props: { project: Object },
data() {
return {}
}
}
</script>
Then I have my View on my Vue CLI application where I want to render the project tiles and where I want to give the data to the tiles:
View where the projects should be shown
<template>
<div id="projekte">
<section class="container">
<div id="projects">
<projectlist v-for="project in projects" :project="project" />
</div>
</section>
</div>
</template>
<script>
import TheProjectTile from './components/TheProjectTile'
export default {
components: {
projectlist: TheProjectTile
},
data() {
return {
projects: [
{
url: '/projekte/client1',
backgroundcolor: '#005ca9',
title: 'Website client 1',
img: 'client1.png'
},
{
url: '/projekte/client2',
backgroundcolor: '#c10b25',
title: 'Website client 2',
img: 'client2.png'
}
]
}
}
}
</script>
What do I need to change that it works? :/
Please take a look at following snippet:
You need to bind data with v-bind or :,
in v-for loop you need key
Vue.component('projectList', {
template: `
<a :to="project.url">
<div
class="row project-container"
:style="{'background-color': project.backgroundcolor}"
>
<div class="column column-60">
<h2>{{ project.title }}</h2>
<div class="button">view</div>
</div>
<div class="column">
<img :src="'#/assets/img/'+project.image" :alt="project.title" />
</div>
</div>
</a>
`,
props: { project: Object },
})
new Vue({
el: '#demo',
data() {
return {
projects: [{url: '/projekte/client1', backgroundcolor: '#005ca9', title: 'Website client 1', img: 'client1.png'}, {url: '/projekte/client2', backgroundcolor: '#c10b25', title: 'Website client 2', img: 'client2.png'}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div id="projekte">
<section class="container">
<div id="projects">
<!-- 👇 key -->
<project-list v-for="(project, index) in projects" :key="index" :project="project" />
</div>
</section>
</div>
</div>

how to call URL in axios.post request for get data each id?

I'm fetching Data from an API using Axios and i'm displaying them as Cards in a Component movie cards, the thing is that i want to be able to click on a single movie card and the router take me to another page(singlepage.vue) with that movie id from the API and displaying the Book specific data but the problem is that I do not know how to send the ID of the same movie card I entered to the API and then return its data (I have to use the post method for request and put my post image below).
this is postman image. click here.
firstPage.vue
this is same component that i have movie cards.
<template>
<div class="articles">
<h2>featured articles</h2>
</div>
<div class="article-container">
<div class="article-grid" v-for="data3 in datas3" :key="data3.ContentID" >
<router-link to="/content" >
<img :src="data3.LandscapeImage">
<div class="article-title">
<p>{{data3.Properties[5].Value}}</p>
<h3>{{data3.Title}}</h3>
</div>
</router-link>
</div>
</div>
<div class="number-container">
<a class="previous" href="">« <span>previous</span></a>
1
2
3
4
...
10
<a class="next" href="#"> <span>next</span> »</a>
</div>
</template>
<script>
export default {
name : "ThirdSection",
props : ['datas3'],
}
</script>
singlepage.vue
this is same component i want show data each cart after i click on card.
<template>
<div class="content">
<div class="content-sidebar">
<SideBar />
</div>
<section class="main-content">
<div class="content-container">
<div class="content-img"> <img src="" alt=""></div>
<div class="content-text" >
<h2></h2>
<p></p>
</div>
</div>
</section>
</div>
</template>
<script>
import axios from 'axios'
import SideBar from '../../components/Sidebar.vue'
export default {
components :{
SideBar
},
//I have a problem here//
setup() {
const request = { RequestID : "16460"}
function getContent (){
axios.post('request url', request ,
{ headers : {
'Content-Type' : 'application/json',
}}
)
.then(function(response){
console.log(response);
})
}
getContent();
return {};
}
}
</script>
What you need is to create a route for the single page that has params in it, and parse them in the component to use them in the request.
See: https://router.vuejs.org/guide/essentials/passing-props.html
Register your routes with the desired component and specify a parameter:
{ path: '/user/:book_id', component: require("<singlepage.vue>"), props: true }
singlepage.vue:
<template>
<div class="content">
<div class="content-sidebar">
<SideBar />
</div>
<section class="main-content">
<div class="content-container">
<div class="content-img"> <img src="" alt=""></div>
<div class="content-text" >
<h2></h2>
<p></p>
</div>
</div>
</section>
</div>
</template>
<script>
import axios from 'axios'
import SideBar from '../../components/Sidebar.vue'
export default {
components :{
SideBar
},
props: ["book_id"],
//I have a problem here//
setup() {
const request = { RequestID : "16460"}
function getContent (){
axios.post('request url', request ,
{ headers : {
'Content-Type' : 'application/json',
}}
)
.then(function(response){
console.log(response);
})
}
getContent();
return {};
}
}
</script>

Vue.js Component doesn't appear when embedded in another component

I have a header, logo, menu, and menu item.
The menu item contains the text "This is a menu item", but vue is not processing and displaying it.
These are the components:
App.vue
<template>
<div id="app">
<mainHeader />
</div>
</template>
<script>
import mainHeader from './components/mainHeader.vue'
export default {
name: 'App',
components: {
mainHeader
}
}
</script>
<style>
html,body{
box-sizing: border-box;
margin:0px;
padding:0px;
}
#app{
background-color:gray;
}
</style>
./components/mainHeader.vue
<template>
<div id="main-header">
<logo />
<mainMenu />
</div>
</template>
<script>
import logo from "./logo.vue";
import mainMenu from "./mainMenu.vue";
export default
{
name: 'mainHeader',
components:
{
logo,
mainMenu,
}
}
</script>
./components/mainMenu.vue
<template>
<div id="main-menu">
<menuItem />
</div>
</template>
<script>
import menuItem from "./menuItem.vue";
export default
{
name: "mainMenu",
components:
[
menuItem
]
}
</script>
./components/menuItem.vue
<template>
<div class="menu-item">
This is a menu item
</div>
</template>
<script>
export default
{
name: "menuItem"
}
</script>
When I check the DOM, the menuItem is not being parsed into a div with the message:
<div id="app">
<div data-v-ea6a1e94="" id="main-header">
<div data-v-4b16403b="" data-v-ea6a1e94="" id="logo"></div>
<div data-v-d2968a70="" data-v-ea6a1e94="" id="main-menu">
<menuitem data-v-d2968a70=""></menuitem>
</div>
</div>
</div>
How can I get the component to work?
The components option has an object as a value :
components:{
menuItem
}
it's recommended to name the component using kebab-case:
name: "menu-item"
and the file name with CamelCase MenuItem
and import it like :
import MenuItem from "./MenuItem.vue";
then register it like :
components:{
MenuItem
}
finally use it like <menu-item ... />

How to trigger a method in Single File Component from another Single File Component VueJS

I have Three components I want to trigger the show() method that is located in overlay.vue component, from the about.vue component
I am a beginner so I wish if I found some help from you guys
first is overlay.vue
<template>
<div class="overlay"></div>
</template>
<script>
export default {
name: "overlay",
methods: {
show() {
document.querySelector(".overlay").style.display = "block";
}
}
};
</script>
second is about.vue
<template>
<section class="about">
<div class="container">
<div class="row video">
<div class="col-lg-6 order-lg-1 order-2">
<img
class="dots img-fluid"
src="../assets/images/dots.svg"
alt="dots"
/>
<div class="video-wrapper">
<div class="video-img">
<img
class="img-fluid"
src="../assets/images/video.png"
alt="#"
/>
</div>
<div class="video-i">
<!-- ***************************************************************
***** this is where i want to trigger the method using this below a tag*****
*************************************************** -->
<i class="fas fa-play"></i>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
The third which is the parent app.vue where I import about.vue and overlay.vue
<template>
<div id="app">
<overlay></overlay>
<about></about>
</div>
</template>
<script>
import overlay from "./components/overlay";
import about from "./components/about";
export default {
name: "App",
components: {
about,
overlay
}
};
</script>
You can do something like this, in your app.vue set a variable to show your overlay.vue or not. And then in the overlay.vue set a props that change the style of your component. This solution is not using a dom manipulation.
app.vue
<template>
<div id="app">
<overlay :show="show_overlay"></overlay>
<about></about>
</div>
</template>
<script>
import overlay from "./components/overlay";
import about from "./components/about";
export default {
name: "App",
data(){
return {
show_overlay:false
}
},
components: {
about,
overlay
}
};
</script>
overlay.vue
<template>
<div class="overlay" :style="[(this.show) ? 'display:block' : 'display:none']"></div>
</template>
<script>
export default {
name: "overlay",
props:{
show:{
default:false,
type:Boolean
}
}
};
</script>
because the two components are siblings and not imported in each other I coulden't use $ref and the best choice is to use Store
this is my store code
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
showOverlay: false
},
mutations: {
//showing the overlay
TOGGLE_OVERLAY(state, payload) {
state.showOverlay = payload;
}
},
actions: {
//showing the overlay
toggleOverlay(context, payload) {
context.commit("TOGGLE_OVERLAY", payload);
}
},
getters: {
getStatus: state => state.showOverlay
}
});
and here where i dispatch it. I dispatch it from about.vue or any other component as well
<a #click.prevent="toggleOverlay" href="#"><i class="fas fa-play"></i></a>
methods: {
toggleOverlay() {
this.$store.state.showOverlay = !this.$store.state.showOverlay;
this.$store.dispatch(
"toggleOverlay",
this.$store.state.showOverlay
);
}
}

Pass component as a property and respect its named slots in Vue.js

I want my container component to render contents based on child's slot names. Here's an example markup:
<div id="app">
<Container>
<component :is="childComponent"></component>
</Container>
</div>
<script>
import Container from './Container'
import someComponent from './someComponent'
export default {
components: {
Container,
someComponent
},
data() {
childComponent: 'someComponent'
}
}
</script>
// Container.vue
<template>
<div>
<header>
<slot name="head"></slot>
</header>
<div class="ContainerBody">
<slot name="body"></slot>
</div>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
// Some child component
<template>
<div>
<h1 slot="head">Child Title</h1>
<div slot="body" class="body"><div>Child Body</div></div>
<footer slot="footer">Child Footer</footer>
</div>
</template>
How do I make it that Vue respects slot names and renders child contents in accordingly named slots, so the result would look like this:
<div>
<header>
Child Title
</header>
<div class="ContainerBody">
<div>Child Body</div>
</div>
<footer>
Child Footer
</footer>
</div>
Right now it will only render my child component in an unnamed slot:
<slot></slot>
The idea is to render child component differently when it's loaded as a child of Container. I would like it to work with .Vue files and allow child components to still behave as usual when they're not a child of a container.
I don't think you can do exactly what you want because each component has to have a single root element, which precludes it being plugged in as three separate slots.
What I was able to do was to turn the problem inside-out, making the top-level component the childComponent and having it take a container prop which it uses to set the :is of its root element.
// "importing" async component definitions
const vueContainerComponent = () => new Promise((resolve) => resolve({
template: '#container-template'
}));
const vueChildComponent = () => new Promise((resolve) => resolve({
template: '#child-template',
props: ['container']
}));
new Vue({
el: '#app',
components: {
someComponent:() => vueChildComponent().then((spec) => ({
extends: spec,
components: {
Container: vueContainerComponent
}
}))
},
data: {
container: 'Container',
childComponent: 'someComponent'
}
});
header {
background-color: lightgray;
}
footer {
background-color: darkslategray;
color: white;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<component :is="childComponent" :container="container"></component>
</div>
<template id="container-template">
<div>
<header>
<slot name="head"></slot>
</header>
<div class="ContainerBody">
<slot name="body"></slot>
</div>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<template id="child-template">
<div :is="container">
<h1 slot="head">Child Title</h1>
<div slot="body" class="body"><div>Child Body</div></div>
<footer slot="footer">Child Footer</footer>
</div>
</template>

Categories

Resources