img src didnt show in vue - vue.js

So I here my code, I create a component and its got a slot inside it, I want to passing the image url into <img /> with v-bind:src but the image didn't showed up on the docs, nor there is no error in console.
<MyComp v-if="myData.length">
<template #img>
<div class="my-slot">
<img :src="myData.image"/>
</div>
</template>
</MyComp>
data () {
return {
myData: [
{
image: "https://www...."
},
{
image: "https://www...."
},
{
image: "https://www...."
}
}
}
Wondering did I miss something? I couldn't use new URL or require too. The static url on tag also didnt work.

In your case you need to use scoped-slot. Pass myData as prop in your parent component and use scoped-slot to pass url in :src
Example:
<template>
<MyComp v-if="myData.length" :images="myData">
<template #img="{ image }">
<div class="my-slot">
<img :src="image"/>
</div>
</template>
</MyComp>
</template>
<script>
export default {
data () {
return {
myData: [
{
image: 'https://www....',
},
{
image: 'https://www....',
},
{
image: 'https://www....',
},
],
}
},
}
</script>

It's because your myData variable is an array of objects, and you're referring to it as if it was simply an object:
<img :src="myData.image"/>
You should reference particular element of the array:
<img :src="myData[0].image"/>

<MyComp v-if="myData.length">
<template #img>
<div class="my-slot">
<img :src="myData.image" />
</div>
</template>
</MyComp>
<script>
export default {
data() {
return {
myData: [
{
image: "https://www...."
},
{
image: "https://www...."
},
{
image: "https://www...."
}
]
};
}
};
</script>

Related

wrap template component with his name

I have components and I would like every component template wrapped inside a div with his name.
Vue.component('search', {
template: '<div>component template</div>'
html result
<div class="component-search">
<div>component template</div>
</div>
I can't imagine why you would want to be do that but anyhow you could do the following
Vue.component('search', {
name: 'search',
template: `<div :class="wrapperClass">
<div>component template</div>
</div>`,
computed: {
componentName() {
return this.$options.name
},
wrapperClass() {
return `component-${this.componentName}`
},
}
})

Can I pass props to a child component and use the data in the parent component in Vue

I would like to pass data to a child component and render that same data in the parent components. Also I would like to use the data in a function and not simply render it in the child. When I pass the props in this example it no longer renders the tags with the data
<template>
<div class="hello">
<div v-for="(section, index) in sections" :key="index">
<p>{{section.name}}</p>
<p>{{section.type}}</p>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
sections: [
{
name: "scoop",
type: "boulder"
},
{
name: "pew pew",
type: "roped"
}
]
};
},
props: ["sections"]
};
</script>
You can't use the same word/property name (sections in your case) for data and props.
I assume your code is the parent component:
// parent.vue
<template>
<div class="hello">
<div v-for="(section, index) in sections" :key="index">
<p>{{section.name}}</p>
<p>{{section.type}}</p>
</div>
<my-child-component :sections="sections" />
</div>
</template>
<script>
import MyChildComponent from '~/components/MyChildComponent.vue'
export default {
name: "HelloWorld",
components: {
MyChildComponent
},
data() {
return {
sections: [
{
name: "scoop",
type: "boulder"
},
{
name: "pew pew",
type: "roped"
}
]
}
},
methods: {
consoleSections() {
console.log(this.sections) // the way to use data in function
}
}
}
</script>
// MyChildComponent.vue
<template>
<div class="hello">
<div v-for="(section, index) in sections" :key="index">
<p>{{section.name}}</p>
<p>{{section.type}}</p>
</div>
</div>
</template>
<script>
export default {
name: "ChildHelloWorld",
props: ['sections'],
methods: {
consoleSections() {
console.log(this.sections) // the way to use data in child
}
}
}
</script>
Take a look in the vue guide about component: https://v2.vuejs.org/v2/guide/components.html

How to make a function from another brother component be called when pressed?

Good afternoon, tell me please, I wrote a calendar displaying the events that the user sets, and now I want to make a detailed display of the event when I click it. The problem is that the events are in my component and the whole display logic is in another, how can I use them together.I want to make it so that the getDetailInformation() function in the ModalWindowDetail component component is called by clicking on an event in another component Calendar.vue. I use the event bus, but nothing works for me, I don’t understand why. Please help me solve this problem.
Screenshot of Calendar and error in console
Code of Calendar on GitHub
App.vue:
<template>
<div class="all">
<app-calendar #sendTextEvent="text = $event"></app-calendar>
<app-detail v-if="modalWindowDetail"
:eventText="text"></app-detail>
</div>
</template>
<script>
import appCalendar from './components/Calendar.vue'
import appDetail from './components/ModalWindowDetail.vue'
export default {
data(){
return{
text: String
}
},
components: {
appCalendar,
appDetail
},
computed: {
modalWindowDetail() {
return this.$store.state.modalWindowDetail;
}
}
};
</script>
Calendar.vue component which display calendar:
<template>
<div class="overflow-div">
<transition :name="nameOfClass" >
<div :key="currentPage" class="fade_wrapper">
<div v-for="(week, i) in getCalendar" class="d_day">
<li v-for="day in week" class="li_day">
<div class="day">{{ day }}</div>
<div v-for="event in buildEvents(i, day)"
class="event"
v-bind:class="{ 'eventBrown': eventBrown(event),
'eventPurple': eventPurple(event),
'eventOrange': eventOrange(event),
'eventBlue': eventBlue(event) }"
v-on:click="openModalDetail(event)">{{ event }}
</div>
</li>
</div>
</div>
</transition>
</div>
</template>
<script>
import json from './Calendar_data.json'
import { mapState } from "vuex";
import { eventBus } from './../main.js'
export default {
mounted(){
eventBus.$on('getDetailInformation', this.openModalDetail())
},
computed: {
modalWindowDetail() {
return this.$store.state.modalWindowDetail;
},
},
methods: {
openModalDetail(text){
this.$emit('sendTextEvent', text);
}
};
</script>
The component in which the getDetailInformation() is located ModalWindowDetail.vue:
<template>
<div class="underModalWindow">
<div class="modalWindow">
<img src="src/assets/x.png" width="20px" height="20px">
<div class="nameofModal">Вся детальная информация о событии</div>
<div v-for="(key, name) in eventDetail" class="detailEvent">{{ name }}: {{ key }}</div>
<button>Окей</button>
</div>
</div>
</template>
<script>
import { eventBus } from './../main.js'
export default {
props: ['eventText'],
data(){
return{
options: [
{ text: 'Встреча', value: '8' },
{ text: 'День Рождения', value: '4' },
{ text: 'Праздник', value: '1' },
{ text: 'Другое', value: '16' }
],
eventDetail: Object,
}
},
computed: {
eventsData() {
return this.$store.state.eventData;
},
modalWindowDetail() {
return this.$store.state.modalWindowDetail;
},
},
created(){
eventBus.$emit('getDetailInformation', this.getDetailInformation())
},
methods: {
getDetailInformation(){
let arrOfEvents = this.eventsData.events;
for(let z = 0; z < arrOfEvents.length; z++){
let memo = arrOfEvents[z].memo;
console.log(this.memo)
if(memo === this.eventText){
let dataStartOfEvent = arrOfEvents[z].starts_at;
let getStartDataOfEvent = new Date(dataStartOfEvent);
let dataEndOfEvent = arrOfEvents[z].ends_at;
let getEndDataOfEvent = new Date(dataEndOfEvent);
if((getStartDataOfEvent.getHours() - 3) > 0){
this.$store.commit('changeModalWindowDetail', this.modalWindowDetail);
this.eventDetail = {
'Событие': this.eventText,
'Начало события': getStartDataOfEvent.toLocaleTimeString(),
'Конец события': getEndDataOfEvent.toLocaleTimeString(),
'Тип события': this.getType(arrOfEvents[z].type)
}
}else if(getStartDataOfEvent.getDate() != getEndDataOfEvent.getDate()){
this.$store.commit('changeModalWindowDetail', this.modalWindowDetail);
this.eventDetail = {
'Событие': this.eventText,
'Начало события': getStartDataOfEvent.toLocaleDateString(),
'Конец события': getEndDataOfEvent.toLocaleDateString(),
'Тип События': this.getType(arrOfEvents[z].type)
}
}
}
}
}
}
};
</script>
You should remove the () from the function name in eventBus.$on('getDetailInformation', this.openModalDetail()) - you want to reference the function, not to call it and use the result as a reference.
Also, your function getDetailInformation() does not return anything - but you seem to expect that it returns a text. You should correct this.
And finally, I think that #sendTextEvent="text = arguments[0]" would be more appropriate - and using a dedicated method/function will be the best.

Pass data to vue component

i'm learning Vue.js right now, but i have a little problem on understanding a quite easy task ( maybe my idea of programming is too old ).
i've created a little component with this code.
<template>
<div class="tabSelectorRoot">
<ul>
<li v-for="(element,index) in elements" v-on:click="changeSelected(index)">
<a :class="{ 'selected': activeIndex === index }" :data-value="element.value"> {{ element.text }}</a>
</li>
</ul>
<div class="indicator"></div>
</div>
</template>
<script>
export default {
name: "TabSelectorComponent",
data () {
return {
activeIndex : 0,
elements: [
{ 'text':'Images', 'value': 'immagini','selected':true},
{ 'text':'WallArts', 'value': 'wallart'}
]
}
},
created: function () {
},
methods: {
'changeSelected' : function( index,evt) {
if ( index == this.activeIndex) { return; }
this.activeIndex = index;
document.querySelector('.indicator').style.left= 90 * index +'px';
this.$emit('tabSelector:nameChanged',)
}
}
}
</script>
and this is the root
<template>
<div id="app">
<tab-selector-component></tab-selector-component>
</div>
</template>
<script>
import TabSelectorComponent from "./TabSelectorComponent";
export default {
name: 'app',
components: {TabSelectorComponent},
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
'mounted' : function() {
console.log(this)
//EventManager.eventify(this,window.eventManager);
/*this.register('tabSelector:changeValue',function(el){
console.log(el);
});*/
}
}
</script>
All of this renders in something like this
I'd like to reuse the component by varying the number of objects inside the list but i cannot understand how to accomplish this simple task
The basic way to communicate between components in Vue is using properties and events. In your case, what you would want to do is add an elements property to your TabSelectorComponent that is set by the parent.
TabSelectorComponent
export default {
name: "TabSelectorComponent",
props: ["elements"],
data () {
return {
activeIndex : 0
}
},
...
}
In your parent:
<tab-selector-component :elements="elementArray"></tab-selector-component>
This is covered in the documentation here.

how to hide sidebar in vue

guys, I m new to Vue and taken a coreui admin panel to develop some font vue but now I got stuck in this problem this is nav.js file
export default {
items: [
{
name: 'Product',
url: '/product',
icon: 'fa fa-cart-arrow-down',
children: [
{
name: 'Addproduct',
url: '/product/Addproduct',
},
{
name: 'Listproduct',
url: '/product/Listproduct',
}
]
},
]
}
main container
<template>
<div class="app">
<div class="app-body">
<Sidebar :navItems="nav"/>
<main class="main">
<div class="container-fluid">
<router-view></router-view>
</div>
</main>
<AppAside/>
</div>
</div>
</template>
<script>
import nav from '../_nav'
export default {
name: 'full',
components: {
Sidebar,
},
data () {
return {
nav: nav.items
}
},
computed: {
name () {
return this.$route.name
},
list () {
return this.$route.matched
}
}
}
</script>
here is my sidebar
<template v-for="(item, index) in navItems">
<template v-if="item.title">
<SidebarNavTitle :name="item.name" :classes="item.class" :wrapper="item.wrapper"/>
</template>
<template v-else>
<template v-if="item.children">
</template>
<template v-else>
<SidebarNavItem :classes="item.class">
<SidebarNavLink :name="item.name" :url="item.url" :icon="item.icon" :badge="item.badge" :variant="item.variant"/>
</SidebarNavItem>
</template>
</template>
</template>
i m stroing addproduct in my browser local storage now if when user login and go to dashboard then my i watch which url name is present in browser application or not if present show that else ignore now my problem is that how i can apply if condition like addproduct=addprodcut this this visible else hide
You could have a method in mounted hook, which can fetch data from localstorage and check if it's present in the url or not. Then assign it to a variable in main component which toggles the sidebar. Something like below should work:
<template>
<div class="app">
<div class="app-body">
<Sidebar :navItems="nav" v-if="showSidebar" />
<main class="main">
<div class="container-fluid">
<router-view></router-view>
</div>
</main>
<AppAside/>
</div>
</div>
</template>
<script>
import nav from '../_nav'
export default {
name: 'full',
components: {
Sidebar,
},
data () {
return {
nav: nav.items,
showSidebar: false
}
},
mounted () {
this.checkSidebarVisibility()
},
methods: {
checkSidebarVisibility: function() {
const inLocal = window.localStorage.getItems('your_item');
const inUrl = window.location.toString();
// check if inurl inside inLocal
if (inUrl is in inLocal) {
this.showSidebar = true;
} else {
this.showSidebar = false;
}
}
},
computed: {
name () {
return this.$route.name
},
list () {
return this.$route.matched
}
}
}
</script>