Headless UI
介绍
最常在Tailwind的範例中看到它,支援Vue3、React两大框架。(Vue只支援3)
特点1:纯功能UI不带有样式
特点2:支援无障碍功能
安装
npm install @headlessui/vue
在需要使用的组件中import就好
假设今天要做一个在父组件页面打开子组件Modal视窗的效果
Dialog (Modal)
首先在父组件先引入需要用到的组件
import { Dialog, DialogPanel, TransitionRoot, TransitionChild } from '@headlessui/vue';import pluginModel from '../components/plugnModel.vue';// 这是要打开的子组件
避免浏览器跳警告我会在components中注册他们
export default { components: { pluginModel, // 子组件 Dialog, // 功能本体(开关在这,如果要全画面暗掉的背景也放这) DialogPanel, // 视窗本人放这 DialogTitle, // 告诉用户的无障碍标题 DialogDescription, // 告诉用户的无障碍内容 TransitionRoot, // 整个页面的过渡动画效果 TransitionChild, // 单个组件的过渡动画(须在TransitionRoot内使用) }}
官方文件没有动画效果的範例可以参考✿这里
但实际上不可能不加过渡的吧(吧?)
虽然说 Vue 中有内建的 Transition 效果
但他可以控制更细微的子组件动画
所以让我们加上上面提到的 TransitionRoot & TransitionChild
// 父组件<template>// 使用动画需要将原本在Dialog的open开关改到TransitionRoot :show="isOpen"// 注意是 :show 不是 :open<TransitionRoot :show="isOpen" as="template" enter="duration-300 ease" enter-from="opacity-0" enter-to="opacity-100"leave="duration-200 ease-in" leave-from="opacity-100" leave-to="opacity-0"> <Dialog class="relative z-30" as="div" @close="closeModal"> // 注意这边是@close <!-- Modal背景 --> <TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0" enter-to="opacity-100" leave="ease-in duration-200" leave-from="opacity-100" leave-to="opacity-0"> // 直接点击背景可以关闭视窗 <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true" @click="closeModal" /> </TransitionChild> <!-- Modal内容 --> <div class="fixed inset-0 overflow-y-auto"> <div class="flex min-h-full items-center justify-center p-4 text-center"> <!-- 上面两行负责定位 --> <TransitionChild as="template" enter="ease-out duration-500 transform" enter-from="opacity-0 -translate-y-40 sm:scale-95" enter-to="opacity-100 -translate-y-0 sm:scale-100" leave="ease-in duration-200" leave-from="opacity-100 sm:scale-100" leave-to="opacity-0 sm:scale-95"> <DialogPanel class="fixed top-20 h-5/6 overflow-y-auto w-11/12 bg-white rounded-lg md:w-8/12"> <!-- 子组件 --> </DialogPanel> </TransitionChild> </div> </div> </Dialog></TransitionRoot></template>
上面会用到的资料、函式
export default { setup() { // 控制 Modal 开关 let isOpen = ref(false); // 关闭 Modal function closeModal() { isOpen.value = false; } return { isOpen, closeModal, } }, components: { Dialog, DialogPanel, TransitionRoot, TransitionChild, },}
子组件就包含DialogTitle
与DialogDescription
完成!
随笔
官方说明文件很完整,但实作的时候常常漏东漏西
所以在这边纪录一下流程跟需要注意的地方