How to pass class attribute to child from parent in vue? - javascript

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

Inject a custom component into a named slot in child

[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!

Nuxtjs: How to call component inside another component?

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/

Render external element inside Vue component

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.

Vue - Passing slot to child component

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>

Is there a way to 'pipe-together' slots in nested components in Vue?

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

Categories