Categories
PrimeVue

Vue 3 Development with the PrimeVue Framework — Toggle and Reorder Table Columns

PrimeVue is a UI framework that’s compatible with Vue 3.

In this article, we’ll look at how to get started with developing Vue 3 apps with PrimeVue.

Toggle Table Columns

We can add a multi-select dropdown to let us toggle table columns on and off.

For instance, we can write:

<template>
  <div>
    <DataTable :value="cars">
      <template #header>
        <div style="text-align: left">
          <MultiSelect
            :modelValue="selectedColumns"
            :options="columns"
            optionLabel="header"
            @update:modelValue="onToggle"
            placeholder="Select Columns"
            style="width: 20em"
          />
        </div>
      </template>
      <Column
        v-for="(col, index) of selectedColumns"
        :field="col.field"
        :header="col.header"
        :key="`${col.field}_${index}`"
      ></Column>
    </DataTable>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      cars: [
        { brand: "Volkswagen", year: 2012, color: "Orange", vin: "dsad231ff" },
        { brand: "Audi", year: 2011, color: "Black", vin: "gwregre345" },
        { brand: "Renault", year: 2005, color: "Gray", vin: "h354htr" },
      ],
      selectedColumns: [],
      columns: [
        { field: "vin", header: "VIN" },
        { field: "year", header: "Year" },
        { field: "color", header: "Color" },
        { field: "brand", header: "Brand" },
      ],
    };
  },
  methods: {
    onToggle(value) {
      this.selectedColumns = this.columns.filter((col) => value.includes(col));
    },
  },
  created() {
    this.selectedColumns = this.columns;
  },
};
</script>

We listen to the update:modelValue event to run code to filter out the columns that we disabled.

We get the selected columns from the value parameter.

Resizable Columns

We can make columns resizable with the resizableColumns prop:

<template>
  <div>
    <DataTable
      :value="cars"
      :resizableColumns="true"
      columnResizeMode="fit"
      class="p-datatable-gridlines"
    >
      <Column field="vin" header="Vin"> </Column>
      <Column field="year" header="Year"> </Column>
      <Column field="brand" header="Brand"></Column>
      <Column field="color" header="Color"></Column>
    </DataTable>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      cars: [
        { brand: "Volkswagen", year: 2012, color: "Orange", vin: "dsad231ff" },
        { brand: "Audi", year: 2011, color: "Black", vin: "gwregre345" },
        { brand: "Renault", year: 2005, color: "Gray", vin: "h354htr" },
      ],
    };
  },
  methods: {},
};
</script>

We set the prop to true to enable column resizing.

columnResizeMode is set to 'fit' to make the columns fit the content.

Reordering Table Rows

Table rows can be reordered by listening to the row-reorder event:

<template>
  <div>
    <DataTable
      :value="cars"
      :reorderableColumns="true"
      @column-reorder="onColReorder"
      @row-reorder="onRowReorder"
    >
      <Column
        :rowReorder="true"
        headerStyle="width: 3rem"
        :reorderableColumn="false"
      />
      <Column
        v-for="col of columns"
        :field="col.field"
        :header="col.header"
        :key="col.field"
      ></Column>
    </DataTable>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      cars: [
        { brand: "Volkswagen", year: 2012, color: "Orange", vin: "dsad231ff" },
        { brand: "Audi", year: 2011, color: "Black", vin: "gwregre345" },
        { brand: "Renault", year: 2005, color: "Gray", vin: "h354htr" },
      ],
      columns: [
        { field: "vin", header: "VIN" },
        { field: "year", header: "Year" },
        { field: "color", header: "Color" },
        { field: "brand", header: "Brand" },
      ],
    };
  },
  methods: {
    onColReorder() {},
    onRowReorder(event) {
      this.cars = event.value;
    },
  },
};
</script>

We get the reordered items with the event.value property.

Likewise, we can listen to the column-reorder event to listen for column reordering actions.

Conclusion

We can toggle and reorder table rows and columns withn PrimeVue’s table.

Categories
PrimeVue

Vue 3 Development with the PrimeVue Framework — Panels and Split Panes

PrimeVue is a UI framework that’s compatible with Vue 3.

In this article, we’ll look at how to get started with developing Vue 3 apps with PrimeVue.

Panel

We can add a panel with PrimeVue’s Panel component.

For example, we can write:

main.js

import { createApp } from "vue";
import App from "./App.vue";
import PrimeVue from "primevue/config";
import Panel from 'primevue/panel';
import 'primevue/resources/primevue.min.css'
import 'primevue/resources/themes/saga-blue/theme.css'
import 'primeicons/primeicons.css'
import 'primeflex/primeflex.css';

const app = createApp(App);
app.use(PrimeVue);
app.component("Panel", Panel);
app.mount("#app");

App.vue

<template>
  <div>
    <Panel header="Header"> Lorem ipsum dolor sit amet </Panel>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

The header prop has the header text.

And the default slot has the content text.

We can customize the header with the header slot:

<template>
  <div>
    <Panel>
      <template #header> Header Content </template>
      Lorem ipsum dolor sit amet
    </Panel>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

And we can add the toggleable prop to make the panel toggleable:

<template>
  <div>
    <Panel toggleable>
      <template #header> Header Content </template>
      Lorem ipsum dolor sit amet
    </Panel>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

We can also collapse the panel initially with the collapsed prop:

<template>
  <div>
    <Panel toggleable collapsed>
      <template #header> Header Content </template>
      Lorem ipsum dolor sit amet
    </Panel>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

We can also add a custom icon by populating the icons slot:

<template>
  <div>
    <Panel>
      <template #icons>
        <button class="p-panel-header-icon p-link p-mr-2">
          <span class="pi pi-cog"></span>
        </button>
      </template>
      Lorem ipsum dolor sit amet
    </Panel>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

Splitter

PrimeVue comes with a splitter component to let us add a split pane.

For instance, we can write:

main.js

import { createApp } from "vue";
import App from "./App.vue";
import PrimeVue from "primevue/config";
import Splitter from 'primevue/splitter';
import SplitterPanel from 'primevue/splitterpanel';
import 'primevue/resources/primevue.min.css'
import 'primevue/resources/themes/saga-blue/theme.css'
import 'primeicons/primeicons.css'
import 'primeflex/primeflex.css';

const app = createApp(App);
app.use(PrimeVue);
app.component("Splitter", Splitter);
app.component("SplitterPanel", SplitterPanel);
app.mount("#app");

App.vue

<template>
  <div>
    <Splitter style="height: 300px">
      <SplitterPanel> Panel 1 </SplitterPanel>
      <SplitterPanel> Panel 2 </SplitterPanel>
    </Splitter>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

We add the Splitter component with the SplitterPane to add the panes.

We can add more than 2 SplitPanel s.

Also, we can set the layout prop of Splitter to 'vertical' to make the layout vertical.

The initial size of each pane can be changed with the size prop:

<template>
  <div>
    <Splitter style="height: 300px">
      <SplitterPanel :size="20"> Panel 1 </SplitterPanel>
      <SplitterPanel :size="80"> Panel 2 </SplitterPanel>
    </Splitter>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

We can also set the min size with tyhe minSize prop:

<template>
  <div>
    <Splitter style="height: 300px">
      <SplitterPanel :size="20" :minSize="10"> Panel 1 </SplitterPanel>
      <SplitterPanel :size="80" :minSize="20"> Panel 2 </SplitterPanel>
    </Splitter>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

SplitterPanel s can also be nested in other SplitterPanel s.

We can also save the splitter sizes to local storage with the stateKey and stateStorage props:

<template>
  <div>
    <Splitter stateKey="splitter-key" stateStorage="local">
      <SplitterPanel :size="20" :minSize="10"> Panel 1 </SplitterPanel>
      <SplitterPanel :size="80" :minSize="20"> Panel 2 </SplitterPanel>
    </Splitter>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

stateKey is the key for local storage.

And stateStorage specifies that we save the size setting for each pane to local storage.

Conclusion

We can add panels and split panels into our Vue 3 with PrimeVue.

Categories
PrimeVue

Vue 3 Development with the PrimeVue Framework — Cards, Deferred Content, and Fieldsets

PrimeVue is a UI framework that’s compatible with Vue 3.

In this article, we’ll look at how to get started with developing Vue 3 apps with PrimeVue.

Cards

Cards are containers that house content of our choice.

To add it, we write:

main.js

import { createApp } from "vue";
import App from "./App.vue";
import PrimeVue from "primevue/config";
import Card from 'primevue/card';
import Button from 'primevue/button';
import 'primevue/resources/primevue.min.css'
import 'primevue/resources/themes/saga-blue/theme.css'
import 'primeicons/primeicons.css'
import 'primeflex/primeflex.css';

const app = createApp(App);
app.use(PrimeVue);
app.component("Button", Button);
app.component("Card", Card);
app.mount("#app");

App.vue

<template>
  <div>
    <Card>
      <template #header> Header </template>
      <template #title> Advanced Card </template>
      <template #content> Lorem ipsum dolor sit amet </template>
      <template #footer>
        <Button icon="pi pi-check" label="Save" />
        <Button
          icon="pi pi-times"
          label="Cancel"
          class="p-button-secondary"
          style="margin-left: 0.5em"
        />
      </template>
    </Card>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

We add the Card component and populate the slots it provides to add our own content.

The header slot lets us add a header.

title lets us populate the title.

content lets us populate the main content.

footer lets us populate the footer.

Deferred Content

The DeferredContent component lets us load content only when the items inside are in the viewport.

To use it, we write:

main.js

import { createApp } from "vue";
import App from "./App.vue";
import PrimeVue from "primevue/config";
import DeferredContent from 'primevue/deferredcontent';
import Card from 'primevue/card';
import DataTable from 'primevue/datatable';
import Column  from 'primevue/column';
import 'primevue/resources/primevue.min.css'
import 'primevue/resources/themes/saga-blue/theme.css'
import 'primeicons/primeicons.css'
import 'primeflex/primeflex.css';

const app = createApp(App);
app.use(PrimeVue);
app.component("DeferredContent", DeferredContent);
app.component("DataTable", DataTable);
app.component("Column", Column);
app.component("Card", Card);
app.mount("#app");

App.vue

<template>
  <div>
    <DeferredContent>
      <DataTable :value="cars">
        <Column field="vin" header="Vin"></Column>
        <Column field="year" header="Year"></Column>
        <Column field="brand" header="Brand"></Column>
        <Column field="color" header="Color"></Column>
      </DataTable>
    </DeferredContent>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      cars: [
        { brand: "Volkswagen", year: 2012, color: "Orange", vin: "dsad231ff" },
        { brand: "Audi", year: 2011, color: "Black", vin: "gwregre345" },
        { brand: "Renault", year: 2005, color: "Gray", vin: "h354htr" },
      ],
    };
  },
  methods: {},
};
</script>

We wrap DeferredContent around the table which we want to load only when the items are in the viewport.

Fieldset

We can add the Fieldset component to add a box with content.

To use it, we write:

main.js

import { createApp } from "vue";
import App from "./App.vue";
import PrimeVue from "primevue/config";
import Fieldset from 'primevue/fieldset';
import 'primevue/resources/primevue.min.css'
import 'primevue/resources/themes/saga-blue/theme.css'
import 'primeicons/primeicons.css'
import 'primeflex/primeflex.css';

const app = createApp(App);
app.use(PrimeVue);
app.component("Fieldset", Fieldset);
app.mount("#app");

App.vue

<template>
  <div>
    <Fieldset legend="Godfather I"> Lorem ipsum </Fieldset>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

The legend text is displayed at the top of the box.

We can populate the legend slot to add a custom header:

<template>
  <div>
    <Fieldset>
      <template #legend> Header Content </template>
      Content
    </Fieldset>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

And we can take it toggleable with the toggleable prop:

<template>
  <div>
    <Fieldset toggleable>
      <template #legend> Header Content </template>
      Content
    </Fieldset>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

Conclusion

We can add various containers for content into our Vue 3 app with PrimeVue.

Categories
PrimeVue

Vue 3 Development with the PrimeVue Framework — Tree Node Content and Accordions

PrimeVue is a UI framework that’s compatible with Vue 3.

In this article, we’ll look at how to get started with developing Vue 3 apps with PrimeVue.

Tree Node Content

We can customize the tree node’s content with the default and url slots.

For instance, we can write:

<template>
  <div>
    <Tree :value="nodes" :expandedKeys="expandedKeys">
      <template #default="slotProps">
        <b>{{ slotProps.node.label }}</b>
      </template>
      <template #url="slotProps">
        <a :href="slotProps.node.data">{{ slotProps.node.label }}</a>
      </template>
    </Tree>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      expandedKeys: undefined,
      nodes: [
        {
          key: "0",
          label: "Introduction",
          children: [
            {
              key: "0-0",
              label: "What is Vue.js?",
              data: "https://vuejs.org/v2/guide/#What-is-Vue-js",
              type: "url",
            },
            {
              key: "0-1",
              label: "Getting Started",
              data: "https://vuejs.org/v2/guide/#Getting-Started",
              type: "url",
            },
            {
              key: "0-2",
              label: "Declarative Rendering",
              data: "https://vuejs.org/v2/guide/#Declarative-Rendering",
              type: "url",
            },
            {
              key: "0-3",
              label: "Conditionals and Loops",
              data: "https://vuejs.org/v2/guide/#Conditionals-and-Loops",
              type: "url",
            },
          ],
        },
        {
          key: "1",
          label: "Components In-Depth",
          children: [
            {
              key: "1-0",
              label: "Component Registration",
              data: "https://vuejs.org/v2/guide/components-registration.html",
              type: "url",
            },
            {
              key: "1-1",
              label: "Props",
              data: "https://vuejs.org/v2/guide/components-props.html",
              type: "url",
            },
            {
              key: "1-2",
              label: "Custom Events",
              data: "https://vuejs.org/v2/guide/components-custom-events.html",
              type: "url",
            },
            {
              key: "1-3",
              label: "Slots",
              data: "https://vuejs.org/v2/guide/components-slots.html",
              type: "url",
            },
          ],
        },
      ],
    };
  },
  methods: {},
};
</script>

We get the node data in each slot with the slotProps.node property.

Also, we can add the filter slot to add a text input to let us search for nodes.

Accordion

PrimeVue comes with an accordion component to let us add content into tabs.

To add it, we write:

main.js

import { createApp } from "vue";
import App from "./App.vue";
import PrimeVue from "primevue/config";
import Accordion from 'primevue/accordion';
import AccordionTab from 'primevue/accordiontab';
import 'primevue/resources/primevue.min.css'
import 'primevue/resources/themes/saga-blue/theme.css'
import 'primeicons/primeicons.css'
import 'primeflex/primeflex.css';

const app = createApp(App);
app.use(PrimeVue);
app.component("Accordion", Accordion);
app.component("AccordionTab", AccordionTab);
app.mount("#app");

App.vue

<template>
  <div>
    <Accordion>
      <AccordionTab header="Header 1"> Content </AccordionTab>
      <AccordionTab header="Header 2"> Content </AccordionTab>
      <AccordionTab header="Header 3"> Content </AccordionTab>
    </Accordion>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

We register the Accordion and AccordionTab components to let us add the accordion with the tabs.

We just put the content into the default slot of AccordionTab to add the content.

header has strings that are displayed in the accordion tab headers.

The Accordion‘s multiple prop lets us keep multiple tabs open at once.

We can also add the disabled prop to AccordionTab to disable the tab.

Also, we can add custom content into the header by populating the header slot:

<template>
  <div>
    <Accordion>
      <AccordionTab>
        <template #header>
          <i class="pi pi-calendar p-mr-2"></i>
          <span>Header 1</span>
        </template>
        Content
      </AccordionTab>
      <AccordionTab header="Header 2"> Content </AccordionTab>
      <AccordionTab header="Header 3"> Content </AccordionTab>
    </Accordion>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  methods: {},
};
</script>

Conclusion

We can add tree node with custom content and accordions into our Vue 3 app with PrimeVue.

Categories
PrimeVue

Vue 3 Development with the PrimeVue Framework — Pick List, Timelines, and Tree Views

PrimeVue is a UI framework that’s compatible with Vue 3.

In this article, we’ll look at how to get started with developing Vue 3 apps with PrimeVue.

Pick List

We add the picklist component to let us reorder items between different lists.

For instance, we can write:

<template>
  <div>
    <PickList v-model="cars" dataKey="vin">
      <template #item="slotProps">
        <div class="p-caritem">
          <p>{{ slotProps.item.vin }}</p>
          <p>{{ slotProps.item.year }}</p>
          <p>{{ slotProps.item.color }}</p>
        </div>
      </template>
    </PickList>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      cars: [
        [
          {
            brand: "Volkswagen",
            year: 2012,
            color: "Orange",
            vin: "dsad231ff",
          },
        ],
        [
          { brand: "Audi", year: 2011, color: "Black", vin: "gwregre345" },
          { brand: "Renault", year: 2005, color: "Gray", vin: "h354htr" },
        ],
      ],
    };
  },
  methods: {},
};
</script>

The model for the picklist is an array with 2 arrays.

The first array is for the left list.

And the 2nd array is for the right list.

The items slot has the item display.

slotProps.item has the item for an entry.

Now we should get 2 lists with buttons to let us move items between 2 lists after selecting one.

Timeline

We can add a timeline into our Vue 3 app with the Timeline component.

To add it, we write:

main.js

import { createApp } from "vue";
import App from "./App.vue";
import PrimeVue from "primevue/config";
import Timeline from 'primevue/timeline';
import Card from 'primevue/card';
import 'primevue/resources/primevue.min.css'
import 'primevue/resources/themes/saga-blue/theme.css'
import 'primeicons/primeicons.css'
import 'primeflex/primeflex.css';

const app = createApp(App);
app.use(PrimeVue);
app.component("Timeline", Timeline);
app.component("Card", Card);
app.mount("#app");

App.vue

<template>
  <div>
    <Timeline :value="events">
      <template #marker="slotProps">
        <span
          class="custom-marker p-shadow-2"
          :style="{ backgroundColor: slotProps.item.color }"
        >
          <i :class="slotProps.item.icon"></i>
        </span>
      </template>
      <template #content="slotProps">
        <Card>
          <template #title>
            {{ slotProps.item.status }}
          </template>
          <template #subtitle>
            {{ slotProps.item.date }}
          </template>
          <template #content>
            <p>Lorem ipsum</p>
          </template>
        </Card>
      </template>
    </Timeline>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      events: [
        {
          status: "Ordered",
          date: "15/10/2020 10:30",
          icon: "pi pi-shopping-cart",
          color: "#9C27B0",
          image: "game-controller.jpg",
        },
        {
          status: "Processing",
          date: "15/10/2020 14:00",
          icon: "pi pi-cog",
          color: "#673AB7",
        },
        {
          status: "Shipped",
          date: "15/10/2020 16:15",
          icon: "pi pi-shopping-cart",
          color: "#FF9800",
        },
        {
          status: "Delivered",
          date: "16/10/2020 10:00",
          icon: "pi pi-check",
          color: "#607D8B",
        },
      ],
      events2: ["2020", "2021", "2022", "2023"],
    };
  },
  methods: {},
};
</script>

We register the Timeline component.

Then we populate the content prop with the content of each timeline entry.

The marker prop lets us change the marker to what we want.

We get the item data with the slotProps.item property in each slot.

Tree View

We can add a tree view into our Vue 3 app with PrimeVue’s Tree component.

To add one, we write:

maim.js

import { createApp } from "vue";
import App from "./App.vue";
import PrimeVue from "primevue/config";
import Tree from 'primevue/tree';
import 'primevue/resources/primevue.min.css'
import 'primevue/resources/themes/saga-blue/theme.css'
import 'primeicons/primeicons.css'
import 'primeflex/primeflex.css';

const app = createApp(App);
app.use(PrimeVue);
app.component("Tree", Tree);
app.mount("#app");

App.vue

<template>
  <div>
    <Tree :value="nodes" :expandedKeys="expandedKeys"></Tree>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      expandedKeys: undefined,
      nodes: [
        {
          key: "0",
          label: "Introduction",
          children: [
            {
              key: "0-0",
              label: "What is Vue.js?",
              data: "https://vuejs.org/v2/guide/#What-is-Vue-js",
              type: "url",
            },
            {
              key: "0-1",
              label: "Getting Started",
              data: "https://vuejs.org/v2/guide/#Getting-Started",
              type: "url",
            },
            {
              key: "0-2",
              label: "Declarative Rendering",
              data: "https://vuejs.org/v2/guide/#Declarative-Rendering",
              type: "url",
            },
            {
              key: "0-3",
              label: "Conditionals and Loops",
              data: "https://vuejs.org/v2/guide/#Conditionals-and-Loops",
              type: "url",
            },
          ],
        },
        {
          key: "1",
          label: "Components In-Depth",
          children: [
            {
              key: "1-0",
              label: "Component Registration",
              data: "https://vuejs.org/v2/guide/components-registration.html",
              type: "url",
            },
            {
              key: "1-1",
              label: "Props",
              data: "https://vuejs.org/v2/guide/components-props.html",
              type: "url",
            },
            {
              key: "1-2",
              label: "Custom Events",
              data: "https://vuejs.org/v2/guide/components-custom-events.html",
              type: "url",
            },
            {
              key: "1-3",
              label: "Slots",
              data: "https://vuejs.org/v2/guide/components-slots.html",
              type: "url",
            },
          ],
        },
      ],
    };
  },
  methods: {},
};
</script>

We register the Tree component in main.js .

We set the value prop to the nodes array, which is an array with some objects with the keys , label and children properties.

label has the label text.

children has an array with more node objects.

Conclusion

We can add picklists, tree views, and timelines into our Vue 3 app with the PrimeVue framework.