How to pass an instantiated Vue component as a prop in Vue.js? - vue.js

I want to pass an instantiated Vue Component as a prop to antoher component and then render it, like so:
<Button :icon=<IconComponent size="25" /> :link="http://wikipedia.org">Click here to visit Wikipedia</Button>
This is at least how I would do this in React. How can I achieve the same with Vue?

You need to use named slots in the child component :
<template>
<button>
<slot name="icon"></slot>
<slot></slot>
</button>
</template>
in parent component:
<Button link="http://wikipedia.org">
<template #icon>
<IconComponent size="25" />
</template>
Click here to visit Wikipedia</Button>

Related

Vue - Component that accepts a nested component

I would like to have a component that can have another component placed into it. I'm struggling to find how this can be achieved.
If I pass a component in it doesn't get displayed. I'm assuming I need to specify it in the component however I can't find how in the documentation.
E.g.
<component-that-allows-nesting>
<nested-component/>
</component-that-allows-nesting>
What needs to be added to my component to allow it to accept a nested component?
Vuejs support nested component like Base Component and you can use it. if you want send data from parent component to child component you can use props.
for example
//parent-component
<form>
<base-input />
<base-button>
add form
</base-button>
</form>
//child-component
//BaseInput.vue
<input type="text" placeholder="userName" />
//BaseButton.vue
<button #click="submitForm" >
<slot></slot>
</button>
Here is an example for vue3 carousel.
You should import nested component
You should add this component in components
Use it as nested component
<template>
<carousel :items-to-show="1.5">
<slide v-for="slide in 10" :key="slide">
{{ slide }}
</slide>
</carousel>
</template>
<script>
import { Carousel, Slide } from 'vue3-carousel';
export default {
name: 'App',
components: {
Carousel,
Slide,
},
};
</script>

Slot and referring template in the same component in parent

I am stuck with a problem in vue 2. Basically I have a parent and child component. Basically I want to do something like this.
Parent.vue:
<template>
<div>
<Child>
<template #MyComponent>
<slot name="MyComponent" />
</template>
</Child>
<template #MyComponent>
<MyComponent/>
</template>
</div>
</template>
Child.vue:
<template>
<slot name="myComponent"/>
</template>
Can this be done in vue? I have tried to do this. But it doesn't refer to the MyComponent
Thanks in advance.
This is not, how the structure of slots work. You are calling <template #MyComponent> outside of your <Child> and trying to do something there, that is hard to understand.
I´ll asume you try to pass a component named MyComponent inside of the slot of another component named Child. This is a small example for this case:
// Parent, where you call your Child with myComponent in the slot
<Child>
<template #mySlot>
<my-component></my-component>
</template>
</Child>
// Child
<template>
<div>
<slot name="mySlot"></slot>
</div>
</template>
// myComponent
<template>
<div>
Text from myComponent.vue
</div>
</template>

How to access or pass props to child slot in vue

If you have this component hierarchy, is it possible to pass or access isPanelClickable from ComponentPanel in ComponentSomething?
<ComponentA>
<ComponentPanel :isPanelClickable="false">
<ComponentSomething />
</ComponentPanel>
</ComponentA>
ComponentPanel:
<template>
<div class="panel">
<slot /> <!-- Can I "use" 'isPanelClickable' here somehow..? -->
</div>
</template>
This is possible through scoped slots. ComponentPanel could pass a prop to the default slot by binding the prop (e.g., named myProp) on the corresponding <slot> element:
<template>
<slot :myProp="isPanelClickable ? 'I am clickable' : 'I do nothing'" />
</template>
That prop is then passed through the v-slot in the default slot:
<ComponentPanel>
<template v-slot="{ myProp }">
<ComponentSomething :foo="myProp" />
</template>
</ComponentPanel>
demo

Register multiple Vue components in parent component

I have a global sidebar component TheSidebar.vue:
<template>
<aside>
<slot></slot>
</aside>
</template>
In Blogs.vue (a page component) I try to register two components.
<template>
<div>
<h1>Experiences</h1>
<TheSidebar>
<SearchBlog />
<CategoryCheckboxFilter />
</TheSidebar>
<ExperienceList />
</div>
</template>
It seems like I cannot register two components in a slot?
Is this a good setup anyway and who do I have to achieve this?
Update
It's just working fine now and I can register more than one component in a <slot />. I think some webpack building issue before.

How expose child element v-model as the vue component v-model

I Was using a simple text area in my vue component.:
<input v-model="someRootProperty"/>
I would like to encapsulate this input inside another component, for instance
<template>
<div>
<div>...</div>
<input v-model="???"/>
</div>
</template>
I would like to use
<my-component v-model="someRootProperty" />
instead and them bypass this to the input inside the component.
What should I do inside the component to expose its input v-model as the component v-model?
<input v-model="someRootProperty"/>
Is the same as (syntactic sugar):
<input :value="someRootProperty" #input="someRootProperty = $event.target.value"/>
That means that you could accept value as a prop in the component and emit input to achieve the same thing.
MyComponent.vue
<template>
<input :value="value" #input="$emit('input', $event.target.value)>
</template>
<script>
export default {
props: ['value']
}
And then use it like this.
<MyComponent v-model="someRootProperty"/>