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. stuartcusack
    S
    • Profile
    • Following 0
    • Followers 0
    • Topics 9
    • Posts 27
    • Best 5
    • Groups 0

    stuartcusack

    @stuartcusack

    6
    Reputation
    113
    Profile views
    27
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    stuartcusack Follow

    Best posts made by stuartcusack

    • RE: Route Animations

      I’ve updated the answer by @Zyme for the current version of Quasar (0.17.17)

      <q-page-container>
      
          <transition appear enter-active-class="animated slideInRight" leave-active-class="animated slideOutLeft" mode="out-in">
              <router-view />
          </transition>
      
      </q-page-container>
      

      Note that mode=“out-in” is important. Don’t forget to add these animations to quasar.conf:
      https://quasar-framework.org/components/transition.html

      posted in Help
      S
      stuartcusack
    • RE: How to have q-layout-drawer in a seperate component?

      I experienced a similar problem with q-layout-drawer and I was seeing the Vue warning: ‘Avoid mutating a property directly…’ .

      As you should know, if you are passing the ‘leftDrawerOpen’ variable down to the child component as a prop then you should avoid manipulating that prop directly in the child component. I was not attempting this in my code but I was still seeing the error.

      It turns out that q-layout-drawer has a built-in function which detects clicks outside the drawer and attempts to close the itself by updating the v-model ‘leftDrawerOpen’. This works fine when the v-model references data, but when it’s referencing a prop it shows the mutation warning because it’s attempting to manipulate the property.

      In order to get around this you have to copy the ‘leftDrawerOpen’ prop variable into a local data variable. This means the q-layout-drawer can manipulate the copied data variable without warnings. However, you have to keep in mind that the ‘leftDrawerOpen’ prop could be changed from the parent or from another component, so to keep our local copy up to date you have to watch for changes to that prop.

      Here is an example:

      /*CustomDrawerComponent.vue*/
      /* Passing local data instead of the prop to q-layout-drawer */
      <q-layout-drawer side="left" v-model="localLeftDrawerOpen">
          <q-list link inset-delimiter>
              <q-item to="/">
                  <q-item-side icon="home" />
                  <q-item-main label="Home" sublabel="This is your home" />
              </q-item>
          </q-list>
      </q-layout-drawer>
      </template>
      
      <script>
      
      export default {
      
          props: {
              /* this prop gets passed down from our parent - it should NOT be manipulated directly! */
              leftDrawerOpen: Boolean
          },
      
          data () {
         
                  return {
                      /* A local data copy of our prop - which CAN be manipulated here */
                      localLeftDrawerOpen: false
          
                  }
          
          },
          
          watch: {
              
              /* If our prop ever gets changed outside of this component then we need to update our local data version of the prop */
              leftDrawerOpen: function(newVal) {
                  this.localLeftDrawerOpen = newVal;
              }
      
          },
      
          mounted: function() {
      
              /* As soon as the component is mounted convert our passed prop into data*/
             /* This line may or may not be necessary - The watch function probably covers it already, but I haven't tested without it yet */
              this.localLeftDrawerOpen = this.leftDrawerOpen;
      
          }
      
      }
      </script>
      
      /* Layout */
      
      <template>
      <q-layout>
      
          <q-layout-header>
      
              <q-toolbar color="primary" :inverted="$q.theme === 'ios'">
      
                  <q-btn flat dense round @click="leftDrawerOpen = !leftDrawerOpen" aria-label="Menu">
                      <q-icon name="menu" />
                  </q-btn>
      
                  <q-toolbar-title>
                      My Custom App
                      <div slot="subtitle">Running on Quasar v{{ $q.version }}</div>
                  </q-toolbar-title>
      
              </q-toolbar>
      
          </q-layout-header>
      
          /*passing our parent's data down to our child as a prop*/ 
          <custom-drawer :left-drawer-open="leftDrawerOpen"></custom-drawer>
      
          <!-- this is where the Pages are injected -->
          <q-page-container>
      
              <router-view></router-view>
      
          </q-page-container>
      
      </q-layout>
      </template>
      
      <script>
      
      //Our custom components
      import CustomDrawer from 'components/CustomDrawer'
      
      export default {
      
          components: {
              CustomDrawer 
          },
      
          // name: 'LayoutName',
          data () {
              return {
                  leftDrawerOpen: this.$q.platform.is.desktop
              }
          },
      
          mounted () {
      
              var self = this;
      
          }
      }
      </script>
      
      

      And to go a little further, if you want to keep your header in a separate component then do something like this using Quasar’s global event bus:

      
      /*CustomHeader.vue*/
      /*Emit a request to update the leftDrawerOpen variable*/
      <q-btn flat dense round @click="$root.$emit('toggle_left_drawer')" aria-label="Menu">
           <q-icon name="menu" />
      </q-btn>
      
      
      /*Layout.vue*/
      mounted () {
      
      var self = this;
      
      //List for $emits from any child components
      this.$root.$on('toggle_left_drawer', function() {
            
           /* our parent's data is updated, which in turn updates the sidebars props, which in turn updates the sidebars local data - NO WARNINGS :) */
            self.leftDrawerOpen = !self.leftDrawerOpen;
      
       });
      
      }
      
      ``
      posted in Help
      S
      stuartcusack
    • QImg and ~assets src

      I’m struggling to understand why this works:

      <img src="~assets/logo.png">
      

      But this doesn’t:

      <q-img src="~assets/logo.png" />
      

      Can someone explain?

      What way should I be referencing the assets folder so that QImgs are loaded correctly for both SPA and Electron? Should I always use statics instead of assets for logos?

      posted in Help
      S
      stuartcusack
    • Electron: How to listen to events on the ipcRenderer?

      I’ve managed to send events out from electron using:

      mainWindow.webContents.send("event-name", value);
      

      And I can successfully receive the event like so:

      this.$q.electron.ipcRenderer.on('event-name', {
        // whatever
      });
      

      But how do I do this in reverse? i.e. send from the vue component to electron. This doesn’t seem to work:

      this.$q.electron.ipcRenderer.send('event-name', {
      	value: value
      });
      
      mainWindow.webContents.on('event-name', (event, info) => {
          console.log('event received')
      });
      
      posted in Help
      S
      stuartcusack
    • RE: Electron and Cookies

      I’ve been doing a lot of research today on LocalStorage and it seems the way to go for Electron. I don’t think Cookies work the same way with Electron.

      By the way, you probably shouldn’t store anything sensitive in LocalStorage, including api tokens. Instead use secure storage packages (untested):

      • Electron: https://github.com/atom/node-keytar

      • Cordova: https://github.com/Crypho/cordova-plugin-secure-storage (no longer maintained)

      For SPAs that utilise APIs I think I need to integrate Implicit Password Grants, instead of Password Grants. SPAs don’t have a secure way to store data.

      posted in Help
      S
      stuartcusack

    Latest posts made by stuartcusack

    • Dialog Plugin - No OK dismiss

      I think it would be useful to have a noOkDismiss property on the Dialog plugin.

      In my case I would like to keep the dialog open until my asynchronous API functions complete and then I would dismiss it manually.

      posted in Framework
      S
      stuartcusack
    • RE: Q Popup Edit - How to set computed vuex model @input?

      I got it working. It was very easy in the end, I just switched ‘v-model’ for ‘value’ on the popup, but I don’t understand why either are necessary.

      My inputs already define the v-model so what are the reasons for v-model on the popup?? If you remove it you get an error.

      <q-popup-edit
          value="details">
      
              <q-input
              type="textarea"
              v-model="details"
              @keyup.enter.stop
              placeholder="Enter some details..."
              autogrow />
      
          </q-popup-edit>
      
      posted in Help
      S
      stuartcusack
    • Q Popup Edit - How to set computed vuex model @input?

      I would like my q-popup-edit component to commit it’s v-model to my vuex store each time the user inputs (@input).

      Currently the value is not committed if the user click’s outside the popup or if the user navigates away from the router page destroying the popup.

      I could use the ‘buttons’ property and force the user to click ‘Set’ but I’d rather this behaviour.

      <q-popup-edit
          v-model="details">
      
              <q-input
              type="textarea"
              v-model="details"
              @keyup.enter.stop
              placeholder="Enter some details..."
              autogrow />
      
          </q-popup-edit>
      

      I’m sure I’ve done something similar before using :value and @input on a q-date field but I can’t figure it out this time.

      posted in Help
      S
      stuartcusack
    • RE: ipcRenderer and Platform Detection in Boot Files

      Seems the only solution for the moment is to have two separate Boot files and perform platform detection within quasar.conf. I might need to rethink my oauth system.

      https://github.com/quasarframework/quasar/issues/4552

      posted in Help
      S
      stuartcusack
    • RE: Electron: How to listen to events on the ipcRenderer?

      @rick-luan I wonder if you can help me with this:
      https://forum.quasar-framework.org/topic/3915/ipcrenderer-and-platform-detection-in-boot-files

      posted in Help
      S
      stuartcusack
    • ipcRenderer and Platform Detection in Boot Files

      Can someone tell me the correct way to achieve this:

      I have a Boot file called oauth/index.js:

      import { Platform } from 'quasar'
      const { ipcRenderer } = require('electron');
      
      class OAuth {
          
         // Send a message to electron
         storeAuthData () {
             if (Platform.is.electron) {
               ipcRenderer.send('setSecurePassword', password);
             }
         }
      
      }
      

      This works fine when I build Electron but when I build SPA or run ‘quasar dev’ I get the following error:
      Uncaught TypeError: fs.existsSync is not a function

      I opened a GitHub bug but I was told that I am not using Platform Detection correctly.

      Any ideas? Thanks.

      posted in Help
      S
      stuartcusack
    • RE: Electron: How to listen to events on the ipcRenderer?

      And here’s a way to receive a response / get a variable from ipcRenderer:

      /* in component - use sendSync when a response is needed */
      let password ipcRenderer.sendSync('getPassword', 'MyService', username);
      
      /* in electron-main.js */
      ipcMain.on('getPassword', (event, ...[service, account]) => {
      	var passwordPromise = keytar.getPassword(service, account);
      
      	// Every function in keytar is asynchronous and returns a promise
      	passwordPromise.then((result) => {
                      // This is how we return data to ipcRenderer
      		event.returnValue = result
      	})
      })
      
      posted in Help
      S
      stuartcusack
    • RE: Electron: How to listen to events on the ipcRenderer?

      By the way, this might be useful for you if you ever need to pass multiple values from ipcRenderer to ipcMain.

      /* in component (pass as many args as you like) */
      ipcRenderer.send('savePassword', 'MyService', username, password);
      
      /* in electron-main.js (define the args you want using JS rest operator and deconstruction) */
      ipcMain.on('savePassword', (event, ...[service, account, secret]) => {
              // keytar is a nice package for secure storage of credentials on Electron
      	keytar.setPassword(service, account, secret);
      })
      
      posted in Help
      S
      stuartcusack
    • RE: Electron: How to listen to events on the ipcRenderer?

      @rick-luan THANK YOU!

      That works perfectly. You saved some hairs on my head.

      posted in Help
      S
      stuartcusack
    • RE: Electron and Cookies

      I’ve been doing a lot of research today on LocalStorage and it seems the way to go for Electron. I don’t think Cookies work the same way with Electron.

      By the way, you probably shouldn’t store anything sensitive in LocalStorage, including api tokens. Instead use secure storage packages (untested):

      • Electron: https://github.com/atom/node-keytar

      • Cordova: https://github.com/Crypho/cordova-plugin-secure-storage (no longer maintained)

      For SPAs that utilise APIs I think I need to integrate Implicit Password Grants, instead of Password Grants. SPAs don’t have a secure way to store data.

      posted in Help
      S
      stuartcusack