talents. I want to create beautiful button for vue. But I have a problem. I want to pass class attribute to child from parent component easily.
Parent component is like this:
<!-- parent component -->
<template>
<custom-element class="wanted-class">
<span slot="custom-body">
Some Effects or text
</span>
</custom-element>
</template>
and "custom-element" component is
<template>
<div id="custom-element">
Some elements or text
<slot name="custom-body">
Some default text
</slot>
</div>
</template>
<script>
export defatult{ ...
I really want the root element in child ( $("#custom-element") for jQuery expression) to have "wanted-class" from parent. Is it possible? or it's too easy?
Related
[Lang.vue]
<Core ref="core">
<template v-slot:passageOne>
<p>This is passage One Content!</p>
</template>
<template v-slot:video>
<myVideo ref="video"></myVideo> <!--For Q2-->
</template>
</Core>
[Core.vue]
<div>
<slot name="passageOne"></slot>
<slot name="video">GG</slot> <!--The fallback text is GG-->
</div>
*myVideo is a self developed component
Q1: Is it possible to inject a custom component (myVideo in this case) into Core component's second slot? In my case, the fallback text "GG" is shown which meaning that inject unsuccessfully, but why?
Q2: If it is possible for Q1, is it possible to get reference object for myVideo component (the line commented with 'For Q2') in Lang.vue scope(Parent)?
Please provide an use case if possible. Thanks!
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/
I have an external div that I need to render inside my Vue app. I'm trying to use a slot, like but that's a no go as nothing renders.
Any ideas?
Goal is to have HTML like this (Vue mounts on #app):
<div id="app" data-slot-header="#header"></div>
<div id="header">
<h1>Title here</h1>
</div>
Then the Vue component
<template>
<div>
<slot name="header"></slot>
</div>
</template>
You can use a dynamic <component> and refer to your #header element as a template reference.
For example
new Vue({
data: () => ({
headerComponent: {
template: '#header' // refer to template element by selector
}
}),
}).$mount('#app')
#app:before,#header:before{position:absolute;top:0;right:0;color:rgba(1,1,1,.5);font-size:.8rem}#app{border:1px solid #666;position:relative}#app:before{content:'Vue app'}#header{position:relative;opacity:.5}#header:before{content:'Original header'}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app">
<p>Dynamic component rendered here 👇</p>
<component :is="headerComponent"></component>
</div>
<div id="header">
<h1>Title here</h1>
</div>
Slots are mainly used with reusable Vue components so that the parent component can render custom stuff inside designated sections of the child. The root component does not have a parent, so it doesn't make sense to use slots for this.
Why can't you just hard-code the div in the template? Or do you need it to be dynamic; will you be swapping out the header contents in some situations? Please provide more information about what your use-case is, otherwise my answer is "just hard-code it".
Take a look at portal-vue. It allows child components to render templates anywhere in the DOM. This might work for your situation.
The image I use below are svg component loaded with vue-svg-loader (see app.vue)
I have 2 components parent and child.
The parent use the child and display an image from the child with a text.
The child can be used without the parent and only display an image.
Both use a named slot to display the image, the issue is I want to pass a named slot from the parent component to the child one, but seems like to not work the way I want with vuejs named slot and start to be very confusing, is there another way to solve this issue ?
Parent.vue
<template>
<child>
<label>Text with image</label>
<slot name="img">
</child>
<template>
Child.vue
<template>
<slot name="img">
<template>
App.vue
<template>
<parent>
<mySvg slot="img"/>
</parent>
<template>
<script>
import mySvg from 'pathToSvg';
export default {
components: {
mySvg,
}
}
</script>
Try this for the Parent component
<template>
<child>
<label>Text with image</label>
<slot slot="img" name="img">
</child>
<template>
Let's say I'm developing an enhanced popper.js for Vue and I'm about to give it some additional functionality. This is how the very (child) component looks like:
<popper>
<div :is="tag" class="popper">
{{ content }}
</div>
<button class="btn btn-primary" slot="reference">
Reference Element
</button>
</popper>
As you can see, for it to work it requires defining reference element right beneath the ".popper" div with a slot="reference" attribute.
Question:
How to turn my enhanced-popper component into a re-usable entity, aka be able to pass slotted data indirectly - from
<enhanced-popper> //referenced element// </enhanced-popper> so that it has the slot="reference" attribute inside the child (popper.js-based) component?
What did not work:
Employing slots and having the attribute in a component passed in by the parent component does not yield desired results, as it does not get rendered at all.
<popper>
<div :is="tag" class="popper">
{{ content }}
</div>
<slot></slot>
</popper>
To ensure having the attribute out there I also tried to replace said button in the child component with a named slot inside a slot and go like this in my enhanced-popper:
<slot name="reference">
<slot></slot>
</slot>
That way the first slotted component has the attribute - and it almost works, but since there are two "slot-layers" (no idea how to call it), the referenced component is not the first one as a child, and popper gets mis-positioned.
Cheers,
Paco