Good evening!
I'm trying to create a page in Vue, parsing it into components, and rendering content using json. And it seems to be nothing complicated, but there is a problem.
But why is the href parameter in the wrong place? Please tell me, I have been unable to solve this riddle for several hours.
index.vue
<template>
<section>
<Hero
v-for="(hero, index) in heroes"
:title="hero.title"
:description="hero.description"
:more="hero.more"
:href="hero.href"
:key="index"
/>
</section>
</template>
Hero.vue
<template>
<div>
<h2>{{ title }}</h2>
<p>{{ description }}</p>
<a :href="href">{{ more }}</a>
</div>
</template>
<script>
Result
<section>
<div href="/create">
<h2>Create and share your photo stories.</h2>
<p>
Photosnap is a platform for photographers and visual storytellers. We make
it easy to share photos, tell stories and connect with others.
</p>
<a>Get an Invite </a>
</div>
...
</section>
You probably forgot to define href as a prop in your Hero component.
Make sure you have added href as prop in your Hero component.
props: {
href: {
type: String,
required: true
}
}
Related
Usually in vue 2, you render a component that doesn't close on route change, you include it directly in your app.vu file. How do I achieve this in nuxt 2.
I am trying to implement a chat module and don't want to include the component on every instance it is needed (That will mean new socket connection on every route)
Is there a workaround?
Put that in your default layout, it should be enough.
More info here: https://nuxtjs.org/docs/concepts/views/#default-layout
Something like this in /layouts/default.vue
<template>
<div>
<nav>
<ul>
<li>
<NuxtLink to="/">Home</NuxtLink>
</li>
<li>
<NuxtLink to="/parent">Parent</NuxtLink>
</li>
</ul>
</nav>
<main>
<img src="~/assets/logo.svg" />
<Nuxt />
</main>
</div>
</template>
And a simple page should do it
<template>
<div>
<h1>Hello Nuxters! 👋</h1>
</div>
</template>
No need to define a specific layout here since default is the one used by default.
Codesandbox example available here: https://nuxtjs.org/examples/routing/nested-pages
Otherwise, you could indeed have your content nested inside of a main parent wrapper.
I understand paradigm "Page-component" but what if I have a page that renders component, how do I call another component inside this component? Currently nuxtjs does not allow me do it. I can not stick to standart "page-component" scheme as I am bulding cart which calls cart-items.
Say If a cart component which is called by page looks like this, how would it call cart-item component inside it?
<!---- cart component called from index.vue --->
<template>
<div>
<Cart-item></Cart-item> < ---------- This doesn't work.
</div>
</template>
<script>
export default {
props: ['items']
}
</script>
I managed it the standard way:
<template>
<div>
<CartItem></CartItem>
</div>
</template>
<script>
import CartItem from '../components/Cart-item'
export default {
props: ['items']
}
</script>
Since nuxtjs auto-registers all components wonder if there is more graceful way.
EDIT: as promised, here is an example on how to pass some content to a component from another one thanks to slots. This is totally working in any Nuxt page ofc.
NestedContent.vue
<template>
<div>
<p>Here is the NestedContent component and below is a slot passed to ParentWithSlots' component</p>
<hr />
<parent-with-slots>
<!-- <template #default> // this one can be omit since we do use the default slot here -->
<p>This content is inserted into the component ParentWithSlots</p>
<!-- </template> -->
</parent-with-slots>
</div>
</template>
ParentWithSlots.vue
<template>
<div>
<p>xxxxxxxxxxx ParentWithSlots' content before slot xxxxxxxxxxx</p>
<slot>Default content in case none is provided</slot>
<p>xxxxxxxxxxx ParentWithSlots' content after slot xxxxxxxxxxx</p>
</div>
</template>
Here is how it looks
PS: you may also give a try to layouts, it can be useful for overall positioning of some of your components visually.
If your components are in the components directory, you can set components: true in your nuxt.config.js and have access to it pretty much anywhere without any additional step with the <cart-item></cart-item> syntax.
More details here: https://nuxtjs.org/blog/improve-your-developer-experience-with-nuxt-components/
If I have a layout component that contains a few slots, is it possible to have a component within layout populate those slots?
JS Fiddle
<div id="app">
<layout>
<page></page>
</layout>
</div>
const app = Vue.createApp({});
app.component('layout', {
template: `
<header>
<slot name="header"></slot>
</header>
<main>
<slot name="main"></slot>
</main>
`,
});
app.component('page', {
template: `
<!--
is there a way fill each slot of "layout"? i.e.
<template #header>
<h1>Page Header</h1>
</template>
<template #main>
<h1>Page Content</h1>
</template>
-->
`,
});
app.mount('#app');
It seems what I'm looking for is being referred to as template blocks in other places. This is not something Evan You (the creator of Vue) currently supports as he doesn't believe this functionality adds enough value for the added complexity.
Some interesting links:
Template blocks for component inheritence (proposed syntax)
Possible upcoming third-party package to achieve this
Example of using Pug with it's concepts of block and extends
My Question
I have a Vue component that renders content like so:
<template>
<div class="item">
<h1>{{ title }}</h1>
<p>{{ contents }}</p>
<!-- Lot's of other stuff... -->
</div>
</template>
<script>
// export default...
</script>
<style lang="scss">
// style...
</style>
Note the contents within the div...
In some circumstances, I need to change <div class="item"> to <a class="item">. With that in mind, is there a way to conditionally change the tag (e.g. a, div) for the root element of a Vue component?
Research
I have searched around online and was able to find something about using the render function like so:
render (createElement) {
return createElement(this.tag, {}, this.$slots.default);
}
The issue I have with the above is that it implies that I need two separate components, for example; Item.vue and ItemTag.vue. Surely there is a way to do this with one component?
I believe you could use is:
<div :is="useA ? 'a' : 'div'">
...
</div>
This isn't quite what the docs suggests it's for but it does seem to have the desired effect.
https://v2.vuejs.org/v2/api/#is
Using a render function instead wouldn't necessarily require you to have two components but it would need you to rewrite your entire template as a render function.
I am building app using laravel and vue. I have navbar, currently it looks like:
<template>
<nav class="navbar">
<p>{{msg}}</p>
</nav>
</template>
And I use it like here:
<body class="">
<div id="app">
<div class="">
<navbar></navbar>
#yield('content')
</div>
</div>
</body>
In yield I am loading another components, so I have navbar and another component together. Now I want to override that {{msg}} variable from navbar in another components. In every component that variable will be diferent.
I do not know how to override it in components and from {{msg}} do some text. Can you help me? (That code above is all what I have)
If you want to use msg in other components, then you need to use prop
Use like:
props: ['msg'],
Then, you need to bind it like:
<component-name :msg="msg"></component-name>
In your component, you can take it like:
<template>{{ msg }}</template>
Hope you understand!
Components can be communicate with props. You can transfer the data to another components and you can use if statement.
https://v2.vuejs.org/v2/guide/components.html#Props