Side panel with content from page

I want to use the side-panels to show data (lists) from a page - but for every page the panel has different content. Think of the side-panels e.g. in ‘Sketch.app’.

  • If you open another page/route the panels have different content.
  • The data needs to stay reactive - that means: if someone clicks an object on the page, those changes are reflected in the side-panel(s). And the other way round: if something is changed in the side-panel, the changes are reflected on the page/route.

What’s the best way to do this? Create the panels dynamically? Or how would I ‘link’ the panel (created in app.vue) dynamically? (the panel needs to access a page’s data)

In Vue.js things a bit easier with this. You have reactive $root object that you can reuse:
Add root panel-related data
app.js

new Vue({
  // ...
  data() {
    return {
      panelComponent: null,
      panelProps: null,
    };
  }
})

Add dynamic component in panel:
app.vue

<f7-app>
  <f7-panel v-if="$root.panelComponent" left cover>
    <component :is="$root.panelComponent" v-bind="$root.panelProps"></component>
  </f7-panel>
  ...
  <f7-view>
    ...
  </f7-view>
</f7-app>

And in page where you need to load it:
page-a.vue

<template>
  <f7-page>
    ...
    <f7-button @click="changePanelFoo">Change Panel Foo</f7-button>
  </f7-page>
</template>
<script>
  import panelA from './page-a-panel.vue';

  export default {
    // ...
    mounted() {
      this.$root.panelComponent = panelA;
      this.$root.panelProps = {
        foo: 'bar',
      }
    },
    methods: {
      changePanelFoo() {
        this.$root.panelProps.foo = 'baz';
      },
    },
  }
</script>

And, for example:
page-a-panel.vue

<template>
  <f7-page>
    {{foo}}
  </f7-page>
</template>

<script>
  export default {
    props: {
      foo: String,
    },
  }
</script>

Oh - that’s great! Is this somewhere documented? That’s really awesome!
Thanks for the snippets!

Im my current implementation I had it exactly the other way round: :slight_smile:

<f7-panel left cover theme-dark>
<f7-view>
  <f7-page>
    <f7-navbar title="Layers"></f7-navbar>
    <f7-list v-if="$root.mainView" class="layerlist" sortable sortable-enabled @sortable:sort="onSort">
    <f7-list-item  v-for="(itm, idx) in $root.mainView.layers" :key="idx"
      :title = "itm.name"
    >
  </f7-list-item>
</f7-list>

where I swapped the mainView property for every page. (Which works fine, too)

No, as it is mostly about how just Vue works.

Could be a solution too that fits good for simple things.

I’ve used the way as Vladimir described. But I just wrapped them within the method

methods: {
   Panel_show() {
     this.$root.panelComponent = panelA;
     this.$root.panelProps = {
        foo: 'bar',
     } 
   }
},
mounted() {
   this.Panel_show();
}

And even when the user returns back, I call it again on page:reinit event:

<f7-page @page:reinit="Panel_show">
...
</f7-page>
1 Like

Very cool!
Although my implementation does what I need, I will try this as well.
Sorry I currently can’t test, so just one question:
Do I put my reactive list like this?

methods: {
   Panel_show() {
     const self = this;
     this.$root.panelComponent = panelA;
     this.$root.panelProps = self.$layers;
   }
},

Thanks again for your hints! Works like a charme!! :ok_hand: