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 on ChildComponent 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

    alt text

    Final note

    If anyone can offer suggestions around that ChildComponent being able to accept a per-instance generator function into it’s generateValue 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.


  • Admin

    1. There’s no need for a “name” prop in your component. That’s useful only when you write some recursive templates.

    2. 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.

    3. 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 wrote clock.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!


  • Admin

    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.


Log in to reply
 

Looks like your connection to Quasar Framework was lost, please wait while we try to reconnect.