I have a vue component Jumbotron.vue:
<template lang="html">
<div class="jumbotron" style="border-radius:0px; color:#fff;">
<div class="container">
</div>
</div>
</template>
And other page component Main.vue:
<template>
<div class="root">
<navbar></navbar>
<jumbotron>
<h1 class="display-4">I want to add here, to the jumbotron's div container some h1 and paragraph</h1>
<p class="lead ">Like this paragraph</p>
</jumbotron>
<words></words>
</div>
</template>
But i cant add content to the jumbotron, because its wrong. I dont want to add content(p and h1) inside of the Jumbotron.vue, because i want to use Jumbotron.vue more than 1 time with different content inside it. Is this possible?
This is done with slots.
<template lang="html">
<div class="jumbotron" style="border-radius:0px; color:#fff;">
<div class="container">
<slot></slot>
</div>
</div>
</template>
Everything you put inside the jumbotron component in the parent will be rendered in the slot.
Related
I'm trying to get a v-for cycle with background images. My intention is to have for columns each containing a different background image. Is there something wrong here? :(
Please note also photos it's an array imported with props. This is a component template.
<template>
<div class="row">
<div
v-for="photo in photos"
:key="photo"
class="col-3"
style="background-image: url({{photo.url}})"
>
Need to see photo here
</div>
</div>
</template>
<script>
export default {
props: ["photos"],
};
</script>
I'd use template literals with the :style shorthand for v-bind:style
<template>
<div class="row">
<div
v-for="(photo, index) in photos"
:key="index"
class="col-3"
:style="`background-image: url(${photo.url})`"
>
Need to see photo here
</div>
</div>
</template>
Refer to Binding Inline Styles
<div
v-for="photo in photos"
:key="photo"
class="col-3"
v-bind:style="{background-image: 'url(' + photo.url + ')'}"
>
Need to see photo here
</div>
I made a view to show some contact information for the user:
<template>
<div v-for="user in users" class="user">
<div class="userInformation">
<img :src="user.photo" />
<div class="userName">
<h3>{{ user.age }}</h3>
<p>{{ user.gender }}</p>
</div>
</div>
<div class="button-wrapper">
<a href="#">
<button #click="$router.push(`/user/${user.id}`)">User Profile</button>
</a>
</div>
</div>
</template>
<style>
</style>
users is an array that holds all users which I fetch from the backend.
I want to create a component so that I can re-use the user card in other classes and don´t have to include the markup. I tried it the following way but I'm stuck at the button to redirect the user and the img because I don´t know how to use named slots there.
<template>
<div class="user">
<div class="userInformation">
<img />
<div class="userName">
<h3>{{ age }}</h3>
<p>{{ gender }}</p>
</div>
</div>
<div class="button-wrapper">
<a href="#">
<button>User Profile</button>
</a>
</div>
</div>
</template>
<script>
export default {
name: "UserCard",
props: [
"age",
"gender"
]
};
</script>
Another problem is that I have to re-create the fetch method for my users in other classes to access the user information. Would there be a better way of doing this?
// fetch user data from backend and create users array
...
<div v-for="user in users" :key="user.name">
<UserCard
:age="`${user.age}`"
:gender="`${user.gender}`"
/>
</div>
Is this the right approach to create a reusable component?
You're headed in the right direction for your component. If you wanted a named slot for the button you could use something like this.
Child Component
<template>
...
<slot name="button">
<!-- default/fallback content can be provided, if the parent does
not provide slot content the button-wrapper div will appear -->
<div class="button-wrapper">
<a href="#">
<button>Default Button</button>
</a>
</div>
</slot>
</div>
</template>
Parent
<div v-for="user in users" :key="user.name">
<UserCard
:age="user.age"
:gender="user.gender">
<template v-slot:button>
<div>some custom button here {{ user.phone }}</div>
</template>
</UserCard>
</div>
Also compilation scope (Vuejs v2 guide) is an important thing to keep in mind with slots - "Everything in the parent template is compiled in parent scope; everything in the child template is compiled in the child scope."
In terms of fetching your users, that's a separate issue. Look into something like Vuex or other ways of managing shared state if you find yourself constantly having to fetch users in various components
suppose we have a component like this.
<template>
<div class=" ">
<div class="flex-grow">{{title}}</div>
<div class=" p-5">
<!-- want to show here -->
</div>
</div>
<script>
export default {
props: ['title'],
mounted() {
console.log('Component mounted.')
}
}
</script>
i try this
<comp :title="'here'">
<h1> this is </h1>
</comp>
i want to show html b.w vue component tag, like we do in react.
how we can achieve this
If I understand the question, you're looking to create a component that can accept child elements. In order to do this, use <slot></slot> in your template where you'd like child elements to be inserted. Child elements can be other components or HTML.
See the reference for more thorough details.
In your example:
<template>
<div class=" ">
<div class="flex-grow">{{title}}</div>
<div class=" p-5">
<slot></slot>
</div>
</div>
</template>
I have a html structure like this:
<template>
<div>
<div class="container">
<somecontent>
<someothercontent>
</div>
</div>
</template>
However, depending on the layout, I want to remove the container div so the structure looks like this:
<template>
<div>
<somecontent>
<someothercontent>
</div>
</template>
Note that the div is completely added or removed, not just the class name. v-if doesn't work here because it would also show or hide the content that is enclosed by the div. What's the simplest solution for that?
You can use
v-if ... v-else
<template>
<div v-if="condition">
<div class="container">
<somecontent>
<someothercontent>
</div>
</div>
<div v-else>
<somecontent>
<someothercontent>
</div>
</template>
I have two templates on components and one flag.
<template v-if="mainPage">
<div class="col-md-12">
<h1>1 page</h1>
</div>
</template>
<template v-else>
<div class="col-md-12">
<h1>2 page</h1>
</div>
</template>
export default {
data () {
return {
text : '',
mainPage: true,
}
},
but default include second template. why?
First of all, when creating a vuejs you are only allowed one root element per component, so without the v-else part your component wouldnt work, unless you change template to div, and create one parent template:
If you don't want to use v-if you can just use v-show as:
<template v-show="mainPage">
<div class="col-md-12">
<h1>1 page</h1>
</div>
</template>
<template>
<div class="col-md-12">
<h1>2 page</h1>
</div>
</template>
This will not work for templates though. Because you can not have two templates in vuejs components