Skip to content

Customizing Toolbar

Overview of the Toolbar

Vue PDF Viewer features a flexible toolbar that consists of two main components: a top bar and a left sidebar. These provide an intuitive interface for navigating and interacting with PDF documents.

By default, all tools are enabled, giving users immediate access to the full range of features out-of-the-box without any additional configurations. However, Vue PDF Viewer also offers customization options, allowing you to tailor the toolbar to fit your specific use case.

Let’s take a closer look at the tutorial below to learn how to customize and adapt the toolbar to your needs.

To get started, explore the available configuration options in the Toolbar Options documentation.

Show/Hide Top Bar and Left Sidebar

Change Visibility of Top Bar

The top bar can be shown or hidden by changing the :toolbar-options property. Setting it to true will display the top bar (the default setting), while setting it to false will hide it. This feature provides flexibility for users to customize the interface based on their needs or preferences.

vue
<VPdfViewer :src="samplePDF" :toolbar-options="false" />

Example of a top bar and left sidebar is hidden

Change Visibility of Left Sidebar

The sidebarEnable is a property that can be used in conjunction with the :toolbar-options property to control the visibility of the left sidebar.

INFO

There are specific conditions regarding the top bar and left sidebar visibility:

  • The left sidebar can be hidden without affecting the visibility of the top bar.
  • When the :toolbar-options property is set to false, the left sidebar is automatically hidden, as it cannot function independently without the top bar.

To hide the left sidebar without hiding the top bar, use the following setting:

vue
<VPdfViewer
    :src="samplePDF"
    :toolbar-options="{
        sidebarEnable: false,
    }" 
/>

Example of left sidebar hidden

Show/Hide Icons on Top Bar

Change Visibility of Each Icon

You can easily control the visibility of top bar icons in Vue PDF Viewer by toggling their respective settings. Use the toolbar-options prop to specify which icons should appear on the top bar.

Here’s how you can configure the top bar:

vue
<VPdfViewer
    :src="samplePDF"
    :toolbar-options="{
        themeSwitchable: false,
        newFileOpenable: false,
        downloadable: false,
        printable: false,
        fullscreen: false,
    }" 
/>

Example of each icon hidden

For a full list of available toolbar options and their descriptions, see the Toolbar Options documentation.

Customize Icons in the Toolbar

Vue PDF Viewer provides slots for you to customize the icons in the top toolbar. This feature gives you the flexibility to replace default icons with your own, ensuring the toolbar aligns with your application’s design.

For a complete list of slots available for each icon, refer to the Slots - Icons documentation.

Changing Icons on the Top Bar

To change an icon in the top bar, you can use a slot in the template to replace the default icon with your own custom content. For example, you can replace it with an image:

vue
<VPdfViewer :src="samplePDF">
  <template #iconThemeDark>
      <img src="../assets/your-image.png" />
  </template>
</VPdfViewer>

Alternatively, you can use text as an icon, such as "Moon" or any other label.

vue
<VPdfViewer :src="samplePDF">
  <template #iconThemeDark>
    Moon
  </template>
</VPdfViewer>

Here is an example, using the following settings to try it for yourself:

vue
<VPdfViewer :src="samplePDF">
  <template #iconThemeDark>
      <img src="../assets/your-image.png" />
  </template>
  
  <template #iconOpenFile>
      <img src="../assets/your-image.png" />
  </template>
  
  <template #iconDownload>
      <img src="../assets/your-image.png" />
  </template>
  
  <template #iconPrint>
      <img src="../assets/your-image.png" />
  </template>
  
  <template #iconFullScreen>
      <img src="../assets/your-image.png" />
  </template>
</VPdfViewer>

Example of each top bar icon replaced

Changing Icon in More Options Menu

You can also customize the icons within the More Options menu using the same approach as the example above. Simply use the appropriate slots to replace the default icons with your custom designs.

Give this example a try to see it in action:

vue
<VPdfViewer :src="jpPDF">
  <template #iconFirstPage>
    <img src="../assets/your-img.png" />
  </template>

  <template #iconLastPage>
    <img src="../assets/your-img.png" />
  </template>

  <template #iconRotateClockwise>
    <img src="../assets/your-img.png" />
  </template>

  <template #iconRotateCounterClockwise>
    <img src="../assets/your-img" />
  </template>

  <template #iconTextSelection>
    <img src="../assets/your-img" />
  </template>

  <!-- and so on... -->
</VPdfViewer>

Example of each more options icon replaced

Extend or Modify Tool Functions

Vue PDF Viewer allows you to override the behavior of a tool in the toolbar to extend or modify their default functionality based on your application's needs.

For a complete list of slots available for customizing tools, refer to the Slots - Tools documentation.

Example: Customizing the zoomTool

You can use the zoomTool slot to customize how the zoom functionality behaves in the viewer. In this example, custom buttons are added to adjust the zoom scale. The zoom function is used to increase or decrease the zoom level by a specified amount, and the currentScale is displayed in the middle.

vue
<VPdfViewer :src="samplePDF">
  <template #zoomTool="{ currentScale, zoom }">
      <button @click="zoom(currentScale - 2)">ZoomOut</button>
      <strong>{{ currentScale }}</strong>
      <button @click="zoom(currentScale + 5)">ZoomIn</button>
  </template>
</VPdfViewer>
  • The Zoom Out button decreases the zoom level by 2.
  • The Zoom In button increases the zoom level by 5.
  • The current scale value is displayed between the buttons to show the current zoom level.

Example of result when customizing zoomTool

Example: Customizing the loaderImage

You can also change the loader image to customize the appearance. Use the loaderImage slot as shown below:

vue
<VPdfViewer :src="samplePDF">
    <template #loaderImage>
       <img src="/your-image.png" width="80" height="80" />
    </template>
</VPdfViewer>

Example of loader replaced

Using Custom Buttons/Icons with Instance API

Certain tools within the toolbar and More Options menu expose an Instance API, enabling advanced control and customization. These APIs allow developers to interact with and modify the behavior of specific tools directly from the parent component.

The methods are exposed through Vue's defineExpose() and can be accessed via a ref in the parent component. This setup allows developers to dynamically trigger actions, such as adjusting zoom levels, toggling visibility, or navigating pages. For a detailed list of available configuration options, refer to the Instance API documentation.

Show Tool from 'More Options' in the Top Bar

By default, the tools available in the 'More Options' menu are not shown in the top bar. However, you can use the Vue PDF Viewer’s Instance API to selectively display specific tools directly in the top bar, providing a more tailored user experience.

Example: Displaying Rotate Tool on Top Bar

By default, the Rotate Clockwise and Rotate Counterclockwise tools are located within the More Options menu. This example demonstrates how to use the Instance API to display these tools directly on the top bar for better accessibility.

Step 1: Access the Rotate Controller

First, create a rotateControl variable to reference the rotate controller provided by the Instance API. This will allow you to interact with the rotation functionality programmatically.

vue
const rotateControl = computed(() => vpvRef.value?.rotateControl);
vue
const rotateControl = computed(() => vpvRef.value?.rotateControl);
vue
computed: {
  rotateControl() {
    return this.$refs.vpvRef ? this.$refs.vpvRef.rotateControl : null;
  },
}
vue
computed: {
  rotateControl() {
    return this.$refs.vpvRef ? this.$refs.vpvRef.rotateControl : null;
  },
}
Step 2: Define Rotation Functions

Next, create two functions, rotateClockwise and rotateCounterClockwise, to invoke the rotation actions from the controller. These functions will call the respective methods of the rotateControl object.

vue
const rotateClockwise = () => {
  if (!rotateControl.value) {
    return;
  }
  rotateControl.value.rotateClockwise();
};

const rotateCounterClockwise = () => {
  if (!rotateControl.value) {
    return;
  }
  rotateControl.value.rotateCounterclockwise();
};
vue
const rotateClockwise = () => {
  if (!rotateControl.value) {
    return;
  }
  rotateControl.value.rotateClockwise();
};

const rotateCounterClockwise = () => {
  if (!rotateControl.value) {
    return;
  }
  rotateControl.value.rotateCounterclockwise();
};
vue
methods: {
  rotateClockwise() {
    if (!this.rotateControl) {
      return;
    }
    this.rotateControl.rotateClockwise();
  },
  rotateCounterClockwise() {
    if (!this.rotateControl) {
      return;
    }
    this.rotateControl.rotateCounterclockwise();
  }
}
vue
methods: {
  rotateClockwise() {
    if (!this.rotateControl) {
      return;
    }
    this.rotateControl.rotateClockwise();
  },
  rotateCounterClockwise() {
    if (!this.rotateControl) {
      return;
    }
    this.rotateControl.rotateCounterclockwise();
  }
}
Step 3: Add Custom Buttons to the Top Bar

Use Vue’s onMounted lifecycle hook to programmatically add custom buttons for rotation into the top bar. These buttons will be prepended to the toolbar using DOM manipulation.

vue
onMounted(() => {
  // Ensure the viewer is loaded before manipulating DOM
  const toolbarEnd = vpvRef.value?.$el.querySelector(".vpv-toolbar-end");
  if (toolbarEnd && customRotateClockwiseButton.value) {
    // Prepend the custom button to the toolbar-end
    toolbarEnd.insertBefore(
      customRotateClockwiseButton.value,
      toolbarEnd.firstChild
    );
    toolbarEnd.insertBefore(
      customRotateCounterClockwiseButton.value,
      toolbarEnd.firstChild
    );
  }
});
vue
onMounted(() => {
  // Ensure the viewer is loaded before manipulating DOM
  const toolbarEnd = vpvRef.value?.$el.querySelector(".vpv-toolbar-end");
  if (toolbarEnd && customRotateClockwiseButton.value) {
    // Prepend the custom button to the toolbar-end
    toolbarEnd.insertBefore(
      customRotateClockwiseButton.value,
      toolbarEnd.firstChild
    );
    toolbarEnd.insertBefore(
      customRotateCounterClockwiseButton.value,
      toolbarEnd.firstChild
    );
  }
});
vue
mounted() {
  // Ensure the viewer is loaded before manipulating DOM
  const toolbarEnd = this.$refs.vpvRef.$el.querySelector('.vpv-toolbar-end');
  if (toolbarEnd && this.$refs.customRotateClockwiseButton) {
    // Prepend the custom buttons to the toolbar-end
    toolbarEnd.insertBefore(
      this.$refs.customRotateClockwiseButton,
      toolbarEnd.firstChild
    );
    toolbarEnd.insertBefore(
      this.$refs.customRotateCounterClockwiseButton,
      toolbarEnd.firstChild
    );
  }
}
vue
mounted() {
  // Ensure the viewer is loaded before manipulating DOM
  const toolbarEnd = this.$refs.vpvRef.$el.querySelector('.vpv-toolbar-end');
  if (toolbarEnd && this.$refs.customRotateClockwiseButton) {
    // Prepend the custom buttons to the toolbar-end
    toolbarEnd.insertBefore(
      this.$refs.customRotateClockwiseButton,
      toolbarEnd.firstChild
    );
    toolbarEnd.insertBefore(
      this.$refs.customRotateCounterClockwiseButton,
      toolbarEnd.firstChild
    );
  }
}
Step 4: Create the Template

Finally, define the VPdfViewer component and the custom rotate buttons in the template. Use icons to visually represent the rotation actions.

vue
<template>
  <div style="height: 660px">
    <VPdfViewer ref="vpvRef" :src="jpPDF" />
    <button
      ref="customRotateClockwiseButton"
      type="text"
      @click="rotateCounterClockwise"
    >

    </button>
    <button
      ref="customRotateCounterClockwiseButton"
      type="text"
      @click="rotateClockwise"
    >

    </button>
  </div>
</template>
vue
<template>
  <div style="height: 660px">
    <VPdfViewer ref="vpvRef" :src="jpPDF" />
    <button
      ref="customRotateClockwiseButton"
      type="text"
      @click="rotateCounterClockwise"
    >

    </button>
    <button
      ref="customRotateCounterClockwiseButton"
      type="text"
      @click="rotateClockwise"
    >

    </button>
  </div>
</template>
vue
<template>
  <div style="height: 660px">
    <VPdfViewer ref="vpvRef" :src="jpPDF" />
    <button
      ref="customRotateClockwiseButton"
      type="text"
      @click="rotateCounterClockwise"
    >

    </button>
    <button
      ref="customRotateCounterClockwiseButton"
      type="text"
      @click="rotateClockwise"
    >

    </button>
  </div>
</template>
vue
<template>
  <div style="height: 660px">
    <VPdfViewer ref="vpvRef" :src="jpPDF" />
    <button
      ref="customRotateClockwiseButton"
      type="text"
      @click="rotateCounterClockwise"
    >

    </button>
    <button
      ref="customRotateCounterClockwiseButton"
      type="text"
      @click="rotateClockwise"
    >

    </button>
  </div>
</template>
Full codes for this example:
vue
<script setup lang="ts">
import { ref, computed, h, onMounted } from "vue";
import { VPdfViewer } from "@vue-pdf-viewer/viewer";
    
const vpvRef = ref<InstanceType<typeof VPdfViewer>>();
const rotateControl = computed(() => vpvRef.value?.rotateControl);
    
const rotateClockwise = () => {
  if (!rotateControl.value) {
    return;
  }
  rotateControl.value.rotateClockwise();
};

const rotateCounterClockwise = () => {
  if (!rotateControl.value) {
    return;
  }
  rotateControl.value.rotateCounterclockwise();
};
    
const customRotateClockwiseButton = ref(null);
const customRotateCounterClockwiseButton = ref(null);

onMounted(() => {
  // Ensure the viewer is loaded before manipulating DOM
  const toolbarEnd = vpvRef.value?.$el.querySelector(".vpv-toolbar-end");
  if (toolbarEnd && customRotateClockwiseButton.value) {
    // Prepend the custom button to the toolbar-end
    toolbarEnd.insertBefore(
      customRotateClockwiseButton.value,
      toolbarEnd.firstChild
    );
    toolbarEnd.insertBefore(
      customRotateCounterClockwiseButton.value,
      toolbarEnd.firstChild
    );
  }
});
</script>

<template>
  <div style="height: 660px">
    <VPdfViewer ref="vpvRef" :src="jpPDF" />
    <button
      ref="customRotateClockwiseButton"
      type="text"
      @click="rotateCounterClockwise"
    >

    </button>
    <button
      ref="customRotateCounterClockwiseButton"
      type="text"
      @click="rotateClockwise"
    >

    </button>
  </div>
</template>
vue
<script setup>
import { ref, computed, h, onMounted } from "vue";
import { VPdfViewer } from "@vue-pdf-viewer/viewer";
    
const vpvRef = ref(null);
const rotateControl = computed(() => vpvRef.value?.rotateControl);
    
const rotateClockwise = () => {
  if (!rotateControl.value) {
    return;
  }
  rotateControl.value.rotateClockwise();
};

const rotateCounterClockwise = () => {
  if (!rotateControl.value) {
    return;
  }
  rotateControl.value.rotateCounterclockwise();
};
    
const customRotateClockwiseButton = ref(null);
const customRotateCounterClockwiseButton = ref(null);

onMounted(() => {
  // Ensure the viewer is loaded before manipulating DOM
  const toolbarEnd = vpvRef.value?.$el.querySelector(".vpv-toolbar-end");
  if (toolbarEnd && customRotateClockwiseButton.value) {
    // Prepend the custom button to the toolbar-end
    toolbarEnd.insertBefore(
      customRotateClockwiseButton.value,
      toolbarEnd.firstChild
    );
    toolbarEnd.insertBefore(
      customRotateCounterClockwiseButton.value,
      toolbarEnd.firstChild
    );
  }
});
</script>

<template>
  <div style="height: 660px">
    <VPdfViewer ref="vpvRef" :src="jpPDF" />
    <button
      ref="customRotateClockwiseButton"
      type="text"
      @click="rotateCounterClockwise"
    >

    </button>
    <button
      ref="customRotateCounterClockwiseButton"
      type="text"
      @click="rotateClockwise"
    >

    </button>
  </div>
</template>
vue
<script lang="ts">
import { VPdfViewer } from '@vue-pdf-viewer/viewer';

export default {
  components: {
    VPdfViewer,
  },
    
  data() {
    return {
      vpvRef: null,
      customRotateClockwiseButton: null,
      customRotateCounterClockwiseButton: null
    };
  },
    
  computed: {
    rotateControl() {
      return this.$refs.vpvRef ? this.$refs.vpvRef.rotateControl : null;
    }
  },
    
  methods: {
    rotateClockwise() {
      if (!this.rotateControl) {
        return;
      }
      this.rotateControl.rotateClockwise();
    },
    rotateCounterClockwise() {
      if (!this.rotateControl) {
        return;
      }
      this.rotateControl.rotateCounterclockwise();
    }
  },
    
  mounted() {
    // Ensure the viewer is loaded before manipulating DOM
    const toolbarEnd = this.$refs.vpvRef.$el.querySelector('.vpv-toolbar-end');
    if (toolbarEnd && this.$refs.customRotateClockwiseButton) {
      // Prepend the custom buttons to the toolbar-end
      toolbarEnd.insertBefore(
        this.$refs.customRotateClockwiseButton,
        toolbarEnd.firstChild
      );
      toolbarEnd.insertBefore(
        this.$refs.customRotateCounterClockwiseButton,
        toolbarEnd.firstChild
      );
    }
  }
};
</script>

<template>
  <div style="height: 660px">
    <VPdfViewer ref="vpvRef" :src="jpPDF" />
    <button
      ref="customRotateClockwiseButton"
      type="text"
      @click="rotateCounterClockwise"
    >

    </button>
    <button
      ref="customRotateCounterClockwiseButton"
      type="text"
      @click="rotateClockwise"
    >

    </button>
  </div>
</template>
vue
<script>
import { VPdfViewer } from '@vue-pdf-viewer/viewer';

export default {
  components: {
    VPdfViewer,
  },
    
  data() {
    return {
      vpvRef: null,
      customRotateClockwiseButton: null,
      customRotateCounterClockwiseButton: null
    };
  },
    
  computed: {
    rotateControl() {
      return this.$refs.vpvRef ? this.$refs.vpvRef.rotateControl : null;
    }
  },
    
  methods: {
    rotateClockwise() {
      if (!this.rotateControl) {
        return;
      }
      this.rotateControl.rotateClockwise();
    },
    rotateCounterClockwise() {
      if (!this.rotateControl) {
        return;
      }
      this.rotateControl.rotateCounterclockwise();
    }
  },
    
  mounted() {
    // Ensure the viewer is loaded before manipulating DOM
    const toolbarEnd = this.$refs.vpvRef.$el.querySelector('.vpv-toolbar-end');
    if (toolbarEnd && this.$refs.customRotateClockwiseButton) {
      // Prepend the custom buttons to the toolbar-end
      toolbarEnd.insertBefore(
        this.$refs.customRotateClockwiseButton,
        toolbarEnd.firstChild
      );
      toolbarEnd.insertBefore(
        this.$refs.customRotateCounterClockwiseButton,
        toolbarEnd.firstChild
      );
    }
  }
};
</script>

<template>
  <div style="height: 660px">
    <VPdfViewer ref="vpvRef" :src="jpPDF" />
    <button
      ref="customRotateClockwiseButton"
      type="text"
      @click="rotateCounterClockwise"
    >

    </button>
    <button
      ref="customRotateCounterClockwiseButton"
      type="text"
      @click="rotateClockwise"
    >

    </button>
  </div>
</template>

Image of rotate tool on top bar

Custom Buttons in Parent Component

With the Instance API, you can invoke key features like rotating pages, zooming, or navigating through the document without relying solely on the viewer's built-in UI. This approach is particularly useful for users who need to customize specific designs or meet unique usability requirements.

Example: External button to trigger Rotate Function

Vue PDF Viewer provides a Rotate Controller through its Instance API, enabling you to control page rotation from outside the viewer. This flexibility allows you to integrate rotation controls into custom buttons or external components, making the viewer adaptable to your application’s needs.

Here are the available functions for managing page rotation using the Rotate Controller.

vue
<script setup lang="ts">
import { ref, computed } from "vue";
import { VPdfViewer } from "@vue-pdf-viewer/viewer";
    
   const vpvRef = ref<InstanceType<typeof VPdfViewer>>();
   const samplePDF = ref('ur-pdf-file.pdf');
   const rotateControl = computed(() => vpvRef.value?.rotateControl)
   const currentRotate = computed(() => {
    return rotateControl.value?.currentRotation
  })

  const rotateClockwise = () => {
    if (!rotateControl.value) {
      return
    }
    rotateControl.value.rotateClockwise()
  }

  const rotateCounterClockwise = () => {
    if (!rotateControl.value) {
      return
    }
    rotateControl.value.rotateCounterclockwise()
  }
</script>

<template>
   <div>
     <button @click="rotateClockwise">clockwise</button>
   </div>

   <div>
     <button @click="rotateCounterClockwise">counterclockwise</button>
   </div>
    
   <div>
     <p>currentRotate{{ currentRotate }}</p>
   </div>
    
   <VPdfViewer ref="vpvRef" :src="samplePDF" />
</template>
vue
<script setup>
  import { VPdfViewer } from '@vue-pdf-viewer/viewer';
  import { ref } from 'vue';

  const vpvRef = ref(null);
  const samplePDF = ref('ur-pdf-file.pdf');
  const rotateControl = computed(() => vpvRef.value?.rotateControl)
  const currentRotate = computed(() => {
    return rotateControl.value?.currentRotation
  })

  const rotateClockwise = () => {
    if (!rotateControl.value) {
      return
    }
    rotateControl.value.rotateClockwise()
  }

  const rotateCounterClockwise = () => {
    if (!rotateControl.value) {
      return
    }
    rotateControl.value.rotateCounterclockwise()
  }
</script>

<template>
   <div>
     <button @click="rotateClockwise">clockwise</button>
   </div>

   <div>
     <button @click="rotateCounterClockwise">counterclockwise</button>
   </div>
    
   <div>
     <p>currentRotate{{ currentRotate }}</p>
   </div>
    
   <VPdfViewer ref="vpvRef" :src="samplePDF" />
</template>
vue
<script lang="ts">
import { VPdfViewer } from '@vue-pdf-viewer/viewer';

export default {
  components: {
    VPdfViewer
  },
  data() {
    return {
      vpvRef: null,
      samplePDF: 'ur-pdf-file.pdf',
    };
  },
  computed: {
    rotateControl() {
      return this.$refs.vpvRef?.rotateControl;
    },
    currentRotate() {
      return this.rotateControl?.currentRotation;
    }
  },
  methods: {
    rotateClockwise() {
      if (!this.rotateControl) {
        return;
      }
      this.rotateControl.rotateClockwise();
    },
    rotateCounterClockwise() {
      if (!this.rotateControl) {
        return;
      }
      this.rotateControl.rotateCounterclockwise();
    }
  }
}
</script>

<template>
  <div>
    <div>
      <button @click="rotateClockwise">clockwise</button>
    </div>
    <div>
      <button @click="rotateCounterClockwise">counterclockwise</button>
    </div>
    <div>
      <p>currentRotate {{ currentRotate }}</p>
    </div>
    <VPdfViewer ref="vpvRef" :src="samplePDF" />
  </div>
</template>
vue
<script>
import { VPdfViewer } from '@vue-pdf-viewer/viewer';

export default {
  components: {
    VPdfViewer
  },
  data() {
    return {
      vpvRef: null,
      samplePDF: 'ur-pdf-file.pdf',
    };
  },
  computed: {
    rotateControl() {
      return this.$refs.vpvRef?.rotateControl;
    },
    currentRotate() {
      return this.rotateControl?.currentRotation;
    }
  },
  methods: {
    rotateClockwise() {
      if (!this.rotateControl) {
        return;
      }
      this.rotateControl.rotateClockwise();
    },
    rotateCounterClockwise() {
      if (!this.rotateControl) {
        return;
      }
      this.rotateControl.rotateCounterclockwise();
    }
  }
}
</script>

<template>
  <div>
    <div>
      <button @click="rotateClockwise">clockwise</button>
    </div>
    <div>
      <button @click="rotateCounterClockwise">counterclockwise</button>
    </div>
    <div>
      <p>currentRotate {{ currentRotate }}</p>
    </div>
    <VPdfViewer ref="vpvRef" :src="samplePDF" />
  </div>
</template>

Example of external button to trigger Rotate Function

Example: Using Rotate Instance API with VPdfViewer in child component

When using VPdfViewer in a child component, the Rotate Instance API can be exposed to a parent component and invoked directly from the parent. This setup provides flexibility for implementing custom rotation controls.

Step 1: Define Methods to Control the PDF Viewer in Child Component

vue
const vpvRef = ref<InstanceType<typeof VPdfViewer>>();
const rotateClockwise = () => vpvRef.value?.rotateControl?.rotateClockwise();
const rotateCounterClockwise = () =>
  vpvRef.value?.rotateControl?.rotateCounterclockwise();
const getCurrentRotation = () => vpvRef.value?.rotateControl?.currentRotation;
vue
const vpvRef = ref(null);
const rotateClockwise = () => vpvRef.value?.rotateControl?.rotateClockwise();
const rotateCounterClockwise = () =>
  vpvRef.value?.rotateControl?.rotateCounterclockwise();
const getCurrentRotation = () => vpvRef.value?.rotateControl?.currentRotation;
vue
methods: {
  rotateClockwise() {
    this.$refs.vpvRef.rotateControl.rotateClockwise();
  },
    
  rotateCounterClockwise() {
    this.$refs.vpvRef.rotateControl.rotateCounterclockwise();
  },
    
  getCurrentRotation() {
    return this.$refs.vpvRef.rotateControl.currentRotation;
  }
}
vue
methods: {
  rotateClockwise() {
    this.$refs.vpvRef.rotateControl.rotateClockwise();
  },
    
  rotateCounterClockwise() {
    this.$refs.vpvRef.rotateControl.rotateCounterclockwise();
  },
    
  getCurrentRotation() {
    return this.$refs.vpvRef.rotateControl.currentRotation;
  }
}
  • rotateClockwise: Calls the rotateClockwise() method from the rotateControl object to rotate the PDF in the clockwise direction.
  • rotateCounterClockwise: Calls the rotateCounterclockwise() method from the rotateControl object to rotate the PDF in the counterclockwise direction.
  • getCurrentRotation: Retrieves the current rotation value from the rotateControl object.

Step 2: Expose Methods to Parent Component

vue
defineExpose({
  rotateClockwise,
  rotateCounterClockwise,
  getCurrentRotation,
});
vue
defineExpose({
  rotateClockwise,
  rotateCounterClockwise,
  getCurrentRotation,
});
vue
export default {
  components: {
    VPdfViewer
  },
    
  data() {
    return {
      samplePDF: 'your-pdf.pdf',
      vpvRef: null,
    };
  },
    
  methods: {
    rotateClockwise() {
      this.$refs.vpvRef.rotateControl.rotateClockwise();
    },
      
    rotateCounterClockwise() {
      this.$refs.vpvRef.rotateControl.rotateCounterclockwise();
    },
      
    getCurrentRotation() {
      return this.$refs.vpvRef.rotateControl.currentRotation;
    }
  }
};
vue
export default {
  components: {
    VPdfViewer
  },
    
  data() {
    return {
      samplePDF: 'your-pdf.pdf',
      vpvRef: null,
    };
  },
    
  methods: {
    rotateClockwise() {
      this.$refs.vpvRef.rotateControl.rotateClockwise();
    },
      
    rotateCounterClockwise() {
      this.$refs.vpvRef.rotateControl.rotateCounterclockwise();
    },
      
    getCurrentRotation() {
      return this.$refs.vpvRef.rotateControl.currentRotation;
    }
  }
};
  • defineExpose: For Composition API, defineExpose exposes the rotateClockwise, rotateCounterClockwise, and getCurrentRotation methods to the parent component (eg., App.vue) so that they can be called from there.

Step 3: Call Exposed Methods in Parent Component

vue
const vpvRef = ref(null);
const rotateClockwise = () => vpvRef.value?.rotateClockwise();
const rotateCounterClockwise = () => vpvRef.value?.rotateCounterClockwise();
const getCurrentRotation = () => vpvRef.value?.getCurrentRotation();
vue
const vpvRef = ref(null);
const rotateClockwise = () => vpvRef.value?.rotateClockwise();
const rotateCounterClockwise = () => vpvRef.value?.rotateCounterClockwise();
const getCurrentRotation = () => vpvRef.value?.getCurrentRotation();
vue
methods: {
  rotateClockwise() {
    this.$refs.vpvRef.rotateClockwise();
  },
    
  rotateCounterClockwise() {
    this.$refs.vpvRef.rotateCounterClockwise();
  },
    
  getCurrentRotation() {
    return this.$refs.vpvRef.getCurrentRotation();
  }
}
vue
methods: {
  rotateClockwise() {
    this.$refs.vpvRef.rotateClockwise();
  },
    
  rotateCounterClockwise() {
    this.$refs.vpvRef.rotateCounterClockwise();
  },
    
  getCurrentRotation() {
    return this.$refs.vpvRef.getCurrentRotation();
  }
}
  • rotateClockwise: Calls the rotateClockwise method in the PdfViewer component using the reference (vpvRef).
  • rotateCounterClockwise: Calls the rotateCounterClockwise method in the PdfViewer component using the reference (vpvRef).
  • getCurrentRotation: Calls the getCurrentRotation method to get the current rotation state of the PDF.

Step 4: Invoke Methods in the Template of Parent Component

vue
<template>
   <div>
     <button @click="rotateClockwise">Rotate Clockwise</button>
     <button @click="rotateCounterClockwise">Rotate Counterclockwise</button>
   </div>
   <div>
     <p>Current Rotation: {{ getCurrentRotation() }}</p>
   </div>
    
   <PdfViewer ref="vpvRef" />
</template>
vue
<template>
   <div>
     <button @click="rotateClockwise">Rotate Clockwise</button>
     <button @click="rotateCounterClockwise">Rotate Counterclockwise</button>
   </div>
   <div>
     <p>Current Rotation: {{ getCurrentRotation() }}</p>
   </div>
    
   <PdfViewer ref="vpvRef" />
</template>
vue
<template>
   <div>
     <button @click="rotateClockwise">Rotate Clockwise</button>
     <button @click="rotateCounterClockwise">Rotate Counterclockwise</button>
   </div>
   <div>
     <p>Current Rotation: {{ getCurrentRotation() }}</p>
   </div>
    
   <PdfViewer ref="vpvRef" />
</template>
vue
<template>
   <div>
     <button @click="rotateClockwise">Rotate Clockwise</button>
     <button @click="rotateCounterClockwise">Rotate Counterclockwise</button>
   </div>
   <div>
     <p>Current Rotation: {{ getCurrentRotation() }}</p>
   </div>
    
   <PdfViewer ref="vpvRef" />
</template>

Here are the full codes for this example:

App.vue (Parent Component)

vue
<script setup lang="ts">
import { ref } from "vue";
import PdfViewer from "./components/PdfViewer.vue";

const vpvRef = ref(null);
const rotateClockwise = () => vpvRef.value?.rotateClockwise();
const rotateCounterClockwise = () =>
  vpvRef.value?.rotateCounterClockwise();
const getCurrentRotation = () => vpvRef.value?.getCurrentRotation();
</script>

<template>
   <div>
     <button @click="rotateClockwise">Rotate Clockwise</button>
     <button @click="rotateCounterClockwise">Rotate Counterclockwise</button>
   </div>
   <div>
     <p>Current Rotation: {{ getCurrentRotation() }}</p>
   </div>
    
   <PdfViewer ref="vpvRef" />
</template>
vue
<script setup>
import { ref } from "vue";
import PdfViewer from "./components/PdfViewer.vue";

const vpvRef = ref(null);
const rotateClockwise = () => vpvRef.value?.rotateClockwise();
const rotateCounterClockwise = () =>
  vpvRef.value?.rotateCounterClockwise();
const getCurrentRotation = () => vpvRef.value?.getCurrentRotation();
</script>

<template>
   <div>
     <button @click="rotateClockwise">Rotate Clockwise</button>
     <button @click="rotateCounterClockwise">Rotate Counterclockwise</button>
   </div>
   <div>
     <p>Current Rotation: {{ getCurrentRotation() }}</p>
   </div>
    
   <PdfViewer ref="vpvRef" />
</template>
vue
<script lang="ts">
import PdfViewer from './components/PdfViewer.vue';

export default {
  components: {
    PdfViewer
  },
    
  data() {
    return {
      vpvRef: null
    };
  },
    
  methods: {
    rotateClockwise() {
      this.$refs.vpvRef.rotateClockwise();
    },
      
    rotateCounterClockwise() {
      this.$refs.vpvRef.rotateCounterClockwise();
    },
      
    getCurrentRotation() {
      return this.$refs.vpvRef.getCurrentRotation();
    }
  }
};
</script>

<template>
   <div>
     <button @click="rotateClockwise">Rotate Clockwise</button>
     <button @click="rotateCounterClockwise">Rotate Counterclockwise</button>
   </div>
   <div>
     <p>Current Rotation: {{ getCurrentRotation() }}</p>
   </div>
    
   <PdfViewer ref="vpvRef" />
</template>
vue
<script>
import PdfViewer from './components/PdfViewer.vue';

export default {
  components: {
    PdfViewer
  },
    
  data() {
    return {
      vpvRef: null
    };
  },
    
  methods: {
    rotateClockwise() {
      this.$refs.vpvRef.rotateClockwise();
    },
      
    rotateCounterClockwise() {
      this.$refs.vpvRef.rotateCounterClockwise();
    },
      
    getCurrentRotation() {
      return this.$refs.vpvRef.getCurrentRotation();
    }
  }
};
</script>

<template>
   <div>
     <button @click="rotateClockwise">Rotate Clockwise</button>
     <button @click="rotateCounterClockwise">Rotate Counterclockwise</button>
   </div>
   <div>
     <p>Current Rotation: {{ getCurrentRotation() }}</p>
   </div>
    
   <PdfViewer ref="vpvRef" />
</template>

component/PdfViewer.vue (Child Component)

vue
<script setup lang="ts">
import { ref, defineExpose } from "vue";
import { VPdfViewer } from "@vue-pdf-viewer/viewer";

const samplePDF = ref('your-pdf.pdf');
const vpvRef = ref<InstanceType<typeof VPdfViewer>>();
const rotateClockwise = () => vpvRef.value?.rotateControl?.rotateClockwise();
const rotateCounterClockwise = () =>
  vpvRef.value?.rotateControl?.rotateCounterclockwise();
const getCurrentRotation = () => vpvRef.value?.rotateControl?.currentRotation;

defineExpose({
  rotateClockwise,
  rotateCounterClockwise,
  getCurrentRotation,
});
</script>

<template>
  <VPdfViewer ref="vpvRef" :src="samplePDF" />
</template>
vue
<script setup>
import { ref, defineExpose } from "vue";
import { VPdfViewer } from "@vue-pdf-viewer/viewer";

const samplePDF = ref('your-pdf.pdf');
const vpvRef = ref(null);
const rotateClockwise = () => vpvRef.value?.rotateControl?.rotateClockwise();
const rotateCounterClockwise = () =>
  vpvRef.value?.rotateControl?.rotateCounterclockwise();
const getCurrentRotation = () => vpvRef.value?.rotateControl?.currentRotation;

defineExpose({
  rotateClockwise,
  rotateCounterClockwise,
  getCurrentRotation,
});
</script>

<template>
  <VPdfViewer ref="vpvRef" :src="samplePDF" />
</template>
vue
<script lang="ts">
import { VPdfViewer } from '@vue-pdf-viewer/viewer';

export default {
  components: {
    VPdfViewer
  },
    
  data() {
    return {
      samplePDF: 'your-pdf.pdf',
      vpvRef: null,
    };
  },
    
  methods: {
    rotateClockwise() {
      this.$refs.vpvRef.rotateControl.rotateClockwise();
    },
      
    rotateCounterClockwise() {
      this.$refs.vpvRef.rotateControl.rotateCounterclockwise();
    },
      
    getCurrentRotation() {
      return this.$refs.vpvRef.rotateControl.currentRotation;
    }
  }
};
</script>

<template>
  <VPdfViewer ref="vpvRef" :src="samplePDF" />
</template>
vue
<script>
import { VPdfViewer } from '@vue-pdf-viewer/viewer';

export default {
  components: {
    VPdfViewer
  },
    
  data() {
    return {
      samplePDF: 'your-pdf.pdf',
      vpvRef: null,
    };
  },
    
  methods: {
    rotateClockwise() {
      this.$refs.vpvRef.rotateControl.rotateClockwise();
    },
      
    rotateCounterClockwise() {
      this.$refs.vpvRef.rotateControl.rotateCounterclockwise();
    },
      
    getCurrentRotation() {
      return this.$refs.vpvRef.rotateControl.currentRotation;
    }
  }
};
</script>
<template>
  <VPdfViewer ref="vpvRef" :src="samplePDF" />
</template>