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

    default style

    Framework
    7
    16
    752
    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.
    • metalsadman
      metalsadman @ajenkins last edited by metalsadman

      @ajenkins you are on right track. very basic wrapper eg

      <some-component
        ...
        v-on="$listeners"
        v-bind="$attrs"
      >
        <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
          <slot :name="slot" v-bind="scope"/>
        </template>
      </some-component>
      
      A 1 Reply Last reply Reply Quote 0
      • A
        ajenkins @metalsadman last edited by ajenkins

        @metalsadman Thanks for that. That’s closer to a transparent wrapper than I realized was easily possible. That still leaves out methods, but it’s much less common for me to want to call methods on components anyway, so that’s not a big deal.

        I still prefer my solution of just using the Quasar components directly rather than having to write wrappers for everything though. It seems to me that it would be the rule rather than the exception to want to override the default style props for form components in a consistent way throughout an application. Expecting every app developer to write their own wrapper components to solve this problem seems like a clunky solution, especially since there’s no standardized way to do that, so every developer is going to end up doing it slightly differently.

        1 Reply Last reply Reply Quote 0
        • A
          ajenkins last edited by

          Just to help anyone finding this thread who wants the solution, I just tried @metalsadman’s solution for writing a QInput wrapper. This worked fine for a wrapper that overrides the outlined and dense props but otherwise has the same API as QInput.

          <template>
            <q-input
              v-bind="attrs"
              v-on="$listeners">
              <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
                <slot :name="slot" v-bind="scope"/>
              </template>
            </q-input>
          </template>
          
          <script>
          export default {
            name: 'MyInput',
            computed: {
              attrs () {
                return {
                  // Put any prop value overrides here, before the ...this.$attrs line
                  outlined: true,
                  dense: true,
                  ...this.$attrs
                }
              }
            }
          }
          </script>
          
          1 Reply Last reply Reply Quote 0
          • A
            ajenkins last edited by

            It was just pointed out to me in another thread that you can actually extend Vue components instead of wrapping them, which I think solves most of my concerns with wrapping. https://forum.quasar-framework.org/post/21630

            Basically, instead of writing a wrapper like above, use extends like this:

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

              This Stackoverflow guy says ‘extend’ is a bad idea in Vue ( the last post):

              I’d avoid the “extends” feature of Vue, simply because it is a poorly named method of Vue. It doesn’t really extend anything, not in the case of inheritance. What it does is exactly what the mixin does, it merges the two components together. It has nothing to do with the template code, which isn’t extensible either. The “extend” Vue method should have been called “merge”.

              https://stackoverflow.com/questions/35964116

              Any thoughts?

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

                I don’t know how VueJS run under the hood, but what you achieve with extends is more or less the same as adding a mixin to a component.

                The only difference I see is the fact that mixins are abstract components, you never use them as-it. It’s just a fragment. In inheritance, you may found some cases where you instantiate the parent. In the @ajenkins example, you can have QInput and MyInput together on the same app. So it depends on your app, or what you need to achieve, etc. both ways have pros and cons.

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

                  @dobbel I’m not sure I understand the Stackoverflow guy’s objections. I just tested out extends and it works. It may be true that you can’t “extend” the template code, so it doesn’t exactly correspond to subclassing in an OO language, which seems to be the Stackoverlow guy’s objection, but that seems like a fairly pedantic objection IMO. Extending solves the problem in this case. I just tested this and it works as expected:

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

                  I can use my-input just like q-input, and it supports the same props, events, slots, and methods. The only difference is outlined and dense default to true.

                  1 Reply Last reply Reply Quote 0
                  • A
                    ajenkins last edited by

                    One slight disadvantage I found with using extends vs the solution I described initially above is that if you’re using an IDE, you lose autocomplete for component props, at least IntelliJ family editors. For example if I do

                    <q-input
                       err<tab>
                    

                    The editor will suggest the error-message, error and no-error-icon props, but when using my-input, I don’t get these suggestions. This could work in principle, but the Vue plugin for IntelliJ apparently doesn’t understand extends.

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

                      I’d use whichever is appropriate, extend or wrapping.

                      1 Reply Last reply Reply Quote 0
                      • V
                        vijayganeshpk last edited by vijayganeshpk

                        This is a valid use case for which a more elegant option from the framework would be helpful.

                        For our requirement, we wanted all controls to be flat and bordered, so we went ahead with the following solution:

                        // commattribs.js
                        export default {
                           flat: true,
                           bordered: true
                        }
                        

                        then customized individual components that we use to make use of the above attributes:

                        <template>
                          <q-card
                            v-bind="attrs"
                            v-on="$listeners"
                          >
                            <template
                              v-for="(_, slot) of $scopedSlots"
                              v-slot:[slot]="scope"
                            >
                              <slot
                                :name="slot"
                                v-bind="scope"
                              />
                            </template>
                          </q-card>
                        </template>
                        
                        <script>
                        import cattribs from './comm-attribs'
                        export default {
                          name: 'ACard',
                          computed: {
                            attrs () {
                              return {
                                ...cattribs,
                                ...this.$attrs
                              }
                            }
                          }
                        }
                        </script>
                        

                        so if we needed to customize all components with some other attribute, we change them up in commattribs.js

                        1 Reply Last reply Reply Quote 1
                        • s.molinari
                          s.molinari last edited by

                          But, what if you wanted only some of your components to be a certain way?

                          Scott

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post