Mimic a Desktop Window Using Vue

paulo-pertierra

paulo-p

Posted on July 19, 2023

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!

💖 💪 🙅 🚩
paulo-pertierra
paulo-p

Posted on July 19, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Vue.js Slots
webdev Vue.js Slots

December 14, 2023

Mimic a Desktop Window Using Vue
Implementing Tic Tac Toe in Vue
webdev Implementing Tic Tac Toe in Vue

March 11, 2023