main.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <!--
  2. - Copyright (C) 2018-2019
  3. - All rights reserved, Designed By www.joolun.com
  4. 芋道源码:
  5. ① 移除多余的 rep 为前缀的变量,让 message 消息更简单
  6. ② 代码优化,补充注释,提升阅读性
  7. ③ 优化消息的临时缓存策略,发送消息时,只清理被发送消息的 tab,不会强制切回到 text 输入
  8. ④ 支持发送【视频】消息时,支持新建视频
  9. -->
  10. <template>
  11. <el-tabs type="border-card" v-model="objData.type" @tab-click="onTabClick">
  12. <!-- 类型 1:文本 -->
  13. <TabText v-model="objData.content" />
  14. <!-- 类型 2:图片 -->
  15. <TabImage v-model="objData" />
  16. <!-- 类型 3:语音 -->
  17. <TabVoice v-model="objData" />
  18. <!-- 类型 4:视频 -->
  19. <TabVideo v-model="objData" />
  20. <!-- 类型 5:图文 -->
  21. <TabNews v-model="objData" :news-type="newsType" />
  22. <!-- 类型 6:音乐 -->
  23. <TabMusic v-model="objData" />
  24. </el-tabs>
  25. </template>
  26. <script setup lang="ts" name="WxReplySelect">
  27. import { ObjData, NewsType } from './components/types'
  28. import TabText from './components/TabText.vue'
  29. import TabImage from './components/TabImage.vue'
  30. import TabVoice from './components/TabVoice.vue'
  31. import TabVideo from './components/TabVideo.vue'
  32. import TabNews from './components/TabNews.vue'
  33. import TabMusic from './components/TabMusic.vue'
  34. interface Props {
  35. objData: ObjData
  36. newsType?: NewsType
  37. }
  38. const props = withDefaults(defineProps<Props>(), {
  39. newsType: () => NewsType.Published
  40. })
  41. const objData = reactive(props.objData)
  42. // const tempObj = new Map().set(objData.type, Object.assign({}, objData))
  43. /** 切换消息类型的 tab */
  44. const onTabClick = () => {
  45. clear()
  46. }
  47. /** 清除除了`type`的字段 */
  48. const clear = () => {
  49. objData.content = ''
  50. objData.mediaId = ''
  51. objData.url = ''
  52. objData.title = ''
  53. objData.description = ''
  54. objData.articles = []
  55. }
  56. defineExpose({
  57. clear
  58. })
  59. </script>
  60. <style lang="scss" scoped>
  61. .select-item {
  62. width: 280px;
  63. padding: 10px;
  64. margin: 0 auto 10px auto;
  65. border: 1px solid #eaeaea;
  66. }
  67. .select-item2 {
  68. padding: 10px;
  69. margin: 0 auto 10px auto;
  70. border: 1px solid #eaeaea;
  71. }
  72. .ope-row {
  73. padding-top: 10px;
  74. text-align: center;
  75. }
  76. .input-margin-bottom {
  77. margin-bottom: 2%;
  78. }
  79. .item-name {
  80. font-size: 12px;
  81. overflow: hidden;
  82. text-overflow: ellipsis;
  83. white-space: nowrap;
  84. text-align: center;
  85. }
  86. .el-form-item__content {
  87. line-height: unset !important;
  88. }
  89. .col-select {
  90. border: 1px solid rgb(234, 234, 234);
  91. padding: 50px 0px;
  92. height: 160px;
  93. width: 49.5%;
  94. }
  95. .col-select2 {
  96. border: 1px solid rgb(234, 234, 234);
  97. padding: 50px 0px;
  98. height: 160px;
  99. }
  100. .col-add {
  101. border: 1px solid rgb(234, 234, 234);
  102. padding: 50px 0px;
  103. height: 160px;
  104. width: 49.5%;
  105. float: right;
  106. }
  107. .avatar-uploader-icon {
  108. border: 1px solid #d9d9d9;
  109. font-size: 28px;
  110. color: #8c939d;
  111. width: 100px !important;
  112. height: 100px !important;
  113. line-height: 100px !important;
  114. text-align: center;
  115. }
  116. .material-img {
  117. width: 100%;
  118. }
  119. .thumb-div {
  120. display: inline-block;
  121. text-align: center;
  122. }
  123. .item-infos {
  124. width: 30%;
  125. margin: auto;
  126. }
  127. </style>