• 组件封装 - 对话框组件


    需要满足的需求:

    1. 头部标题是需要自定义的

    2. 主体内容也是需要自定义的

    3. 尾部按钮需要时就显示, 不需要时不显示

    这里我们会使用 class 类来控制 dialog 组件的显示隐藏

    头部标题自定义, 可以由父组件传入 title 属性来实现

    主体内容自定义, 直接放入一个默认插槽

    尾部按钮的控制, 直接使用具名插槽来控制

    1. <template>
    2. <div class="xtx-dialog" :class="{ fade }">
    3. <div class="wrapper" :class="{ fade }">
    4. <div class="header">
    5. <h3>{{ title }}h3>
    6. <a href="JavaScript:;" class="iconfont icon-close-new">a>
    7. div>
    8. <div class="body">
    9. <slot />
    10. div>
    11. <div class="footer">
    12. <slot name="footer" />
    13. div>
    14. div>
    15. div>
    16. template>
    17. <script>
    18. import { ref, onMounted } from 'vue'
    19. export default {
    20. name: 'XtxDialog',
    21. props: {
    22. title: {
    23. type: String,
    24. default: ''
    25. }
    26. },
    27. setup () {
    28. // 首先完成dialog组件的过渡效果
    29. const fade = ref(false)
    30. onMounted(() => {
    31. // 页面刚挂载完毕就使用css去添加过去的话, 是无法生效的
    32. // 所以我们使用定时器延迟添加即可
    33. setTimeout(() => {
    34. fade.value = true
    35. })
    36. })
    37. return { fade }
    38. }
    39. }
    40. script>
    41. <style scoped lang="less">
    42. .xtx-dialog {
    43. position: fixed;
    44. left: 0;
    45. top: 0;
    46. width: 100%;
    47. height: 100%;
    48. z-index: 8887;
    49. background: rgba(0,0,0,0);
    50. &.fade {
    51. transition: all 0.4s;
    52. background: rgba(0,0,0,.5);
    53. }
    54. .wrapper {
    55. width: 600px;
    56. background: #fff;
    57. border-radius: 4px;
    58. position: absolute;
    59. top: 50%;
    60. left: 50%;
    61. transform: translate(-50%,-60%);
    62. opacity: 0;
    63. &.fade {
    64. transition: all 0.4s;
    65. transform: translate(-50%,-50%);
    66. opacity: 1;
    67. }
    68. .body {
    69. padding: 20px 40px;
    70. font-size: 16px;
    71. .icon-warning {
    72. color: @priceColor;
    73. margin-right: 3px;
    74. font-size: 16px;
    75. }
    76. }
    77. .footer {
    78. text-align: center;
    79. padding: 10px 0 30px 0;
    80. }
    81. .header {
    82. position: relative;
    83. height: 70px;
    84. line-height: 70px;
    85. padding: 0 20px;
    86. border-bottom: 1px solid #f5f5f5;
    87. h3 {
    88. font-weight: normal;
    89. font-size: 18px;
    90. }
    91. a {
    92. position: absolute;
    93. right: 25px;
    94. top: 25px;
    95. font-size: 24px;
    96. width: 20px;
    97. height: 20px;
    98. line-height: 20px;
    99. text-align: center;
    100. color: #999;
    101. &:hover {
    102. color: #666;
    103. }
    104. }
    105. }
    106. }
    107. }
    108. style>
    1. <template>
    2. <XtxDialog title="切换收货地址">
    3. 主体内容
    4. <template #footer>
    5. <XtxButton type="gray" style="margin-right:20px">取消XtxButton>
    6. <XtxButton type="primary">确认XtxButton>
    7. template>
    8. XtxDialog>
    9. template>

    dialog 组件的显示隐藏, 并不是自己去控制的; 而是由父组件来进行控制的

    思路分析:

    1. 父组件使用 v-model 传入依赖的数据

    2. 由父组件来控制 dialog 组件的显示, dialog 组件只需要控制隐藏即可

    3. dialog 组件接收父组件传入的值, 当 dialog 组件触发关闭事件的时候; emit 将值抛出, 修改掉父组件的数据

    4. 然后需要使用 watch 监听父组件传入值的变化, 父组件传入的值变化; dialog 组件的值也需要变化

    1. <template>
    2. <div class="xtx-dialog" :class="{ fade }" v-show="visible">
    3. <div class="wrapper" :class="{ fade }">
    4. <div class="header">
    5. <h3>{{ title }}h3>
    6. <a href="JavaScript:;" class="iconfont icon-close-new" @click="close">a>
    7. div>
    8. <div class="body">
    9. <slot />
    10. div>
    11. <div class="footer">
    12. <slot name="footer" />
    13. div>
    14. div>
    15. div>
    16. template>
    17. <script>
    18. import { ref, watch } from 'vue'
    19. export default {
    20. name: 'XtxDialog',
    21. props: {
    22. title: {
    23. type: String,
    24. default: ''
    25. },
    26. visible: {
    27. type: Boolean,
    28. default: false
    29. }
    30. },
    31. setup (props, { emit }) {
    32. // 首先完成dialog组件的过渡效果
    33. const fade = ref(false)
    34. const close = () => {
    35. emit('update:visible', false)
    36. }
    37. watch(() => props.visible, (newVal) => {
    38. setTimeout(() => {
    39. fade.value = newVal
    40. })
    41. }, { immediate: true })
    42. return { fade, close }
    43. }
    44. }
    45. script>
    46. <style scoped lang="less">
    47. ......
    48. style>

    在父组件中使用(父组件通过控制 visibleDialog 数据来显示隐藏 dialog 组件)

    1. <template>
    2. <XtxDialog title="取消订单" v-model:visible="visibleDialog">
    3. <div class="cancel-info">
    4. <p>取消订单后,本单享有的优惠可能会一并取消,是否继续?p>
    5. <p class="tip">请选择取消订单的原因(必选):p>
    6. <div class="btn">
    7. <a
    8. @click="curText = item"
    9. v-for="item in cancelReason"
    10. :key="item"
    11. href="javascript:;"
    12. :class="{ active: curText === item }"
    13. >
    14. {{ item }}
    15. a>
    16. div>
    17. div>
    18. <template #footer>
    19. <XtxButton type="gray" @click="visibleDialog=false" style="margin-right:20px">取消XtxButton>
    20. <XtxButton type="primary" @click="submit">确认XtxButton>
    21. template>
    22. XtxDialog>
    23. template>

  • 相关阅读:
    零代码编程:用ChatGPT批量自动下载archive.org上的音频书
    计算机毕设(附源码)JAVA-SSM辽宁省高考志愿智能辅助填报系统
    kafka原理与应用
    Android面试每日一题(4): 哪些情况下会导致oom问题?
    微信小程序(基本结构)
    大模型解决方案:具体业务场景下的智能表单填充(附代码)
    10分钟搞定manim安装与vscode配置
    mysql GROUP_CONCAT 以及 其逆过程
    【MySQL】MySQL中如何对数据进行排序
    淘宝一键上货API:自动化上架商品、批量获取商品详情信息
  • 原文地址:https://blog.csdn.net/weixin_48524561/article/details/127700176