Toast组件开发实践(Vuejs3.x)
🎄Hi~ 大家好,我是小鑫同学,资深 IT 从业者,InfoQ 的签约作者,擅长前端开发并在这一领域有多年的经验,致力于分享我在技术方面的见解和心得
🚀技术&代码分享
😇推荐几个好用的工具
- var-conv 适用于VSCode IDE的代码变量名称快速转换工具
- generator-vite-plugin 快速生成Vite插件模板项目
- generator-babel-plugin 快速生成Babel插件模板项目
进入正题
Toast组件几乎是没有个组件库必备的组件,通过Toast组件开发可以比较全面的学习Vuejs的相关技能点,一起来看一下~
基础项目准备
依旧推荐你来1024Code Fork 我的《【项目模板】Vue3+Vite3+Ts4》 开始这次学习,如果你不习惯使用在线的IDE,那么可以将项目导出到本地运行~
组件开发
在components
目录下创建Toast
文件夹,并新增插件文件(index.ts
)和组件文件(index.vue
),下面是Toast
组件的样式及DOM结构,接下来将为其增加一系列必要的内容。
<template> <div class="toast"> <div class="toast-content">Hello Vuejs</div> </div> </template> <script lang="ts"> </script> <style> .toast { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #333; color: #fff; padding: 10px; border-radius: 5px; z-index: 9999; } .toast-content { display: inline-block; margin-right: 10px; } </style>
为组件增加属性
Toast组件接收一个必须属性是message
用来显示提示的信息,还可以接收一个非必须的属性duration
属性,在指定的时间后要自动隐藏掉提示信息,当然要有一个默认值的支持。
使用defineComponent
来创建组件对象,并通过props提供message
和duration
属性,注意类型、必传及默认值的设置。
<script lang="ts"> import { defineComponent } from 'vue' export default defineComponent({ name: 'Toast', props: { message: { type: String, required: true }, duration: { type: Number, default: 1000 } }, }) </script>
添加完属性后就可以将模板中的Hello Vuejs
替换成message
属性了。
<template> <div class="toast"> <div class="toast-content">{{ message }}</div> </div> </template>
为组件增加状态
增加一个响应式的visible
数据,动态的切换组件的显示和隐藏,在setup
中将visible
返回后,visible
将被暴露,在插件中会通过修改visible
为true
来显示吐司信息。
<template> <div class="toast" v-if="visible"> <div class="toast-content">{{ message }}</div> </div> </template>
import { ref } from 'vue' setup(props) { const visible = ref(false) return { visible } }
为组件增加监听器
自动隐藏需要用到watch
,当监听到visible
状态激活时启动计时器,在duration
毫秒后将visible
状态改为未激活状态。
watch(visible, (value) => { if (value) { setTimeout(() => { visible.value = false }, props.duration) } })
组件部分完整代码
<template> <div class="toast" v-if="visible"> <div class="toast-content">{{ message }}</div> </div> </template> <script lang="ts"> import { defineComponent, ref, watch } from 'vue' export default defineComponent({ name: 'Toast', props: { message: { type: String, required: true }, duration: { type: Number, default: 1000 } }, setup(props) { const visible = ref(false) watch(visible, (value) => { if (value) { setTimeout(() => { visible.value = false }, props.duration) } }) return { visible } } }) </script> <style> .toast { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #333; color: #fff; padding: 10px; border-radius: 5px; z-index: 9999; } .toast-content { display: inline-block; margin-right: 10px; } </style>
插件开发
在插件文件(index.ts
)中必须包含一个Vuejs插件规范的install
函数,另外需要抽取一个createToast
函数来执行具体的Toast
组件创建加载及提示流程。
实现install函数
在install
函数中主要的目的就是要在全局挂载一个可以随处执行的$toast
方法,通过这个方法可以很方便的使用Toast
组件。
在Vue3中挂载全局变量需要在globalProperties
上添加,具体可以看Vuejs文档。
const createToast = (options: { message: string, duration?: number } ) => { } export const ToastPlugin = { install(app: any) { app.config.globalProperties.$toast = { show: (message: string, duration?: number) => createToast({message, duration}), } } }
实现createToast函数
实现createToast
函数首先要导入vue
模块中的createApp
和同级目录下的组件模块,再借助createApp
创建Toast
组件应用程序实例,通过应用程序实例的mount
函数将其挂载到一个新的div
元素上,至此将得到一个成功挂载的组件实例。
import { createApp } from 'vue' import Toast from './index.vue' const createToast = (options: { message: string, duration?: number } ) => { const app = createApp(Toast, { message: options.message, duration: options.duration, }) const instance = app.mount(document.createElement('div')) }
在得到Toast
组件实例后,将可以直接访问组件暴露的状态和方法,此时就可以将Toast
组件的visible
变更为激活状态。
const createToast = (options: { message: string, duration?: number } ) => { ... const instance = app.mount(document.createElement('div')) instance.visible = true; }
最后可以通过组件实例上的$el
属性获取已挂载组件对应的真实DOM,将其直接插入body
元素中即完成插件的完整功能。
const createToast = (options: { message: string, duration?: number } ) => { ... document.body.appendChild(instance.$el) }
插件部分完整代码
import { createApp } from 'vue' import Toast from './index.vue' const createToast = (options: { message: string, duration?: number } ) => { const app = createApp(Toast, { message: options.message, duration: options.duration, }) const instance = app.mount(document.createElement('div')) instance.visible = true; document.body.appendChild(instance.$el) } export const ToastPlugin = { install(app: any) { app.config.globalProperties.$toast = { show: (message: string, duration?: number) => createToast({message, duration}), } } }
组件使用
安装
import { createApp } from 'vue' import './style.css' import App from './App.vue' // ① 导入插件模块 import { ToastPlugin } from './components/Toast/index' createApp(App) // ② 使用use加载插件 .use(ToastPlugin) .mount('#app')
使用
<script lang="ts"> export default { name: "App", methods: { toast() { this.$toast.show('Hello Vuejs') } } } </script>
// script setup <script setup lang="ts"> import { getCurrentInstance } from 'vue'; const global = getCurrentInstance()?.appContext.config.globalProperties; const toast = () => { global?.$toast.show('Hello Vuejs') } </script>
// defineComponent + setup <script lang="ts"> import { defineComponent, getCurrentInstance } from 'vue'; export default defineComponent({ name: "App", setup() { const global = getCurrentInstance()?.appContext.config.globalProperties; const toast = () => { global?.$toast.show('Hello Vuejs') } return { toast, } } }) </script>
补充优化
这里做一点点小优化,就是为Toast组件增加一下状态切换时的动画效果,可以使用Vuejs内置的Transition
,它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上,通过v-if
状态的变化即可激活绑定的动画效果。
<template> <transition name="toast"> <div class="toast" v-if="visible"> <div class="toast-content">{{ message }}</div> </div> </transition> </template> <style> .toast-enter-active, .toast-leave-active { transition: opacity 0.5s ease; } .toast-enter-from, .toast-leave-to { opacity: 0; } </style>
总结
到此Toast
组件的整个开发流程就结束了,在整个开发流程中涉及的Vuejs的属性、状态、监听器的使用,还有插件开发时的规则及全局变量的挂载,并且在组件使用时针对使用了setup
后无法读取this
而正确读取全局变量的,最后还提到了一点Vuejs
基础中动画组件的使用。希望能给你带来帮助。更多的实现方式不妨你来尝试一下1024Code提供AI编程助手,响应速度非常棒~
如果看完觉得有收获,欢迎点赞、评论、分享支持一下。你的支持和肯定,是我坚持写作的动力~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)