Categories
Vuetify

Vuetify — Intersection and Mutation Observers

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Intersection Observer

We can add the v-intersect directive to use the Intersection Observer API.

It’s used to detect whether an element is visible within the user’s viewport.

For example, we can use it by writing:

<template>
  <div>
    <div class="d-flex align-center text-center justify-center">
      <v-avatar
        :color="isIntersecting ? 'green' : 'red'"
        class="mr-3 swing-transition"
        size="32"
      ></v-avatar>
    </div>

    <v-responsive class="overflow-y-auto" max-height="400">
      <v-responsive height="200vh" class="d-flex align-center text-center pa-2">
        <v-card
          v-intersect="{
            handler: onIntersect,
            options: {
              threshold: [0, 0.5, 1.0]
            }
          }"
          class="mx-auto"
          max-width="336"
        >
          <v-card-title>Title</v-card-title>
          <v-card-text>
            Lorem ipsum dolor sit amet.
          </v-card-text>
        </v-card>
      </v-responsive>
    </v-responsive>
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    isIntersecting: false,
  }),

  methods: {
    onIntersect(entries, observer) {
      this.isIntersecting = entries[0].intersectionRatio >= 0.5;
    },
  },
};
</script>

We have the v-card inside the v-responsive component.

The overflow-y-auto class lets us scroll the content inside it up and down.

We have another v-responsive component inside it which is taller than the 400px of the outer v-responsive component.

Therefore, we’ll scroll whatever we have inside.

We use the v-intersect directive to let us run a callback when we scroll to check for intersection of the viewport and the card.

The threshold is the portion of the card that’s in the viewport.

The onIntersect method when these thresholds are met.

Now when we scroll, we’ll see the dot change color when the card goes in and out of the viewport.

If we’re using Vuetify with IE11, then we need to add the Intersection Observer API polyfill in order to use this directive.

Mutation Observer

The v-mutate directive uses the Mutation Observer API.

It lets us detect whether an element is updated.

For example, we can write:

<template>
  <div>
    <div>
      <div class="text-center">
        <v-btn [@click](http://twitter.com/click "Twitter profile for @click")="content = !content">Change Content</v-btn>
      </div>

<v-container>
        <v-row>
          <v-col cols="12" md="6">
            <v-card>
              <v-card-title>Card 1</v-card-title>

<div class="title text-center pb-3">Times Mutated: {{ card1 }}</div>

<v-card-text v-mutate="() => onMutate('card1')">
                <p
                  v-for="n in +content + 2"
                  :key="n"
                  :class="n === +content + 2 && 'mb-0'"
                >Phasellus nec sem in justo pellentesque facilisis.</p>
              </v-card-text>
            </v-card>
          </v-col>

<v-col cols="12" md="6">
            <v-card>
              <v-card-title>Card 2</v-card-title>

<div class="title text-center pb-3">Times Mutated: {{ card2 }}</div>

<v-card-text v-mutate.once="() => onMutate('card2')">
                <p
                  v-for="n in +content + 2"
                  :key="n"
                  :class="n === +content + 2 && 'mb-0'"
                >Suspendisse enim turpis.</p>
              </v-card-text>
            </v-card>
          </v-col>
        </v-row>
      </v-container>
    </div>
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    content: false,
    card1: 0,
    card2: 0,
  }),

  methods: {
    onMutate(card) {
      this[card]++;
    },
  },
};
</script>

to detect changes in the cards.

We have the Change Content button to toggle the content state.

In the v-card-text components, we have the v-mutate directive to let us run the onMutate method when we click on the Change Content button.

This is because when the button is clicked, the content value changes.

The card1 and card2 will increment when we click on the Change Content button.

The 2nd card has the once modifier on the v-mutate directive, so card2 will only be incremented once.

Conclusion

We can add the intersection and mutation observers on components with Vuetify directives.

Categories
Vuetify

Vuetify — Treeview Selections

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Treeview Selection Type

There 2 supported types of selection.

The default type is 'leaf' . It’ll include the leaf of the nodes when we select the parent.

The other type is 'independent' , which lets us select all nodes individually.

For example, we can write:

<template>
  <v-container>
    <v-select v-model="selectionType" :items="['leaf', 'independent']" label="Selection type"></v-select>
    <v-row>
      <v-col>
        <v-treeview
          v-model="selection"
          :items="items"
          :selection-type="selectionType"
          selectable
          return-object
          open-all
        ></v-treeview>
      </v-col>
      <v-divider vertical></v-divider>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    selectionType: "leaf",
    selection: [],
    items: [
      {
        id: 1,
        name: "Root",
        children: [
          { id: 2, name: "Child 1" },
          { id: 3, name: "Child 2" },
          {
            id: 4,
            name: "Child 3",
            children: [
              { id: 5, name: "Grandchild 1" },
              { id: 6, name: "Grandchild 2" },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

We have a v-select to let us change the selectionType state between the 2 values.

The state is also used in the selection-type prop to let us make the treeview use the given selection type.

If we choose leaf and select the parent node, then all the descendant nodes will be selected.

If we choose independent , then only the node we clicked on will be selected.

Selectable

We can easily select treeview nodes and their children.

For example, we can write:

<template>
  <v-treeview selectable :items="items"></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Root",
        children: [
          { id: 2, name: "Child 1" },
          { id: 3, name: "Child 2" },
          {
            id: 4,
            name: "Child 3",
            children: [
              { id: 5, name: "Grandchild 1" },
              { id: 6, name: "Grandchild 2" },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

to add the selectable prop to our v-treeview to make the nodes selectable.

Activatable

The treeview nodes can be activated by clicking on them if we add the activable prop to our v-treeview :

<template>
  <v-treeview activatable :items="items"></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Root",
        children: [
          { id: 2, name: "Child 1" },
          { id: 3, name: "Child 2" },
          {
            id: 4,
            name: "Child 3",
            children: [
              { id: 5, name: "Grandchild 1" },
              { id: 6, name: "Grandchild 2" },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

Hoverable

We can make treeview nodes hoverable with the hoverable prop:

<template>
  <v-treeview hoverable :items="items"></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Root",
        children: [
          { id: 2, name: "Child 1" },
          { id: 3, name: "Child 2" },
          {
            id: 4,
            name: "Child 3",
            children: [
              { id: 5, name: "Grandchild 1" },
              { id: 6, name: "Grandchild 2" },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

Conclusion

We can make treeview nodes selectable and hoverable in various ways.

Categories
Vuetify

Vuetify — Treeviews

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Treeview

We can add a treeview with the v-treeview component.

To use it, we can write:

<template>
  <v-treeview :items="items"></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Applications",
        children: [
          { id: 2, name: "Calendar" },
          { id: 3, name: "Chrome" },
        ],
      },
      {
        id: 5,
        name: "Framework",
        children: [
          {
            id: 6,
            name: "vuetify",
            children: [
              {
                id: 7,
                name: "src",
                children: [
                  { id: 8, name: "index" },
                  { id: 9, name: "bootstrap" },
                ],
              },
            ],
          },
          {
            id: 10,
            name: "material",
            children: [
              {
                id: 11,
                name: "src",
                children: [
                  { id: 12, name: "v-btn" },
                  { id: 13, name: "v-card" },
                ],
              },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

We have the items state with an array of items in it.

Each object has the id and name properties with the Node ID and name to display.

And the children property has an array with objects with the same properties.

Then we just pass that to the v-treeview ‘s item prop.

Dense Mode

We can make the entries take up less space with the dense prop:

<template>
  <v-treeview :items="items" dense></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Applications",
        children: [
          { id: 2, name: "Calendar" },
          { id: 3, name: "Chrome" },
        ],
      },
      {
        id: 5,
        name: "Framework",
        children: [
          {
            id: 6,
            name: "vuetify",
            children: [
              {
                id: 7,
                name: "src",
                children: [
                  { id: 8, name: "index" },
                  { id: 9, name: "bootstrap" },
                ],
              },
            ],
          },
          {
            id: 10,
            name: "material",
            children: [
              {
                id: 11,
                name: "src",
                children: [
                  { id: 12, name: "v-btn" },
                  { id: 13, name: "v-card" },
                ],
              },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

Color

The text and background color of the entries can be changed:

<template>
  <v-treeview :items="items" color="primary" activatable></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Applications",
        children: [
          { id: 2, name: "Calendar" },
          { id: 3, name: "Chrome" },
        ],
      },
      {
        id: 5,
        name: "Framework",
        children: [
          {
            id: 6,
            name: "vuetify",
            children: [
              {
                id: 7,
                name: "src",
                children: [
                  { id: 8, name: "index" },
                  { id: 9, name: "bootstrap" },
                ],
              },
            ],
          },
          {
            id: 10,
            name: "material",
            children: [
              {
                id: 11,
                name: "src",
                children: [
                  { id: 12, name: "v-btn" },
                  { id: 13, name: "v-card" },
                ],
              },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

We added the activatable and the color props so that the background color is shown when we click on the entry.

Conclusion

Vuetify comes with a treeview component to let us display items in a tree.

Categories
Vuetify

Vuetify — Treeview Customizations

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Shaped

We can make a treeview with rounded borders on one side of the nodes.

For instance, we can write:

<template>
  <v-treeview :items="items" shaped hoverable activatable></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Applications",
        children: [
          { id: 2, name: "Calendar" },
          { id: 3, name: "Chrome" },
        ],
      },
      {
        id: 5,
        name: "Framework",
        children: [
          {
            id: 6,
            name: "vuetify",
            children: [
              {
                id: 7,
                name: "src",
                children: [
                  { id: 8, name: "index" },
                  { id: 9, name: "bootstrap" },
                ],
              },
            ],
          },
          {
            id: 10,
            name: "material",
            children: [
              {
                id: 11,
                name: "src",
                children: [
                  { id: 12, name: "v-btn" },
                  { id: 13, name: "v-card" },
                ],
              },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

Then the corners will be rounded on the right side.

Rounded

The treeview nodes can be made rounded with the rounded prop:

<template>
  <v-treeview :items="items" rounded hoverable activatable></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Applications",
        children: [
          { id: 2, name: "Calendar" },
          { id: 3, name: "Chrome" },
        ],
      },
      {
        id: 5,
        name: "Framework",
        children: [
          {
            id: 6,
            name: "vuetify",
            children: [
              {
                id: 7,
                name: "src",
                children: [
                  { id: 8, name: "index" },
                  { id: 9, name: "bootstrap" },
                ],
              },
            ],
          },
          {
            id: 10,
            name: "material",
            children: [
              {
                id: 11,
                name: "src",
                children: [
                  { id: 12, name: "v-btn" },
                  { id: 13, name: "v-card" },
                ],
              },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

Disabling Nodes

We can disable nodes with the item-disabled prop.

The value of the prop is the property name that indicates the item is disabled.

For example, we can write:

<template>
  <v-treeview :items="items" selectable item-disabled="locked"></v-treeview>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        name: "Applications",
        children: [
          { id: 2, name: "Calendar" },
          { id: 3, name: "Chrome", locked: true },
        ],
      },
      {
        id: 5,
        name: "Framework",
        locked: true,
        children: [
          {
            id: 6,
            name: "vuetify",
            children: [
              {
                id: 7,
                name: "src",
                children: [
                  { id: 8, name: "index" },
                  { id: 9, name: "bootstrap", locked: true },
                ],
              },
            ],
          },
          {
            id: 10,
            name: "material",
            children: [
              {
                id: 11,
                name: "src",
                children: [
                  { id: 12, name: "v-btn", locked: true },
                  { id: 13, name: "v-card" },
                ],
              },
            ],
          },
        ],
      },
    ],
  }),
};
</script>

to make the locked property disable items on the treeview.

Conclusion

We can change the shape of a treeview and disable items with Vuetify.

Categories
Vuetify

Vuetify — Timelines

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Timelines

We can use the v-timeline component to display data chronologically.

For example, we can write:

<template>
  <v-timeline :dense="$vuetify.breakpoint.smAndDown">
    <v-timeline-item color="purple lighten-2" fill-dot right>
      <v-card>
        <v-card-title class="purple lighten-2">
          <v-icon dark size="42" class="mr-4">mdi-magnify</v-icon>
          <h2 class="display-1 white--text font-weight-light">Title 1</h2>
        </v-card-title>
        <v-container>
          <v-row>
            <v-col cols="12" md="10">Lorem ipsum dolor sit amet, no nam oblique veritus.</v-col>
            <v-col class="hidden-sm-and-down text-right" md="2">
              <v-icon size="64">mdi-calendar-text</v-icon>
            </v-col>
          </v-row>
        </v-container>
      </v-card>
    </v-timeline-item>

    <v-timeline-item color="amber lighten-1" fill-dot left small>
      <v-card>
        <v-card-title class="amber lighten-1 justify-end">
          <h2 class="display-1 mr-4 white--text font-weight-light">Title 2</h2>
          <v-icon dark size="42">mdi-home-outline</v-icon>
        </v-card-title>
        <v-container>
          <v-row>
            <v-col cols="12" md="8">Lorem ipsum dolor sit amet.</v-col>
          </v-row>
        </v-container>
      </v-card>
    </v-timeline-item>

    <v-timeline-item color="cyan lighten-1" fill-dot right>
      <v-card>
        <v-card-title class="cyan lighten-1">
          <v-icon class="mr-4" dark size="42">mdi-email-outline</v-icon>
          <h2 class="display-1 white--text font-weight-light">Title 3</h2>
        </v-card-title>
        <v-container>
          <v-row>
            <v-col v-for="n in 3" :key="n" cols="12" md="4">Lorem ipsum dolor sit amet.</v-col>
          </v-row>
        </v-container>
      </v-card>
    </v-timeline-item>
  </v-timeline>
</template>
<script>
export default {
  name: "HelloWorld",
};
</script>

We have the v-timeline component with the v-timeline-item components inside it.

The v-timeline-item has the cards to display the content we want.

The v-card-title has the title.

And v-container has the content.

The right prop makes the entry display to the right of the line.

The left prop makes the entry display to the left of the line.

fill-dot makes the dot filled.

Icon Dots

We can change the dots on the timeline to be icons instead.

For example, we can write:

<template>
  <v-timeline align-top :dense="$vuetify.breakpoint.smAndDown">
    <v-timeline-item
      v-for="(item, i) in items"
      :key="i"
      :color="item.color"
      :icon="item.icon"
      fill-dot
    >
      <v-card :color="item.color" dark>
        <v-card-title class="title">Lorem Ipsum Dolor</v-card-title>
        <v-card-text class="white text--primary">
          <p>Lorem ipsum dolor sit amet.</p>
          <v-btn :color="item.color" class="mx-0" outlined>Button</v-btn>
        </v-card-text>
      </v-card>
    </v-timeline-item>
  </v-timeline>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        color: "red lighten-2",
        icon: "mdi-star",
      },
      {
        color: "purple darken-1",
        icon: "mdi-book-variant",
      },
      {
        color: "green lighten-1",
        icon: "mdi-airballoon",
      },
    ],
  }),
};
</script>

We render the items with the v-timeline-item by setting the icon prop to set the icon name to display.

The color prop also changes the color.

Conclusion

We can add a timeline to display items in chronological order