basic.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <script>
  2. export default {
  3. name: "lemonMessageBasic",
  4. inject: ["IMUI"],
  5. props: {
  6. message: {
  7. type: Object,
  8. default: () => {
  9. return {};
  10. }
  11. },
  12. timeFormat: {
  13. type: Function,
  14. default: () => ""
  15. },
  16. reverse: Boolean,
  17. hiddenTitle: Boolean
  18. },
  19. data() {
  20. return {};
  21. },
  22. render() {
  23. const { fromUser, status, sendTime } = this.message;
  24. return (
  25. <div
  26. class={[
  27. "lemon-message",
  28. {
  29. "lemon-message--reverse": this.reverse,
  30. "lemon-message--hidden-title": this.hiddenTitle
  31. }
  32. ]}
  33. >
  34. <div class="lemon-message__avatar">
  35. <lemon-avatar
  36. size={36}
  37. shape="square"
  38. src={fromUser.avatar}
  39. on-click={e => {
  40. this._emitClick(e, "avatar");
  41. }}
  42. />
  43. </div>
  44. <div class="lemon-message__inner">
  45. <div class="lemon-message__title">
  46. <span
  47. on-click={e => {
  48. this._emitClick(e, "displayName");
  49. }}
  50. >
  51. {fromUser.displayName}
  52. </span>
  53. <span class="lemon-message__time">{this.timeFormat(sendTime)}</span>
  54. </div>
  55. <div
  56. class="lemon-message__content"
  57. on-click={e => {
  58. this._emitClick(e, "content");
  59. }}
  60. >
  61. {this.useScopedSlots("content", this.message)}
  62. </div>
  63. <div
  64. class="lemon-message__status"
  65. on-click={e => {
  66. this._emitClick(e, "status");
  67. }}
  68. >
  69. {this._renderStatue(status)}
  70. </div>
  71. </div>
  72. </div>
  73. );
  74. },
  75. created() {},
  76. mounted() {},
  77. computed: {},
  78. watch: {},
  79. methods: {
  80. _emitClick(e, key) {
  81. this.IMUI.$emit("message-click", e, key, this.message);
  82. },
  83. _renderStatue(status) {
  84. if (status == "going") {
  85. return <i class="lemon-icon-loading lemonani-spin" />;
  86. } else if (status == "failed") {
  87. return (
  88. <i
  89. class="lemon-icon-prompt"
  90. title="重发消息"
  91. style={{
  92. color: "#ff2525",
  93. cursor: "pointer"
  94. }}
  95. />
  96. );
  97. }
  98. return;
  99. },
  100. useScopedSlots(name, params, defVnode = "", context = this) {
  101. return context.$scopedSlots[name]
  102. ? context.$scopedSlots[name](params)
  103. : defVnode;
  104. }
  105. }
  106. };
  107. </script>
  108. <style lang="stylus">
  109. @import '~styles/utils/index'
  110. arrow()
  111. content ' '
  112. position absolute
  113. top 6px
  114. width 0
  115. height 0
  116. border 4px solid transparent
  117. +b(lemon-message)
  118. display flex
  119. padding 10px 0
  120. +e(time)
  121. color #bbb
  122. padding 0 4px
  123. +e(inner)
  124. position relative
  125. +e(avatar)
  126. padding-right 10px
  127. user-select none
  128. .lemon-avatar
  129. cursor pointer
  130. +e(title)
  131. display flex
  132. font-size 12px
  133. line-height 14px
  134. padding-bottom 6px
  135. user-select none
  136. color #999
  137. +e(content)
  138. font-size 14px
  139. line-height 20px
  140. padding 8px 10px
  141. background #fff
  142. border-radius 4px
  143. position relative
  144. margin 0 46px 0 0
  145. img
  146. video
  147. background #e9e9e9
  148. height 100px
  149. &:before
  150. arrow()
  151. left -4px
  152. border-left none
  153. border-right-color #fff
  154. +e(status)
  155. position absolute
  156. top 23px
  157. right 20px
  158. color #aaa
  159. font-size 20px
  160. +m(reverse)
  161. flex-direction row-reverse
  162. +e(title)
  163. flex-direction row-reverse
  164. +e(status)
  165. left 20px
  166. right auto
  167. +e(content)
  168. background #35d863
  169. margin 0 0 0 46px
  170. &:before
  171. arrow()
  172. left auto
  173. right -4px
  174. border-right none
  175. border-left-color #35d863
  176. +e(title)
  177. text-align right
  178. +e(avatar)
  179. padding-right 0
  180. padding-left 10px
  181. +m(hidden-title)
  182. +e(status)
  183. top 7px
  184. +e(title)
  185. display none
  186. +e(content)
  187. &:before
  188. top 14px
  189. </style>