No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Configure component prop defaults

    Framework
    7
    18
    3878
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J
      jraez last edited by

      oh, no, don’t wrap components, extends them.

      <script>
      import QInput from 'quasar'
      export default {
        name: 'MyInput',
        extends: QInput
        props: {
          outlined: {
            type: Boolean,
            default: true
          },
          dense: {
            type: Boolean,
            default: true
          }
        }
       }
      </script>
      

      Then you have to import MyInput or declare globally and use it instead of QInput. This way you have the default behavior you want, you keep all QInput features and you can even remove outlined or dense manually.

      A dobbel C 3 Replies Last reply Reply Quote 1
      • A
        ajenkins @jraez last edited by

        @jraez Thank you! I didn’t know about extend. That’s exactly what I wanted.

        1 Reply Last reply Reply Quote 0
        • dobbel
          dobbel @jraez last edited by dobbel

          @jraez that’s amazing. Setting the same property values( like dense outlined ect) for certain q-components is something you do over and over again in every quasar project.

          Then why is everybody so focused on a composition solution for this problem (composition has it’s uses but will ‘cripple’ the ‘extended’ component, explained in the posts above) and something simple as extending is never mentioned ( Quasar docs)? Are there some untold cave pits with extending vue/quasar components this way? Just really curious …

          1 Reply Last reply Reply Quote 0
          • J
            jraez last edited by

            @ajenkins you’re welcome.

            @dobbel Well, it’s only my guess but it’s related to people’s knowledge of OOP, not really quasar or VueJS. After many years of programming, whatever the language, framework, or such, you’ll always land on coding fundamentals 🙂 Maybe there’s a downside using inheritance but I’d never face it (in a JS/VueJS/Quasar context).

            1 Reply Last reply Reply Quote 0
            • metalsadman
              metalsadman last edited by metalsadman

              Coz both have their uses, in wrapping you can fiddle with the template, which you cant using extend, unless you want to break it. In this case extend is appropriate since you are just changing the props.

              1 Reply Last reply Reply Quote 0
              • J
                jraez last edited by

                For extending my own component template I use pug. I can create the template ‘template’ in parent with block and override what I need in children. The downside is to use 2 files one for Vue component, one for pug template, and include manually the pug into the component each time.

                dobbel 1 Reply Last reply Reply Quote 0
                • dobbel
                  dobbel @jraez last edited by

                  @jraez That sounds like a very flexible solution! Would you want to share an example of extending a quasar component with ‘extend’ combined with overriding a part of the parent template with pug?

                  1 Reply Last reply Reply Quote 0
                  • J
                    jraez last edited by

                    In my case, I use it to create custom QDdialog and inject them through the Dialog plugin. The idea is to have a standard design with an icon + title, some action buttons, and the content.

                    I changed the ProductDialog to something out of my own scope because it’ll be too complex for an example.

                    The base dialog

                    <script>
                    export default {
                      props: ['name'],
                      data: () => ({
                        config: {
                          title: '',
                          position: 'standard',
                          translateTitle: true,
                          cssClass: 'custom-dialog',
                          icon: 'fas fa-exclamation-triangle'
                        }
                      }),
                      methods: {
                        // following method is REQUIRED
                        // (don't change its name --> "show")
                        show () {
                          this.$refs.dialog.show()
                        },
                    
                        // following method is REQUIRED
                        // (don't change its name --> "hide")
                        hide () {
                          this.$refs.dialog.hide()
                        },
                    
                        onDialogHide () {
                          // required to be emitted
                          // when QDialog emits "hide" event
                          this.$emit('hide')
                        },
                    
                        onOKClick () {
                          // on OK, it is REQUIRED to
                          // emit "ok" event (with optional payload)
                          // before hiding the QDialog
                          this.$emit('ok')
                          // or with payload: this.$emit('ok', { ... })
                    
                          // then hiding dialog
                          this.hide()
                        },
                    
                        onCancelClick () {
                          // we just need to hide dialog
                          this.hide()
                        }
                      }
                    }
                    </script>
                    <style>
                    .custom-dialog {
                      width: 600px;
                    }
                    </style>
                    

                    The dialog template:

                    q-dialog(ref="dialog" @hide="onDialogHide" :persistent="true" :position="config.position")
                      q-card(:class="config.cssClass")
                        block wrapper
                          block title
                            q-card-section.row.items-center.text-h4
                              q-icon(:name="config.icon").q-mr-md
                              .text-capitalize {{ config.translateTitle ? $t(config.title) : config.title}}
                              q-space
                              q-icon(@click="onCancelClick" name="fas fa-times").cursor-pointer.q-ml-md
                          block separator
                            q-separator(inset)
                          q-card-section(:horizontal="config.horizontal")
                            block content
                        q-card-actions.justify-end
                          block actions
                            q-btn(color="primary" flat :label="$t('application.actions.cancel')" @click="onCancelClick")
                            q-btn(color="primary" :text-color="$theme.colors.primaryText" :label="$t('application.actions.save')" @click="onOKClick")
                    

                    The my dialog implement:

                      <template lang="pug">
                      extends ../../UI/Dialog/DialogBase
                      block content
                        q-card-section.col-4
                          .text-body2 {{ $t('application.product.list') }}
                          q-scroll-area(style="height: 700px;")
                            q-list.q-mt-md
                              q-item(v-for="product in products" :key="product.id" dense)
                                q-item-section(side)
                                  q-btn(flat round icon="fas fa-times" @click="remove(product)")
                                q-item-section(side)
                                  q-btn(flat round icon="fas fa-edit" @click="edit(product)")
                        q-separator(vertical)
                        q-card-section.col
                          .text-body2.q-mb-sm  {{ $t('application.product.info') }}
                          .row.q-gutter-none 
                             q-editor(v-model="product.description")
                      block actions
                        q-btn(color="primary" flat :label="$t('application.actions.reset')" @click="reset")
                        q-btn(color="primary" :text-color="$theme.colors.primaryText" :label="$t('application.actions.save')" @click="save")
                    </template>
                    <script>
                    import DialogBase from '../../UI/Dialog/DialogBase'
                    export default {
                      name: 'ProductManagerDialog',
                      extends: DialogBase,
                      data: () => ({
                        config: {
                          title: 'application.product.manager.title',
                          cssClass: 'project-product-manager',
                          icon: 'fas fa-calendar-alt',
                          horizontal: true
                        },
                        products: []
                        product: null
                      }),
                      methods: {
                        edit (product) {
                          this.product = product
                        },
                        async remove (product) {
                           // remove product from products and save to the backend
                        }
                      },
                      async mounted () {
                        this.products = await ProductService.list()
                      }
                    }
                    </script>
                    <style>
                      .project-product-manager {
                        min-width: 1100px;
                      }
                    </style>
                    
                    dobbel 1 Reply Last reply Reply Quote 0
                    • dobbel
                      dobbel @jraez last edited by

                      @jraez Thanks for the sample code. Do you like to use Pug to code (Quasar templates) or is it necessary because your want to override templates?

                      1 Reply Last reply Reply Quote 0
                      • J
                        jraez last edited by

                        @dobbel I use pug because it makes the template more readable to me (less “verbose” in fact), so I’ve started using it before the need to override templates. Then it helps me with overriding and composition, so I stick to it.

                        1 Reply Last reply Reply Quote 0
                        • C
                          chrislandeza @jraez last edited by

                          @jraez Tried extending QInput but I’m getting this error:
                          Failed to mount component: template or render function not defined.

                          Tried copy pasting your example but I get the same error

                          MyInput.vue

                          <script>
                          import QInput from 'quasar'
                          export default {
                            name: 'MyInput',
                            extends: QInput,
                            props: {
                              outlined: {
                                type: Boolean,
                                default: true
                              },
                              dense: {
                                type: Boolean,
                                default: true
                              }
                            }
                           }
                          </script>
                          

                          Page.vue

                          <template>
                            <div>
                              <my-input></my-input>
                            </div>
                          </template>
                          
                          <script>
                          import MyInput from 'components/MyInput'
                          
                          export default {
                            components: { MyInput },
                            name: 'PageIndex'
                          }
                          </script>
                          
                          
                          

                          Am I doing it wrong?

                          C 1 Reply Last reply Reply Quote 0
                          • C
                            chrislandeza @chrislandeza last edited by

                            Nvm. I was just missing the curly brace 😁

                            <script>
                            import { QInput } from 'quasar'
                            export default {
                              name: 'MyInput',
                              extends: QInput,
                              props: {
                                outlined: {
                                  type: Boolean,
                                  default: true
                                },
                                dense: {
                                  type: Boolean,
                                  default: true
                                }
                              }
                             }
                            </script>
                            
                            1 Reply Last reply Reply Quote 0
                            • G
                              garhbod last edited by

                              I’ve started a quasar extension for this purpose. At the time of typing it only has a QBtn extension to prove the concept but will continue to add other components that have styling properties. Check it out and submit an issue of the component you want added so I can prioritise them. Or fork it and create a pull request with the component you want. It isn’t hard to extend a component just check out the code for QBtn

                              https://github.com/garhbod/quas-tom
                              https://www.npmjs.com/package/quasar-app-extension-quas-tom

                              dobbel 1 Reply Last reply Reply Quote 1
                              • dobbel
                                dobbel @garhbod last edited by dobbel

                                @garhbod

                                Nice! You should create a post in Show and Tell on this forum for bigger audience.

                                1 Reply Last reply Reply Quote 0
                                • D
                                  dinarys last edited by

                                  This post is deleted!
                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post