• 组件封装 - 消息提示框组件封装


    先来看最终效果是怎样的:

    我们会封装一个像 Element UI 一样的消息提示框组件, 用函数调用的方法来将消息提示框组件显示到页面

    1. this.$message({
    2. message: '恭喜你,这是一条成功消息',
    3. type: 'success'
    4. });

    大致步骤:

    1. 首先需要完成消息提示框组件的基础布局(主要由一个i标签和span标签组成)

    2. 通过 css 样式来改变消息提示框组件的颜色和字体图标的样式

    3. 我们需要封装一个函数, 主要是将消息提示框组件变成一个虚拟节点; 再将此虚拟节点动态的添加到一个真实的 DOM 对象里面去

    4. 我们需要提供两种调用此函数的方式, 第一种是组合式 api 的方法; 第二种是像 Vue2 那样使用 this 来进行调用函数

    第一步:

    完成消息提示框的基本布局

    1. <template>
    2. <div class="xtx-message">
    3. <i class="iconfont">i>
    4. <span class="text">span>
    5. div>
    6. template>
    7. <script>
    8. import { onMounted, ref } from 'vue'
    9. export default {
    10. name: 'XtxMessage',
    11. setup () {
    12. }
    13. }
    14. script>
    15. <style scoped lang="less">
    16. .xtx-message {
    17. width: 300px;
    18. height: 50px;
    19. position: fixed;
    20. z-index: 9999;
    21. left: 50%;
    22. margin-left: -150px;
    23. top: 25px;
    24. line-height: 50px;
    25. padding: 0 25px;
    26. border: 1px solid #e4e4e4;
    27. background: #f5f5f5;
    28. color: #999;
    29. border-radius: 4px;
    30. i {
    31. margin-right: 4px;
    32. vertical-align: middle;
    33. }
    34. .text {
    35. vertical-align: middle;
    36. }
    37. }
    38. style>

    第二步:

    通过 css 样式动态的控制消息提示框组件的颜色和字体图标的样式

    实现思路:

    1. 我们需要将所有会出现的颜色(css样式), 通过一个对象列举出来

    2. 通过父组件传入的数据(type), 拿着 type 数据去我们定义的这个对象里面找; 将对应的样式提取出来

    3. 通过 style 属性动态将提取的样式显示在外层的 div 标签上面, 当然 icon 字体图标也需要跟着改变

    此组件封装一共提供了三种样式

    • 成功 success
    • 失败 error
    • 警告 warning
    1. <template>
    2. <Transition name="down">
    3. // 因为我们在setup里面定义的style本来就是一个对象
    4. // 所以:style="style[type]"不用加 "{}" 直接使用
    5. <div class="xtx-message" :style="style[type]">
    6. // 动态的添加class类有两种方法, 第一是对象; 第二是数组
    7. // 对象的方法是需要判断的, 为true就添加; 否则不添加
    8. // 数组的方式不需要判断, 直接添加
    9. <i class="iconfont" :class="[style[type].icon]">i>
    10. <span class="text">{{text}}span>
    11. div>
    12. Transition>
    13. template>
    14. <script>
    15. export default {
    16. name: 'XtxMessage',
    17. props: {
    18. text: {
    19. type: String,
    20. default: ''
    21. },
    22. type: {
    23. type: String,
    24. // warn 警告 error 错误 success 成功
    25. default: 'warn'
    26. }
    27. },
    28. setup () {
    29. // 定义一个对象,包含三种情况的样式,对象key就是类型字符串
    30. const style = {
    31. warn: {
    32. icon: 'icon-warning',
    33. color: '#E6A23C',
    34. backgroundColor: 'rgb(253, 246, 236)',
    35. borderColor: 'rgb(250, 236, 216)'
    36. },
    37. error: {
    38. icon: 'icon-shanchu',
    39. color: '#F56C6C',
    40. backgroundColor: 'rgb(254, 240, 240)',
    41. borderColor: 'rgb(253, 226, 226)'
    42. },
    43. success: {
    44. icon: 'icon-queren2',
    45. color: '#67C23A',
    46. backgroundColor: 'rgb(240, 249, 235)',
    47. borderColor: 'rgb(225, 243, 216)'
    48. }
    49. }
    50. return { style }
    51. }
    52. }
    53. script>
    54. <style scoped lang="less">
    55. ......
    56. style>

    第三步:

    我们会封装一个函数(message), 用户可以使用函数一样; 需要时就调用显示消息提示框组件

    思路分析:

    1. 导入封装好的消息提示框组件

    2. 导入创建虚拟节点的方法(createVNode)和 render 函数

    3. 创建一个真实的 DOM 对象, 给这个 DOM 对象加上一个 class 类

    4. 向外默认导出一个函数, 此函数需要接收消息提示框组件的父组件传入的 props 数据

    5. 将导入的消息提示框组件变成虚拟节点

    6. 使用 render 函数将虚拟节点插入到真实的 DOM 对象里面

    7. 消息提示框组件并不是一直显示在页面, 定义定时器; 在3秒之后将消失提示框组件销毁

    8. 给消息提示框组件加上一个过渡效果

    1. // 导入需要变为虚拟节点的组件
    2. import XtxMessage from './xtx-message.vue'
    3. // 导入创建虚拟节点方法和render函数
    4. import { createVNode, render } from 'vue'
    5. // 创建一个真实的DOM节点
    6. const div = document.createElement('div')
    7. // 给这个DOM节点加上一个class类
    8. div.setAttribute('class', 'xtx-message-container')
    9. // 将这个DOM节点插入到body标签中
    10. document.body.appendChild(div)
    11. let timeId = null
    12. // 向外默认导出一个函数
    13. export default (props) => {
    14. // 将消息提示框组件变为一个虚拟节点
    15. // vnode的第一个参数是对应组件, 第二个参数是需要的props属性
    16. const vnode = createVNode(XtxMessage, props)
    17. // 将虚拟节点插入到正式的DOM节点中
    18. render(vnode, div)
    19. if (timeId) {
    20. clearTimeout(timeId)
    21. }
    22. timeId = setTimeout(() => {
    23. // 将div元素里面内容变为null就会销毁
    24. render(null, div)
    25. }, 3000)
    26. }

    让 Transition 组件的过渡效果实现, 有两个条件:

    1. 组件的创建和效果

    2. 组件的显示和隐藏

    所以, 我们定义一个变量 show , 在组件被挂载了之后; 就让其显示

    这样 Transition 组件的过渡效果就会实现 

    1. <template>
    2. <Transition name="down">
    3. <div class="xtx-message" :style="style[type]" v-show="show">
    4. <i class="iconfont" :class="[style[type].icon]">i>
    5. <span class="text">{{text}}span>
    6. div>
    7. Transition>
    8. template>
    9. <script>
    10. import { onMounted, ref } from 'vue'
    11. export default {
    12. name: 'XtxMessage',
    13. props: {
    14. ......
    15. },
    16. setup () {
    17. ......
    18. const show = ref(false)
    19. onMounted(() => {
    20. show.value = true
    21. })
    22. return { style, show }
    23. }
    24. }
    25. script>
    26. <style scoped lang="less">
    27. .down {
    28. &-enter {
    29. &-from {
    30. transform: translate3d(0,-75px,0);
    31. opacity: 0;
    32. }
    33. &-active {
    34. transition: all 0.5s;
    35. }
    36. &-to {
    37. transform: none;
    38. opacity: 1;
    39. }
    40. }
    41. }
    42. ......
    43. style>

    第四步:

    提供两种调用方式, 组合式 api 和 this 调用的方式 

    思路分析:

    1. 组合式 api 也就是 Vue3 的方法, 直接将 message 函数导入; 然后调用即可

    2. 将 message 函数追加到 app 的原型里面, 这样可以在 created 里面使用 this 来调用(但是不建议组合式 api 和选项型 api 混合使用)

    3. 直接在 setup 里面调用此函数

    1. import Message from '@/components/library/message.js'
    2. export default {
    3. install (app) {
    4. // 将Message函数追加到app的原型上
    5. // key值为$Message
    6. app.config.globalProperties.$Message = Message
    7. }
    8. }

     组合式 api 调用方式:

     this 调用方式:

     组合式 api 中使用 "this" :

  • 相关阅读:
    每天5分钟复习OpenStack(十三)存储缓存技术Bcache
    架构解析:Dubbo3 应用级服务发现如何应对双11百万集群实例
    设计模式之观察者模式
    js 图形操作一(兼容pc、移动端实现 draggable属性 拖放效果)
    KMP 算法的一些理解
    数据结构(C语言版)严蔚敏->排序
    LCR 145.判断对称二叉树
    论文阅读:Point-to-Voxel Knowledge Distillation for LiDAR Semantic Segmentation
    MyBatis的各种查询功能
    socket结合线程的测试demo
  • 原文地址:https://blog.csdn.net/weixin_48524561/article/details/127451869