Vue3는 Postcss 7까지 지원한다.
참고)https://tailwindui.com/documentation#vue-installing-dependencies
라이브러리 설치.
// use css
npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
// use tailwindui components
npm install @headlessui/vue @heroicons/vue
config 파일 설정.
npx tailwindcss init -p
// tailwind.config.js
module.exports = {
purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
css 파일 임포트
/* ./src/tailwind/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import './tailwind/index.css'; // Here
createApp(App).mount('#app');
css 적용
<template>
<div class="justify-center flex bg-yellow-300 items-center h-screen">
<div class="text-4xl">
Hello 👋🏼
</div>
</div>
</template>
<script>
export default {
name: 'App',
};
</script>
components 적용하기
참고)https://tailwindui.com/components/marketing/elements/headers
<!-- This example requires Tailwind CSS v2.0+ -->
<template>
<Popover class="relative bg-white">
<div class="max-w-7xl mx-auto px-4 sm:px-6">
<div class="flex justify-between items-center border-b-2 border-gray-100 py-6 md:justify-start md:space-x-10">
<div class="flex justify-start lg:w-0 lg:flex-1">
<a href="#">
<span class="sr-only">Workflow</span>
<img class="h-8 w-auto sm:h-10" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="" />
</a>
</div>
<div class="-mr-2 -my-2 md:hidden">
<PopoverButton class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
<span class="sr-only">Open menu</span>
<MenuIcon class="h-6 w-6" aria-hidden="true" />
</PopoverButton>
</div>
<PopoverGroup as="nav" class="hidden md:flex space-x-10">
<Popover class="relative" v-slot="{ open }">
<PopoverButton :class="[open ? 'text-gray-900' : 'text-gray-500', 'group bg-white rounded-md inline-flex items-center text-base font-medium hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500']">
<span>Solutions</span>
<ChevronDownIcon :class="[open ? 'text-gray-600' : 'text-gray-400', 'ml-2 h-5 w-5 group-hover:text-gray-500']" aria-hidden="true" />
</PopoverButton>
<transition enter-active-class="transition ease-out duration-200" enter-from-class="opacity-0 translate-y-1" enter-to-class="opacity-100 translate-y-0" leave-active-class="transition ease-in duration-150" leave-from-class="opacity-100 translate-y-0" leave-to-class="opacity-0 translate-y-1">
<PopoverPanel class="absolute z-10 -ml-4 mt-3 transform px-2 w-screen max-w-md sm:px-0 lg:ml-0 lg:left-1/2 lg:-translate-x-1/2">
<div class="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-hidden">
<div class="relative grid gap-6 bg-white px-5 py-6 sm:gap-8 sm:p-8">
<a v-for="item in solutions" :key="item.name" :href="item.href" class="-m-3 p-3 flex items-start rounded-lg hover:bg-gray-50">
<component :is="item.icon" class="flex-shrink-0 h-6 w-6 text-indigo-600" aria-hidden="true" />
<div class="ml-4">
<p class="text-base font-medium text-gray-900">
{{ item.name }}
</p>
<p class="mt-1 text-sm text-gray-500">
{{ item.description }}
</p>
</div>
</a>
</div>
<div class="px-5 py-5 bg-gray-50 space-y-6 sm:flex sm:space-y-0 sm:space-x-10 sm:px-8">
<div v-for="item in callsToAction" :key="item.name" class="flow-root">
<a :href="item.href" class="-m-3 p-3 flex items-center rounded-md text-base font-medium text-gray-900 hover:bg-gray-100">
<component :is="item.icon" class="flex-shrink-0 h-6 w-6 text-gray-400" aria-hidden="true" />
<span class="ml-3">{{ item.name }}</span>
</a>
</div>
</div>
</div>
</PopoverPanel>
</transition>
</Popover>
<a href="#" class="text-base font-medium text-gray-500 hover:text-gray-900"> Pricing </a>
<a href="#" class="text-base font-medium text-gray-500 hover:text-gray-900"> Docs </a>
<Popover class="relative" v-slot="{ open }">
<PopoverButton :class="[open ? 'text-gray-900' : 'text-gray-500', 'group bg-white rounded-md inline-flex items-center text-base font-medium hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500']">
<span>More</span>
<ChevronDownIcon :class="[open ? 'text-gray-600' : 'text-gray-400', 'ml-2 h-5 w-5 group-hover:text-gray-500']" aria-hidden="true" />
</PopoverButton>
<transition enter-active-class="transition ease-out duration-200" enter-from-class="opacity-0 translate-y-1" enter-to-class="opacity-100 translate-y-0" leave-active-class="transition ease-in duration-150" leave-from-class="opacity-100 translate-y-0" leave-to-class="opacity-0 translate-y-1">
<PopoverPanel class="absolute z-10 left-1/2 transform -translate-x-1/2 mt-3 px-2 w-screen max-w-md sm:px-0">
<div class="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 overflow-hidden">
<div class="relative grid gap-6 bg-white px-5 py-6 sm:gap-8 sm:p-8">
<a v-for="item in resources" :key="item.name" :href="item.href" class="-m-3 p-3 flex items-start rounded-lg hover:bg-gray-50">
<component :is="item.icon" class="flex-shrink-0 h-6 w-6 text-indigo-600" aria-hidden="true" />
<div class="ml-4">
<p class="text-base font-medium text-gray-900">
{{ item.name }}
</p>
<p class="mt-1 text-sm text-gray-500">
{{ item.description }}
</p>
</div>
</a>
</div>
<div class="px-5 py-5 bg-gray-50 sm:px-8 sm:py-8">
<div>
<h3 class="text-sm tracking-wide font-medium text-gray-500 uppercase">Recent Posts</h3>
<ul role="list" class="mt-4 space-y-4">
<li v-for="post in recentPosts" :key="post.id" class="text-base truncate">
<a :href="post.href" class="font-medium text-gray-900 hover:text-gray-700">
{{ post.name }}
</a>
</li>
</ul>
</div>
<div class="mt-5 text-sm">
<a href="#" class="font-medium text-indigo-600 hover:text-indigo-500"> View all posts <span aria-hidden="true">→</span></a>
</div>
</div>
</div>
</PopoverPanel>
</transition>
</Popover>
</PopoverGroup>
<div class="hidden md:flex items-center justify-end md:flex-1 lg:w-0">
<a href="#" class="whitespace-nowrap text-base font-medium text-gray-500 hover:text-gray-900"> Sign in </a>
<a href="#" class="ml-8 whitespace-nowrap inline-flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-indigo-600 hover:bg-indigo-700"> Sign up </a>
</div>
</div>
</div>
<transition enter-active-class="duration-200 ease-out" enter-from-class="opacity-0 scale-95" enter-to-class="opacity-100 scale-100" leave-active-class="duration-100 ease-in" leave-from-class="opacity-100 scale-100" leave-to-class="opacity-0 scale-95">
<PopoverPanel focus class="absolute top-0 inset-x-0 p-2 transition transform origin-top-right md:hidden">
<div class="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 bg-white divide-y-2 divide-gray-50">
<div class="pt-5 pb-6 px-5">
<div class="flex items-center justify-between">
<div>
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="Workflow" />
</div>
<div class="-mr-2">
<PopoverButton class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
<span class="sr-only">Close menu</span>
<XIcon class="h-6 w-6" aria-hidden="true" />
</PopoverButton>
</div>
</div>
<div class="mt-6">
<nav class="grid gap-y-8">
<a v-for="item in solutions" :key="item.name" :href="item.href" class="-m-3 p-3 flex items-center rounded-md hover:bg-gray-50">
<component :is="item.icon" class="flex-shrink-0 h-6 w-6 text-indigo-600" aria-hidden="true" />
<span class="ml-3 text-base font-medium text-gray-900">
{{ item.name }}
</span>
</a>
</nav>
</div>
</div>
<div class="py-6 px-5 space-y-6">
<div class="grid grid-cols-2 gap-y-4 gap-x-8">
<a href="#" class="text-base font-medium text-gray-900 hover:text-gray-700"> Pricing </a>
<a href="#" class="text-base font-medium text-gray-900 hover:text-gray-700"> Docs </a>
<a v-for="item in resources" :key="item.name" :href="item.href" class="text-base font-medium text-gray-900 hover:text-gray-700">
{{ item.name }}
</a>
</div>
<div>
<a href="#" class="w-full flex items-center justify-center px-4 py-2 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-indigo-600 hover:bg-indigo-700"> Sign up </a>
<p class="mt-6 text-center text-base font-medium text-gray-500">
Existing customer?
{{ ' ' }}
<a href="#" class="text-indigo-600 hover:text-indigo-500"> Sign in </a>
</p>
</div>
</div>
</div>
</PopoverPanel>
</transition>
</Popover>
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue";
import { Popover, PopoverButton, PopoverGroup, PopoverPanel } from '@headlessui/vue'
import {
BookmarkAltIcon,
CalendarIcon,
ChartBarIcon,
CursorClickIcon,
MenuIcon,
PhoneIcon,
PlayIcon,
RefreshIcon,
ShieldCheckIcon,
SupportIcon,
ViewGridIcon,
XIcon,
} from '@heroicons/vue/outline'
import { ChevronDownIcon } from '@heroicons/vue/solid'
const solutions = [
{
name: 'Analytics',
description: 'Get a better understanding of where your traffic is coming from.',
href: '#',
icon: ChartBarIcon,
},
{
name: 'Engagement',
description: 'Speak directly to your customers in a more meaningful way.',
href: '#',
icon: CursorClickIcon,
},
{ name: 'Security', description: "Your customers' data will be safe and secure.", href: '#', icon: ShieldCheckIcon },
{
name: 'Integrations',
description: "Connect with third-party tools that you're already using.",
href: '#',
icon: ViewGridIcon,
},
{
name: 'Automations',
description: 'Build strategic funnels that will drive your customers to convert',
href: '#',
icon: RefreshIcon,
},
]
const callsToAction = [
{ name: 'Watch Demo', href: '#', icon: PlayIcon },
{ name: 'Contact Sales', href: '#', icon: PhoneIcon },
]
const resources = [
{
name: 'Help Center',
description: 'Get all of your questions answered in our forums or contact support.',
href: '#',
icon: SupportIcon,
},
{
name: 'Guides',
description: 'Learn how to maximize our platform to get the most out of it.',
href: '#',
icon: BookmarkAltIcon,
},
{
name: 'Events',
description: 'See what meet-ups and other events we might be planning near you.',
href: '#',
icon: CalendarIcon,
},
{ name: 'Security', description: 'Understand how we take your privacy seriously.', href: '#', icon: ShieldCheckIcon },
]
const recentPosts = [
{ id: 1, name: 'Boost your conversion rate', href: '#' },
{ id: 2, name: 'How to use search engine optimization to drive traffic to your site', href: '#' },
{ id: 3, name: 'Improve your customer experience', href: '#' },
]
export default defineComponent({
components: {
Popover, PopoverButton, PopoverGroup, PopoverPanel,
BookmarkAltIcon,
CalendarIcon,
ChartBarIcon,
CursorClickIcon,
MenuIcon,
PhoneIcon,
PlayIcon,
RefreshIcon,
ShieldCheckIcon,
SupportIcon,
ViewGridIcon,
XIcon,
ChevronDownIcon,
},
setup() {
const state = reactive({});
return {
state,
solutions,
callsToAction,
resources,
recentPosts
};
},
});
</script>
Docs에 명시된 컴포넌트를 defineComponents로 설정한다.
<template>
<Header />
<div class="justify-center flex bg-yellow-300 items-center h-screen">
<div class="text-4xl">
Hello 👋🏼
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue";
import Header from "../components/Header.vue";
export default defineComponent({
setup() {
const state = reactive({});
return {
state,
};
},
components: { Header }
});
</script>
헤더 컴포넌트를 넣어주면 성공
'Client > VueJS 3.0' 카테고리의 다른 글
Css) Video tag autoplay가 안될 때 (0) | 2022.07.28 |
---|---|
Vue3) Youtube iframe 영상 재생 (0) | 2022.07.12 |
CSS) Box Shadow (0) | 2022.07.07 |
Axios로 데이터 받아서 state, store 사용하기 (0) | 2022.05.10 |
vue-router 사용하기. 페이지 이동 (0) | 2022.05.03 |