前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Toast组件开发实践(Vuejs3.x)

Toast组件开发实践(Vuejs3.x)

作者头像
前端小鑫同学
发布2023-05-01 09:56:04
1.2K0
发布2023-05-01 09:56:04
举报

进入正题

Toast组件几乎是没有个组件库必备的组件,通过Toast组件开发可以比较全面的学习Vuejs的相关技能点,一起来看一下~

基础项目准备

依旧推荐你来1024Code Fork 我的《【项目模板】Vue3+Vite3+Ts4》 开始这次学习,如果你不习惯使用在线的IDE,那么可以将项目导出到本地运行~

组件开发

components目录下创建Toast文件夹,并新增插件文件(index.ts)和组件文件(index.vue),下面是Toast组件的样式及DOM结构,接下来将为其增加一系列必要的内容。

代码语言:javascript
复制
<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提供messageduration属性,注意类型、必传及默认值的设置。

代码语言:javascript
复制
<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属性了。

代码语言:javascript
复制
<template>
    <div class="toast">
      <div class="toast-content">{{ message }}</div>
    </div>
</template>

为组件增加状态

增加一个响应式的visible数据,动态的切换组件的显示和隐藏,在setup中将visible返回后,visible将被暴露,在插件中会通过修改visibletrue来显示吐司信息。

代码语言:javascript
复制
<template>
    <div class="toast" v-if="visible">
      <div class="toast-content">{{ message }}</div>
    </div>
</template>
代码语言:javascript
复制
import { ref } from 'vue'

setup(props) {
  const visible = ref(false)

  return {
    visible
  }
}

为组件增加监听器

自动隐藏需要用到watch,当监听到visible状态激活时启动计时器,在duration毫秒后将visible状态改为未激活状态。

代码语言:javascript
复制
watch(visible, (value) => {
  if (value) {
    setTimeout(() => {
      visible.value = false
    }, props.duration)
  }
})

组件部分完整代码

代码语言:javascript
复制
<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文档

代码语言:javascript
复制
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元素上,至此将得到一个成功挂载的组件实例。

代码语言:javascript
复制
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变更为激活状态。

代码语言:javascript
复制
const createToast = (options: 
    { message: string, duration?: number }
) => {

  ...

  const instance = app.mount(document.createElement('div'))
  instance.visible = true;
}

最后可以通过组件实例上的$el属性获取已挂载组件对应的真实DOM,将其直接插入body元素中即完成插件的完整功能。

代码语言:javascript
复制
const createToast = (options: 
    { message: string, duration?: number }
) => {

  ...

  document.body.appendChild(instance.$el)
}

插件部分完整代码

代码语言:javascript
复制
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}),
    }
  }
}

组件使用

安装

代码语言:javascript
复制
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')

使用

代码语言:javascript
复制
<script lang="ts">
export default {
  name: "App",
  methods: {
    toast() {
      this.$toast.show('Hello Vuejs')
    }
  }
}
</script>
代码语言:javascript
复制
// script setup
<script setup lang="ts">
import { getCurrentInstance } from 'vue';
const global = getCurrentInstance()?.appContext.config.globalProperties;

const toast = () => {
  global?.$toast.show('Hello Vuejs')
}
</script>
代码语言:javascript
复制
// 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状态的变化即可激活绑定的动画效果。

代码语言:javascript
复制
<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编程助手,响应速度非常棒~

如果看完觉得有收获,欢迎点赞、评论、分享支持一下。你的支持和肯定,是我坚持写作的动力~

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基础项目准备
  • 组件开发
    • 为组件增加属性
      • 为组件增加状态
        • 为组件增加监听器
          • 组件部分完整代码
          • 插件开发
            • 实现install函数
              • 实现createToast函数
                • 插件部分完整代码
                • 组件使用
                  • 安装
                    • 使用
                    • 补充优化
                    • 总结
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                    http://www.vxiaotou.com