how can i pass registered vue component as prop to a component - vue.js

Need to pass component to child component, using props or you have better way to solve this problem
I registered component needed to pass globally or just registered this component locally. But these solutions can't solve my problem.
Here is my code to register component needed to pass locally:
a.vue html
<dropdown :icon="UserIcon"></dropdown>
a.vue js
components: {'dropdown', Dropdown, 'icon-user': UserIcon}
dropdown.vue html
<div class="dropdown"><icon></icon></div>
dropdown.vue js
props: ['icon']
UserIcon.vue
<i class="user-icon"></i>
the browser reminds me that icon is unknown custom element. It seems like vue does not support this way to use component, doesn't it?

I solve this problem using slot.
and there is another question comes...
a.vue
<dropdown><template v-slot:icon><icon-user></icon-user></template></dropdown>
dropdown.vue
<div class="dropdown"><slot name="icon"></slot></div>
But icon-user component didn't show...
and I did this work, cuz I remove the name attribute of slot.
a.vue
<dropdown><template><icon-user></icon-user></template></dropdown>
dropdown.vue
<div class="dropdown"><slot></slot></div>

Related

Difference between router-link and RouterLink in Vue

When using Vue Router, I found that I could use <router-link> as well as RouterLink to achieve the same result, i.e. navigate between different routes.
Similarly, there's <router-view> as well as RouterView component.
Following two code examples give me the same result:
With <router-link> and <router-view>:
<template>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<hr />
<router-view></router-view>
</template>
With <RouterLink> and <RouterView>:
<script setup>
import { RouterLink, RouterView } from "vue-router";
</script>
<template>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
<hr />
<RouterView />
</template>
Question
What is the difference between <router-link> and RouterLink (and between <router-view> and RouterView?)
I couldn't find anything on Vue Router docs. Searching for RouterView or RouterLink doesn't show any results related to them. Docs only mention <router-link> and <router-view>.
P.S. Scaffolding a new Vue project with npm init vue#latest command uses RouterLink and RouterView components instead of router-link and router-view.
It's the same components, just with different cases, in vue it's recommended to use the PascalCase syntax as mentioned here :
In SFCs, it's recommended to use PascalCase tag names for child components to differentiate from native HTML elements. Although native HTML tag names are case-insensitive, Vue SFC is a compiled format so we are able to use case-sensitive tag names in it. We are also able to use /> to close a tag.
They are the same thing. Any component can be used either by writing its name as PascalCase or kebab-case.
One is the component name and one is the vue class. I don't think there is a difference. If you would create your own component e.g. MyComponent.vue, you can also use <MyComponent> or <my-component>

Is there a way to pass elements to a vue component?

when I need to pass some information between child and parent element I use props. But is there a way to pass elements to the component, for example like this
<MyComponent>
<router-link to="/oneOfTheList">OneOfTheList</router-link>
</MyComponent>
Router-Link seems to do it somehow...
How can I specify where the elements will be placed in my component
This is called slot
ComponentA.vue
<div>
<slot></slot>
</div>
ComponentB.vue
<component-a>
<span>test</span> // this part will be shown inside component A's slot tags
</component-a>
Here you go

Aurelia custom element without outer node

Is it possible to let Aurelia render a custom element without the capsulating component node? Or replace the custom-element node with its content?
Example:
app.html
<template>
<require from = "./components/custom-component.html"></require>
<custom-component></custom-component>
</template>
app.ts
export class App {
}
custom-component.html
<template>
<p>This is some text from dynamic component...</p>
</template>
Result
Based on this example: Is it possible with aurelia to render the <p> element from the component as direct child of the <body>, so that there will be no custom-component-node?
Use the containerless attribute on your component.
example: https://gist.run/?id=8e57000c7b8423dc0246a7006d90ba79
you can also decorate your custom components with the containerless() decorator.
see: http://aurelia.io/hub.html#/doc/article/aurelia/framework/latest/cheat-sheet/9

Accessing properties/methods of a Vuejs component globally

I want to create a custom component and to use it like
<div id="app">
<router-view />
<my-custom-loader />
</div>
My component has some methods which I want to use globally anywhere like
this.$loader.show();
this.$loader.hide();
I can create the component but not sure how to inject its method/properties so that it's available everywhere.
Component create a encapsulated scope in vuejs.
AFAIK you should not be doing this as I feel this to be more like a workaround that a perfect vuejs way of doing this.
You can setup a ref on the <my-custom-loader> component.
<div id="app">
<router-view />
<my-custom-loader ref="loader"/>
</div>
Since the component looks like the child of root vue instance mounted on #app you can use it to acess $refs
var vm = new Vue({
el: '#app'
});
//my-custom-loader component's instance
var loader = vm.$rers.loader;
Then you can setup this loader which is the my-custom-loader component's instance on the Vue.prototype. This now allows you to acess $loader in any component using this.$loader
Vue.prototype.$loader = loader;
Now you can acess its methods using
this.$loader.hide();
this.$loader.show();
keep in mind the warning of using refs as mentioned in the docs
$refs are only populated after the component has been rendered, and it is not reactive. It is only meant as an escape hatch for direct child manipulation - you should avoid using $refs in templates or computed properties.
As for me I recommend you use custom events or register a global event bus or use vuex if your app is very big and has complex state management

Attribute "id" is ignored on component

I persistently getting this warning on my vuejs app, dint know where and why:
build.js:9371 [Vue warn]: Attribute "id" is ignored on component <div> because the component is a fragment instance
I am using vue-router, with index.html:
<body>
<div id="app"></div>
</body>
Just to add to what #Roy J has said. Look through your components. Make sure that all your components have one wrapping dom element around them, like a single parent. The best thing to always do is wrap all elements in your components in one parent div.
Something like this:
<div>
<div>Some content</div>
<div> some more content </div>
</div>
That way, Vue know how to mount your component on the parent app. If your component is fragmented, you'll get the error you are talking about. Vue sometimes doesn't tell you which component exactly so you'll have to skim through all your components.
If your component does not have a single containing DOM element, it is a fragment instance and can't have an id. That is, if it expands to
<div></div>
<div></div>
<div></div>
there's no correct place to put the id.