DEV Community

paulo-p
paulo-p

Posted on

Mimic a Desktop Window Using Vue

I want to make a draggable Windows-type component in my app. So today we'll be doing just that with v-drag.

Vue Desktop Window

Step 1: Initialize a Vue app.

npm init vue@latest window-vue
cd window-vue
npm install
Enter fullscreen mode Exit fullscreen mode

Step 2: Install TailwindCSS, Font Awesome Icons, and v-drag!

We'll use Tailwind and FontAwesome to style our component.

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Enter fullscreen mode Exit fullscreen mode

Now go to your tailwind.config.js file and paste this.

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
Enter fullscreen mode Exit fullscreen mode

Paste this into your src/assets/main.css file...

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Then install Font Awesome Icons for beautiful logos...

npm i --save @fortawesome/fontawesome-svg-core
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons
npm i --save @fortawesome/vue-fontawesome@latest-3
Enter fullscreen mode Exit fullscreen mode

Step 3: Install and use the last library v-drag.

npm install v-drag
Enter fullscreen mode Exit fullscreen mode

Now that you have v-drag, let's set it up on our src/main.js or src/main.ts.*

*Note: If you're using Typescript, add a src/declarations.d.ts file anywhere inside your src/ folder.
Inside your src/declarations.d.ts, add this bit declare module "v-drag";

// ...
import App from './App.vue'
import router from './router'
import drag from "v-drag";

const app = createApp(App)
app.use(router)
app.use(drag)

app.mount('#app')
// ...
Enter fullscreen mode Exit fullscreen mode

Step 4: Time to make something cool.

We'll only be using Font Awesome's fa-circle logo.

To make something draggable, we just use the v-drag directive to move it around.

<script setup lang="ts">
import { faCircle } from '@fortawesome/free-solid-svg-icons';
import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
library.add(faCircle);
</script>

<template>
  <div v-drag>
    Hello! Drag me.
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

Using v-drag

Now that we know how to use v-drag, let's add in a few styling on our component!

<script lang="ts" setup>
// ...
const handleWindow = {
  handle: "#window-handle" // Will be the only element that can be clicked to drag the entire v-drag.
}
</script>

<template>
  <main class="bg-black w-screen h-screen relative text-gray-200 overflow-hidden">
    <div v-drag="handleWindow" class="bg-slate-950 max-w-2xl border rounded-lg absolute w-full -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2">
      <div class="flex border-b">
        <div class="flex items-center px-2 w-full" id="window-handle">
          <p>Window in Vue</p>
        </div>
        <div class="w-fit text-xs flex items-center justify-end px-2">
          <font-awesome-icon class="ml-2" icon="fa-solid fa-circle" />
          <font-awesome-icon class="ml-2" icon="fa-solid fa-circle" />
          <font-awesome-icon class="ml-2" icon="fa-solid fa-circle" />
        </div>
      </div>
      <div class="p-4">
        <h1 class="text-lg">Need Money</h1>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Recusandae velit eaque, sunt temporibus expedita alias accusamus mollitia ut qui quasi cumque facere. Deserunt incidunt voluptate iste ex laudantium recusandae nostrum!</p>
      </div>
    </div>
  </main>
</template>
Enter fullscreen mode Exit fullscreen mode

v-drag accepts an options object containing handle that will be used to point to an element that can be used to drag the entire element using v-drag.

Vue Desktop Window

So I guess that's it!

Top comments (0)