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
    1068
    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.
    • matroskin
      matroskin last edited by

      Hi,
      how can I set default props?
      for example I want that all q-card components make bordered

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

        Do you mean like the right QCard here? https://codepen.io/smolinari/pen/BaBmPLm?&editable=true&editors=111

        Scott

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

          @matroskin you need to learn component composition https://vuejs.org/v2/guide/components.html. wrap your q-card component with bordered prop on, and use that component.
          ie.

          // MyBorderedCard.vue
          <template>
            <q-card bordered .... />
          ...
          // SomeVue.vue
            <my-bordered-card />
            <my-bordered-card />
            <my-bordered-card />
          ...
          
          A 1 Reply Last reply Reply Quote 0
          • matroskin
            matroskin last edited by

            thanks, that is the way

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

              I recently ran into the same issue, of wanting to impose consistent style options with multiple Quasar component types throughout my app. For example I might want q-input components to default to dense and outlined, and q-btn components to default to dense and flat. Since Quasar components use props for configuring many aspects of components, you can’t just use CSS for this.

              I tried the approach mentioned above of wrapping components, but found this to be problematic. To use QInput as an example, what I really want is a component with the same API as QInput, including the same props, events, slots and methods, but just with different defaults for some of the props.
              To achieve this by wrapping I would have to make my wrapper forward all of these things to the wrapped component. For props this is simple using v-bind="$attrs" like this:

              // MyInput
              <template>
                <q-input v-bind="$attrs" .../>
              ...
              

              However I’m not aware of an equivalently trivial method for forwarding all events, slots and methods to the wrapped component. This means when I write a wrapper, I have to choose between either doing a non-trivial amount of work, or not replicating the API of the wrapped component. For simple components like QInput this might still not be a big deal, but it adds up when I start wanting to do the same thing for multiple components, and especially for complex components like QTable.

              The approach I came up with instead was to create a defaults.js file with an object for each component I want to customize, like this:

              // defaults.js
              
              // default prop values for QInput
              export const inputDefaults = {
                outlined: true,
                dense: true
              }
              
              // default prop values for QBtn
              export const btnDefaults = {
                flat: true
              }
              
              // .. Etc for any other components you want to customize
              

              To make it easy to access these defaults I make a boot file like this:

              import * as defaults from 'src/defaults'
              
              export default async ({ Vue }) => {
                Vue.prototype.$defs = defaults
              }
              

              Now in templates I can make a component use the defaults simply by adding a v-bind="$defs.componentTypeDefaults" attribute, like:

              <template>
                <div>
                  <q-input 
                    v-bind="$defs.inputDefaults"
                    label="The Label"
                    ... other props
                  />
              
                  <q-btn
                    v-bind="$defs.btnDefaults"
                    ... other props
                  />
                </div>
              </template>
              

              It’s not quite as convenient to use as custom wrapper components, but on the other hand it’s much easier to customize a large number of components, and I’m not losing access to any of the functionality of the Quasar components. I still have access to all the events, slots and methods of the Quasar components without having to explicitly forward them in my wrappers.

              What I wish for is that Quasar would add this functionality so that component prop defaults could be configured in quasar.conf.js. I’d like for there to be a componentDefaults section in quasar.conf.js that allows configuring component defaults just like I’m doing in defaults.js.

              metalsadman 1 Reply Last reply Reply Quote 0
              • 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