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
    1. Home
    2. a47ae
    • Profile
    • Following 0
    • Followers 6
    • Topics 4
    • Posts 259
    • Best 76
    • Groups 0

    Robin Schreiner

    @a47ae

    147
    Reputation
    1233
    Profile views
    259
    Posts
    6
    Followers
    0
    Following
    Joined Last Online
    Location Germany

    a47ae Follow

    Best posts made by a47ae

    • [How To] Building components with Quasar

      This is a more detailed write up from my post here: http://forum.quasar-framework.org/topic/673/make-own-component-from-quasar-component/7

      This is still work in progress and some topics are missing. If some information is wrong, or I am missing on something, just let me know and I will update this post accordingly.

      Building reusable components with Quasar

      Vue.js greatly encourages the use of components to encapsulate reusable code and therefore DRY up your code.

      Most of the time Vue components are distributed as so called “Single File Components”. Single file components have the .vue file extension and allow to write the JS code, template, and style in the same file. These files are then put into a build system like webpack and vue-loader which will transform the template into a render function and extract the styles into a CSS file.

      Most of Quasars components are also distributed as single file components, you can check out their source here.

      Extending components

      Quasar is a framework and therefore provides building blocks to build your own Apps on top of it. But often the question arises how one could use the already existing Quasar components to build own components.

      The first thing to notice it that Vue.js favors composition over inheritance.

      Inheritance is a concept know from object oriented programming, where classes are able to extend another class to reuse its methods and attributes to build a new but similar class. Composition, on the other hand, is also known from object oriented programming, but instead of extending or overwriting an existing class, the class uses other classes to provide some common services.

      Mixins

      Mixins allow reusing certain features that you need in a set of components to not repeat yourself writing that code over and over.

      To define a mixin one has to export an object that looks similar to a normal component. Other components now can use this mixin to implement the mixin functionality.

      For example, lets we need to call a register method on a lot of different components. This method calls an API and returns some identifier that should be stored in the data object of the component.

      First, let us define the RegisterMixin:

      export const RegisterMixin = {
        data () => {
          return {
            id: ''
          }
        },
        
        methods: {
          register () {
            // Lets assume we extracted the AJAX call to the Registration class
            new Registration()
              .register()
              .then(response => {
                this.id = response.id
              })
          }
        },
        
        created () {
          this.register()
        }
      }
      

      Now that we have defined the mixin, we can use it on any other component and it will be mixed in the component attributes.

      import { RegisterMixin } from './registerMixin'
      
      export default {
        mixins: [RegisterMixin]
      }
      

      A component can use as many mixins as it likes.
      But be aware how Vue merges the options. You can read more about mixins in the Vue docs.

      Quasar uses mixins for some of its internal functionality. For example, the RouterLinkMixin which allows adding link functionality to different components.

      But as great as mixins are, you can not use another single file component as mixin because only the attributes are mixed in and not the template or style definition.

      Let’s assume we want to build a component called MySelect which behaves a bit different from QSelect.

      If we would write the following code:

      import { QSelect } from 'quasar'
      
      export default {
        mixin: [QSelect]
      }
      

      We would end up with a component that has all the internal methods and data from QSelect but no template at all. So we would have to get to the source of QSelect and copy the whole template definition. This would work as long as QSelect gets updated and you forget to update the template as well. Even if you only update minor versions it could break, because you are not relying on the external interface of QSelect which is described in the docs, but also on the internal code, which normally one shouldn’t have to care about.

      But how do we build or own MySelect component?

      Custom select component

      Let’s take an example from the forum. Someone asked how to build a component that hides some of the props passed to QSelect. Specifically, he wanted to build a select component which always had the filter prop set to true and always apply a default filter-placeholder.
      A simple implementation of this component could look like this:

      <template>
          <q-select :value="value" :options="options" @change="handleChange" filter filter-placeholder="select"/>
      </template>
      
      <script>
        import { QSelect } from 'quasar'
      
        export default {
          props: ['value', 'options'],
          methods: {
            handleChange (newVal) {
              this.$emit('input', newVal)
            }
          },
          components: {
            QSelect
          }
        }
      </script>
      

      Because v-model="foo" is just syntactic sugar for :value="foo" @input="foo = $event.target.the value" we can define a property value on our new component, which is then passed as value to the inner QSelect. We are then listening to the change event on the QSelect which indicates that the value has changed. If we receive such an event, we are emiting an input event from our new component and pass the new value as parameter.

      Now we can use the component like this:

      <template>
        <my-select v-model="selected" :options="myOptions" />
      </template>
      
      <script>
        import MySelect from './MySelect'
        
        export default {
          data () => {
            return {
              selected: null,
              myOptions: []
            }
          },
          
          components: { MySelect }
        }
      </script>
      

      And this would render a QSelect with filter set to true and filter-placeholder set to “select”.

      But if we wanted to set other properties on the internal QSelect we would have to define all of them on our own component und pass them to QSelect.

      Pinpad component

      Another user also asked how to build a custom component which is again a good example on how to use composition to create new components. He wanted to build a Pinpad component.

      We can simply achieve that by using QBtns which are aligned on a flexbox grid:

      <template>
          <div>
              <div v-for="row in 3" class="row justify-center">
                  <div v-for="col in 3" class="col-auto">
                      <q-btn @click="handleClick((row-1)*3 + col)">
                          {{ (row-1)*3 + col }}
                      </q-btn>
                  </div>
              </div>
          </div>
      </template>
      
      <script>
        import { QBtn } from 'quasar'
      
        export default {
          data () {
            return {
              pin: ''
            }
          },
          methods: {
            handleClick (digit) {
              this.pin += digit
            }
          },
          components: { QBtn }
        }
      </script>
      

      This gives us a whole new component by using existing components.
      We could now even extend this component with other Quasar components like an QInput to allow for manually entered pins.

      How to style custom components

      Styling custom components is easy, just declare your styles in the <style></style> section of your component.

      But what if we want our styles to be consistent and be able to change them in a single place?

      Quasar uses Stylus variables for that purpose.
      If you want to use some of the variables in your own components you can just import them like so:

      <template>...</tempalte>
      
      <script>...</script>
      
      <style lang="stylus">
        @import '~src/themes/app.variables.styl'
      </style>
      

      Now you can use all the variables like colors or breakpoints in your own component.

      Todos

      • Explain slots
      • Explain component communication
      • Static components
      • Directives
      • Quasar Utils
      posted in Show & Tell
      a47ae
      a47ae
    • RE: vue-cli 3.0 and the future of quasar-cli

      @qyloxe Sorry if I did not state this clearly, your comment is rude and you are disrespecting the time and thought @Vinkman has put into his comment, while your comment(s) do not add anything to this discussion.

      Also get your facts straight if you have to start this discussion:

      In computer science, a software framework is an abstraction in which software providing generic functionality can be selectively changed by additional user-written code, thus providing application-specific software.

      • Source: https://en.wikipedia.org/wiki/Software_framework

      In computer science, a library is a collection of non-volatile resources used by computer programs, often to develop software. These may include configuration data, documentation, help data, message templates, pre-written code and subroutines, classes, values or type specifications.

      • Source: https://en.wikipedia.org/wiki/Library_(computing)

      A framework has nothing to do with “client side” or “server side” and a libary has not necessarily anything to do with event handling.

      Quasar works and helps not only on the server side

      Can you please give me an example where Quasar is involved in the server side?
      Even if you count server side rendering it is not really involved in any server side stuff.
      Quasar at its base is JavaScript that gets executed in the Browser (or a web wrapper like Electron or Cordova) so in my understanding browser = client.

      […] federated logins, with potential of milions of users, with team of hundreds of people, with mixed backend servers, localised reverse proxy configurations, AWS […]

      Oh I just won at buzzword bingo!

      Also this was never about feelings but rather about a focused discussion which @Vinkman wanted to start here and I guess @rstoenescu is als happy to discuss possible improvement to Quasar-CLI if people struggle with some of the recent changes.

      Nobody here stated that their opinion was right, but wanted to express their opinion on the topic.

      And in fact, your comment and my very own comment are the only comments here which do not add anything to this discussion so I would say we stop it right here and listen to what @rstoenescu has to say on this topic.

      posted in CLI
      a47ae
      a47ae
    • RE: Make own component from Quasar component

      As far as I know, there is no way in Vue.js to really inherit from components, because Vue uses composition over inheritance. One option to write reusable components is mixins. A Mixin is basically a Vue component which is merged into your component. For example, you always want to print out foo bar in a dozen of your components. Instead of manually writing created () => { console.log('foo bar') } in each component you could define a mixin:

      export const FooBarMixin {
        created: function () {
          console.log('foo bar')
        }
      }
      

      And in each of your components you would write the following:

      import FooBarMixin from 'FooBarMixin'
      
      export default {
        // Your normal component stuff
        mixins: [FooBarMixin]
      }
      

      Now your component is merged with the mixin and prints out foo bar.

      But you can’t use mixins to extend the functionality of a whole single file component. If you use a Quasar component as a mixin, all the internal methods and data would be merged into your component, but the template would not. So you had to manually copy the template from that Quasar component into your component, which would not make it update safe.

      But how do you achieve the outcome @losika asked for?
      The solution is simple. Here you do not want to extend a Quasar component, instead, you want to wrap it, to hide some of the implementation details.
      So let’s write such a wrapping component:

      <template>
          <q-select :value="value" :options="options" @change="handleChange" filter filter-placeholder="select"/>
      </template>
      
      <script>
        import { QSelect } from 'quasar'
      
        export default {
          props: ['value', 'options'],
          methods: {
            handleChange (newVal) {
              this.$emit('input', newVal)
            }
          },
          components: {
            QSelect
          }
        }
      </script>
      

      Note that we are passing value to the QSelect component and we are listening for the change event on the QSelect. This is because v-model="foo" is just syntactic sugar for :value="foo" @input="foo = $event.target.value". Also note, that in order to pass additional props that are defined on QInput to the inner component, each of them has to be explicitly defined on the wrapping components and passed to the QInput.

      So often when you just want to use Quasar components to build another component you are using composition and not inheritance. For example @dgk in your example, you do not need to change something on existing components, but you want to build a new component based on Quasar components. So let’s say we build up your pin pad based on QBtn:

      <template>
          <div>
              <div v-for="row in 3" class="row justify-center">
                  <div v-for="col in 3" class="col-auto">
                      <q-btn @click="handleClick((row-1)*3 + col)" :disabled="disabled">
                          {{ (row-1)*3 + col }}
                      </q-btn>
                  </div>
              </div>
          </div>
      </template>
      
      <script>
        import { QBtn } from 'quasar'
      
        export default {
          data () {
            return {
              pin: ''
            }
          },
          methods: {
            handleClick (digit) {
              this.pin += digit
            }
          },
          components: { QBtn }
        }
      </script>
      

      Hopefully, that clarifies a bit when to use mixins and when to just build your component on top of other components. If I am missing something please let me know 🙂

      posted in Framework
      a47ae
      a47ae
    • RE: vue-cli 3.0 and the future of quasar-cli

      @qyloxe Sorry, but your comment seems a bit rude. @Vinkman has some valid points and even if I think we should fix the things that are missing for people in quasar-cli, because Quasar is a framework and not a component libary, we should have a discussion about why people want to use vue-cli instead and what features are missing for them isntead of just discrediting all their points.

      posted in CLI
      a47ae
      a47ae
    • RE: Migration 0.13 to 0.14

      Also, if you initialy created your Quasar application out of the v0.13 quasar-template-default, you may find it helpful to look at the diff of the master branch compared to the beta branch. Keep in mind that only the files that changed in them template folder are relevant.

      I started migrating to v0.14 by reading through each components doc, then I applied all the fixes from the template diff and fixied all the errors that occured during build with the new version.
      Next step I would suggest is to update the layout accordingly to the layout docs. This will help, because now your application doesn’t look totally broken 😰 .
      After that the tedious part begins, where you have to go through all of your commponents, look at the Quasar components used, and update them accordingly to the docs.

      For me the most notable changes where in the following components:

      • Forms - The form components got a complete overhaul, the no longer use CSS classes, but know are components on their own. The QField component comes in really handy, if you want to dispaly helper messages and achieve consistent styling.
      • Cards - Card are now also implemented as different components
      • Lists - Also items on their own, and increased flexibility, examples come in handy.
      • Grid system - Complete overhaul, very similar to Bootsrap 4 grid

      Most of the time you do not have to change a lot in your code, only in your templates, because the API stayed the same for most components. I would suggest to use the time to refactor your code a bit, because Quasar v0.14 introduced a lot of new helpers / posibilities to clean things up by quite a bit. In the end I even managed to reduce the size of our codebase by quite a bit.
      And even if it is tedious work, in the end it is totally worth it, and I am even excited to refactor existing components to use new stuff that was added in v0.14! 🙂

      Also you could use the time to report possible issues with the beta, and try to improve the docs, if some things are unclear to you, so Quasar finally can get the attention it deserves. 👍🏼

      posted in Framework
      a47ae
      a47ae
    • RE: How to vertically centering a single line or component? (SOLVED!)

      Oh, the hard coded height is only there to visualize the centering. Normally a div only has the height it needs. Even if you give it the full-height class, it only sets the height to 100% of the parent div. So to have an element centered vertically (at least to be able to see a vertical center), the element must have a higher height than the auto calculated, which should make sense and is not an issue with CSS but how the box model works. Go ahead and inspect the height of the elements in your example and you will notice, that they are exactly the height they need.

      If you want centered login form, try this snippet:

      <div class="window-height window-width row justify-center items-center">
          <q-card>
            <q-card-title>Login</q-card-title>
            <q-card-main>
              <form>
                <q-field>
                  <q-input v-model="email" type="email" float-label="E-Mail" required></q-input>
                </q-field>
      
                <q-field>
                  <q-input v-model="password" type="password" float-label="Password" required></q-input>
                </q-field>
              </form>
            </q-card-main>
      
            <q-card-separator/>
      
            <q-card-actions>
              <q-btn @click="login" type="submit">Login</q-btn>
            </q-card-actions>
          </q-card>
        </div>
      

      The interesting part is the classes applied to the wrapping div: window-height window-width row justify-center items-center

      row sets the display property to flex, justify-center centers it horizontally and items-center centers it vertically.

      But in order to work, we need a height for the element. This is where window-height comes in. It sets the height of the div to 100vh which stands for the whole viewport height. This would not work if there was something other displayed, like a top bar, because then you would have a scroll bar, or had to do something like this: height: calc(100vh-$top-bar-height). window-width on the other hand is not really needed because each element which has display: block automatically spans the full available width.

      I hope this illustrates why you need to set a height and solves your problem 🙂

      posted in Help
      a47ae
      a47ae
    • RE: NUXT with Quasar

      Hey @kiranvasi
      we are currently working on integrating SSR into Quasar. The roadmap that we intend to ship this feature in v1 is still valid.
      The template you are referring to will be deprecated, so until you are not in total need for SSR in your app right now you should wait for v1.
      Currently, we can not give a real estimate when v1 will be ready, but probably it will take some more time because we have to make sure that v1 really is stable.

      posted in Framework
      a47ae
      a47ae
    • RE: Debugging with VsCode and chrome-dev-tools

      This is really easy.
      First build your project with sourcemapping activated.
      Then install the “Debugger for Chrome” extension for VS Code and create a file .vscode/launch.jsonwith the following config:

      {
        "version": "0.2.0",
        "configurations": [
          {
            "type": "chrome",
            "request": "launch",
            "name": "Debug Quasar",
            "url": "http://localhost:8000",
            "webRoot": "${workspaceRoot}",
            "sourceMaps": true,
            "sourceMapPathOverrides": {
              "webpack:///*": "${webRoot}/*"
            }
          }
        ]
      }
      
      

      The only part that differs from your example are the source map path overrides.
      Then you should be able to create breakpoints an debug right from within VS Code.

      posted in CLI
      a47ae
      a47ae
    • RE: Layout breakpoints (media queries)

      Oh, then you are doing something wrong 😃
      Never, never change code in the source folder of an installed dependency (this will even not longer be possible in Quasar 0.14 because too much people misused the src).
      Quasar already defines a convenient place to overwrite variables.

      Add the variables under src/themes/app.variables.styl like described here

      This should also persist when you run npm install 🙂

      posted in Framework
      a47ae
      a47ae
    • RE: vue-cli 3.0 and the future of quasar-cli

      I agree that it is always bad to be forced to a specific build system by a framework, but I think Quasars case is a bit different.

      Meteor is a standalone framework, whereas Quasar is somehow dependent on Vue.js, so it is also dependent on how Vue.js apps can be build (e.g. vue-template-compiler).
      And because of that you are totally free to implement the build on your own just like pre 0.15 (I used to never use the cli to build but just call webpack directly via npm).

      The real benefit of Quasar CLI comes from having one tool which supports different build setups like SPA, PWA, Electron and Cordova. In the pre 0.15 days it was a bit of a struggle to set up an Electron version of your app after you initiated a plain SPA. Also having all the webpack config in your project scared lots of people because it seemed very complex to get your project up and running, even if most people never needed to touch the build configurationand in the past is was not really possible to easily upgrade your Quasar version without modifying all the changed template parts by hand.

      I think the problem here is that @rstoenescu commited lots of his time to build the new cli version and pack all the features in it. So I can totaly understand that its not really statisfying that you build such a tool, which right now is mostly state of the art and works flawlessly and people directly ask you to throw it all away because as @rstoenescu formulated it

      […] developers going for the new shiny thing

      without arguing what they are missing from the current solution.

      But I can also see where lots of the concernes are coming from. Of course it would be fatal if someday Quasar CLI would not longer work with the latest Vue.js version or was missing feature that makes it not longer usable for people. But if that happens it is most likely that Quasar as it self is not longer maintained, because why should @rstoenescu stop updating the cli somedays?

      On the other hand the current Quasar CLI setup is very similar to the Vue.js CLI v3 setup:

      • Both no longer ship a webpack config as part of the source but build this config during runtime
      • Both provide a config file where most of the aspects are configured
      • Both use webpack for building

      Where they are different:

      • + Quasar allows to build SPAs, PWAs, Electron apps and Cordova apps out of one source repository, as far as I know this is not possible with the defautl Vue.js setup
      • - Vue CLI allows for a plugin infrastructure which can alter the build process. Even Vue CLI itself is build using these plugins
      • - Vue CLI alows for “Chaining” of webpack config (https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md#chaining-advanced) which allows to later tap into webpack rules

      I guess webpack chain feature is easily integratable into Quasar CLI. So currently I see no real benefit from migrating to Vue CLI except

      Migrating to Vue CLI (while being a bit of a pain at first) propably saves dev time in the future.
      Lets assume Quasar is provided as a config of Vue CLI, then @rstoenescu never has to bother about updating the webpack config, learning about new PWA toolchains, testing and maintaining a cli by himself, while still being able to support Cordova and Eelctron via the plugin infrastructure.

      This integration would propably also support Quasars stand in the Vue.js community.

      So I am really looking forward to hear some input from @rstoenescu on this topic! 🙂

      P.S.: @LaurentPayot Are you sure the tempalte system will be deprecated? From your link I can only see that the PWA template will be deprecated but not the infrastructure as such. Also last time I checked workbox was not deprecating the other tools, but more combining the, while still being in development, but you are right, workbox is propably the future for PWAs

      posted in CLI
      a47ae
      a47ae

    Latest posts made by a47ae

    • RE: Themeing, Stylus vs SCSS

      Hey @spanners welcome to Quasar. 🙂
      You will be in no way tied to use Stylus, it is true that the internal components use Stylus as CSS pre processor, but you can choose whatever you like for your Quasar app.
      The docs explain how you can switch the pre processor on the example of SCSS.
      Also, if somehow there are issues with Stylus that are not resolved upstream, I am certain that Quasar will adopt accordingly.

      If you look at the contributor graph at GitHub you will see, that there are actually a lot of people that contribute to Quasar and there are two lead developer, namely @rstoenescu and @pdanpdan

      I can only recommend you to join our Discord chat at https://discordapp.com/invite/5TDhbDg where the community is way more active. From the forum you could get a false impression about how much people care for Quasar. 🙂

      Hopefully I could resolve you concerns, otherwise I am glad to answer additional questions.

      posted in Framework
      a47ae
      a47ae
    • RE: Why there are two themes to choose during the building process?

      The themes are only referring to the style guidelines used to create them.
      The “Material theme” sticks to the Material guidelines from Google and the “iOS theme” to Apple Human Interface guidelines.

      You can, however, choose any theme in any browser/device, the compatibility is the same.
      Due how the build process works you cannot switch themes during runtime (also this would ship lots of unneeded resources for your customers), this is why you have to set the theme at build time.

      posted in Framework
      a47ae
      a47ae
    • RE: NUXT with Quasar

      Hey @kiranvasi
      we are currently working on integrating SSR into Quasar. The roadmap that we intend to ship this feature in v1 is still valid.
      The template you are referring to will be deprecated, so until you are not in total need for SSR in your app right now you should wait for v1.
      Currently, we can not give a real estimate when v1 will be ready, but probably it will take some more time because we have to make sure that v1 really is stable.

      posted in Framework
      a47ae
      a47ae
    • RE: How to install a specific version of quasar-cli? (0.15.2)

      Hey André,
      you can install a specific version of Quasar cli using npm install -g quasar-cli@version.
      In your case that would be npm install -g quasar-cli@0.15.2.

      But please note that there are two versions of Quasar CLI.
      One that is installed globally and one that is installed in your project.
      The one in your project automatically installs to the same version your friend installed it.

      I would recommend updating your Quasar version to the latest version by running npm update quasar-cli inside your project.

      Also best luck on your project, make sure to share your results on the forum or on Discord 🙂

      posted in CLI
      a47ae
      a47ae
    • RE: Is there any Vue-centric way to access external APIs?

      Hey, there is no “official” way, but I can tell you what we did with our API endpoints.
      We have a directory /src/api. In this directory, each file represents an API endpoint.
      All files extend a simple REST client which uses axios and has methods like list, create, update and delete.

      The crucial point here is that each file exports a class by default.

      // Simplified example
      // src/api/demo.js
      import axios from 'axios'
      
      export default class DemoClient {
        list () {
          return axios.get('/my/api/endpoint')
        }
      }
      

      Also, note that the methods return the axios promise.

      Not in your components you can import your client and use it.

      // demo.vue
      import  DemoClient from  'src/api/demo.js'
      
      export default {
        data () {
          return {
            demoData: []
          }
        },
      
        created () {
          DemoClient.list()
            .then(response => {
              this.demoDate = response.data
            })
        }
      }
      
      posted in Framework
      a47ae
      a47ae
    • RE: Can we get props from quasar.config.js? (0.15)

      @leopiccionia No it would not be reactive. 🙂
      But in this case, it wouldn’t matter because you certainly would not edit the quasar.conf.js during runtime 😃

      posted in Framework
      a47ae
      a47ae
    • RE: Can we get props from quasar.config.js? (0.15)

      @leopiccionia You don’t need a mixin for this.

      Assuming you had access to the config (which is not easily possible because it is a function which requires a context), you could have an app plugin like this:

      import config from 'quasar.conf.js' // This does not work
      
      export default ({ Vue }) => {
        Vue.prototype.$config= config
      }
      
      posted in Framework
      a47ae
      a47ae
    • RE: Can we get props from quasar.config.js? (0.15)

      The problem is that quasar.conf.js requires a context that is passed.
      Here is the source from quasar-cli which parses the config: https://github.com/quasarframework/quasar-cli/blob/dev/lib/quasar-config.js

      Any special settings you wanted to read from that config file?
      You could go the other way and import your custom config file (e.g. /src/config/index.js) in Quasars config file.

      posted in Framework
      a47ae
      a47ae
    • RE: this.$emit not a function in component method

      That’s really strange, it should be available on every VueComponent: https://vuejs.org/v2/api/#vm-emit

      Is it only on this component or also on others?

      posted in Framework
      a47ae
      a47ae
    • RE: this.$emit is not a function

      Please do not double post questions!

      posted in Framework
      a47ae
      a47ae