Vue Konva
Vue Konva is a JavaScript library that provides declarative and reactive bindings for the Konva Framework, enabling complex canvas graphics within Vue.js applications. It leverages Vue's component system to render Konva stages, layers, and shapes, abstracting away direct DOM manipulation. The current stable version, 3.4.0, primarily supports Vue 3 and Konva >7, with `vue-konva@2` maintained for Vue 2 compatibility. While there's no fixed release cadence, updates generally align with advancements in Vue.js and Konva.js to ensure continued integration. Its key differentiator is simplifying canvas interaction by mapping Konva objects to Vue components prefixed with 'v-', allowing developers to define canvas elements and their properties reactively using Vue's familiar template syntax and data flow, making complex canvas animations and interactions more manageable.
Common errors
-
Failed to resolve component: v-stage
cause `VueKonva` plugin was not correctly installed via `app.use()` (Vue 3) or `Vue.use()` (Vue 2), or the application did not correctly mount.fixEnsure `import VueKonva from 'vue-konva';` and `app.use(VueKonva);` (for Vue 3) are present in your main application entry file (e.g., `main.ts` or `main.js`). -
TypeError: Cannot read properties of undefined (reading 'getNode')
cause Attempting to call `getNode()` on a Vue ref that has not yet been assigned to a mounted `vue-konva` component, or on a ref that points to a non-`vue-konva` element.fixEnsure the component is mounted before accessing its ref and calling `getNode()`, typically within `onMounted` (Composition API) or `mounted` (Options API) lifecycle hooks. Also, confirm the ref is correctly attached to a `v-` component. -
[Vue warn]: Property "x" was accessed during render but is not defined on instance.
cause Konva properties like `x`, `y`, `fill`, etc., are being passed directly as props to a `v-` component instead of being encapsulated within the `:config` prop.fixPlace all Konva-specific properties inside a single `config` object and bind it to the `v-` component using `:config`. For example, `<v-circle :config="{ x: 100, y: 100, fill: 'red' }"></v-circle>`. -
Error: Konva error: You may only add layers to the stage.
cause Incorrect nesting of `vue-konva` components, specifically attempting to place shapes directly inside `v-stage` or other containers that are not `v-layer` or `v-group` components.fixEnsure `v-stage` contains `v-layer` components, and `v-layer` or `v-group` components contain your specific Konva shapes (`v-circle`, `v-rect`, etc.). Correct hierarchy is `<v-stage><v-layer><v-shape/></v-layer></v-stage>`.
Warnings
- breaking Vue 2 and Vue 3 projects require different versions of `vue-konva`. Version 3.x+ (the latest) is for Vue 3 and Konva >7. For Vue 2 compatibility, you must explicitly install `vue-konva@2`.
- gotcha All Konva object properties (e.g., `x`, `y`, `fill`, `strokeWidth`) must be passed via the `config` prop object to `v-` components. Passing them directly as individual props (e.g., `<v-circle :x="100" :fill="'red'"></v-circle>`) will not work as expected and may cause reactivity issues or be ignored.
- gotcha To interact with the underlying Konva.js objects (e.g., calling `stage.toDataURL()`, `layer.draw()`, or direct Konva API methods), you must use the `getNode()` method on the Vue component's ref. Directly accessing the ref (e.g., `this.$refs.stage` or `stageRef.value`) will return the Vue component instance, not the Konva object itself.
- gotcha By default, `vue-konva` works in 'non-strict' mode. If you manually change properties of a Konva node obtained via `getNode()` (e.g., during drag-and-drop), these changes might not automatically synchronize back to the Vue component's `config` prop, leading to discrepancies if the `config` prop is later updated.
Install
-
npm install vue-konva -
yarn add vue-konva -
pnpm add vue-konva
Imports
- VueKonva
const VueKonva = require('vue-konva');import VueKonva from 'vue-konva';
- v-stage, v-layer, v-circle (components)
import { VStage } from 'vue-konva';<template><v-stage :config="..."><v-layer><v-circle :config="..."></v-circle></v-layer></v-stage></template>
- getNode()
this.$refs.myKonvaComponentRef;
this.$refs.myKonvaComponentRef.getNode();
- Konva types
import type Konva from 'konva';
Quickstart
import { createApp } from 'vue';
import App from './App.vue';
import VueKonva from 'vue-konva';
const app = createApp(App);
app.use(VueKonva);
app.mount('#app');
// App.vue
/*
<template>
<v-stage :config="configKonva">
<v-layer>
<v-circle :config="configCircle"></v-circle>
<v-rect :config="configRect"></v-rect>
</v-layer>
</v-stage>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const configKonva = ref({
width: 400,
height: 300
});
const configCircle = ref({
x: 100,
y: 100,
radius: 50,
fill: "red",
stroke: "black",
strokeWidth: 4,
draggable: true
});
const configRect = ref({
x: 200,
y: 150,
width: 80,
height: 60,
fill: "blue",
stroke: "darkblue",
strokeWidth: 3,
draggable: true
});
</script>
*/