How to regsiter custom components?
-
I’ve created a custom component, and I’d like to know how to register it, if possible,
quasar/src/via install.js
if that it the correct way to do it?In most of the online tutorials for Vue 2.0 and their own guides, they’re mostly using
template: ...
but I get errors about runtime mode not allowing that. So I switched to use of the<template />
tag as with all of the Quasar components - but I cannot find a way to register my component official for use.Cheers!
-
Argh, nevermind, I figured it out. I don’t need to register my component, I was referencing it incorrectly within another component that was using it.
-
You should give an example how you achieved this, for future people searching of a similar issue
-
@Dobromir Good point! Ok here goes, and maybe this can serve as a time for some QA on what I’ve done to. Happy for improvement suggestions
Problem
I want to create a custom, re-usable component that follows Vue.js conventions as well as Quasar conventions, where they apply.
To add context, many online forums, articles & posts at the time of this post’s writing focus on use if the
template
property within a component definition, which has caused a runtime error unless set up correctly.Solution
Parent component
<template><!-- use of tag-based templating within this parent component --> <div><!-- single root node, required --> <h1>A Route View</h1> <h2>Here is a custom component:</h2> <!-- this component differs from the basic input component provided by Vue.js and Quasar in that it will contain a button which can be used to auto-populate the input value with the return value of supplied function. for this example, i have not implemented the supplied function part. --> <child-component label="My Label" componentclasses="floating-label" inputclasses="full-width" ></child-component> </div> </template> <script> // import our custom component to use within this component import ChildComponent from '../ChildComponent' export default { name: 'ParentComponent', // be sure to list our custom component here, i've used kebab-case here as // the name to be used in the above <template> definition. ComponentCamelCase // is used for the actual component definition components: { 'child-component': ChildComponent } } </script>
Child component
<template><!-- use of tag-based templating within this child component --> <div :class="componentclasses"> <input :required="required" :class="inputclasses" v-model="model" :disabled="disable"> <label v-show="label">{{label}}</label> <a @click="generateValue()" class="icon icon-generate"></a> </div> </template> <script> export default { methods: { /** * Given a generator function, this component's inputValue is set * to the return value of the generator. * * @param Function **/ generateValue: function (generator) { // set this component's value prop as result of supplied generator function return } }, props: { 'value': String, 'required': Boolean, 'disable': Boolean, 'label': String, 'inputclasses': String, 'componentclasses': String }, computed: { model: { get () { return this.value }, set (value) { this.$emit('input', value) } } } } </script> <style> .icon-generate { float:right; width:16px; height:16px; border:1px dashed red; } </style>
Recap
Counter to tutorials & posts I’ve read through, no
template
property onChildComponent
is used, instead tag-based templating combined with component names & importing are used.My original post asked about installing components in some official way, as with Quasar components via
quasar/src/install.js
, but nothing was needed.Screenshot
Final note
If anyone can offer suggestions around that
ChildComponent
being able to accept a per-instancegenerator
function into it’sgenerateValue
method - your help would be much appreciated.To illustrate my needs by example, the parent component, when including the child, might want to auto-populate the input field with a name picked randomly from a default set of names. I can’t directly add that logic into the child component because then it only has a single use. I might also want to use that child component again and be able to pass a different function into
generateValue
which returns a fruit picked randomly from a default set of fruits. -
-
There’s no need for a “name” prop in your component. That’s useful only when you write some recursive templates.
-
Since we got Webpack and Vue we can use *.vue files which transforms your components into render functions. So no need to include Vue compiler into your app’s final code. This eases up on the size of your app and takes full advantage of Vue’s speed. If you need to compile templates at runtime speed of execution will drop. Vue compiler is not included by default, that’s why “template” prop won’t work. Examples you’ve seen are just examples to get you started quickly, but you don’t need the “template” prop since we got *.vue files. When you use *.vue files the
<template>
tag is parsed and converted to a render function by vue-loader. -
Writing and using components is easy. Write a *.vue file with your component, then include it in whatever other component you need it, through the
components
prop. Let’s say we wroteclock.vue
. We need that component in our page, so on the page’s *.vue file we write:
import Clock from '...path..to..clock.vue' export default { .... components: { Clock } }
…and we use it like this in the page’s
<template>
tag:<template> .... <clock ...></clock> .... </template>
My recommendations is to leave Vue tutorials aside. Read the official documentation website for Vue. It will suffice! Read it inside out before digging in.
-
-
Very clear, thank you @rstoenescu !
-
Looking at the
name
property again, @rstoenescu - is there any detriment to naming the component? If not, in giving it a name the Vue dev tools uses the name (converting to camelCase) property to populate nodes. My preference would be to supply the name for this reason, unless there’s a good reason to avoid it! -
Using the
name
property has no place in talking about how to require/register a component because it doesn’t affect it in any way. This means however you can use and there’s no reason or recommendation not to. It’s just out of the scope of custom component discussion.