Messages Component

    Messages Vue component represents component.

    • - main Messages container
    • **f7-message** - single message element
    • **f7-messages-title** - single messages title element

    Messages Properties

    Messages Events

    Single message Vue component (<f7-message>) has additional slots for custom elements:

    • **default** - element will be inserted as a child of <div class="message-bubble"> element in the end
    • **start** - element will be inserted in the beginning and direct child of main message element <div class="message">
    • **end** - element will be inserted in the end and direct child of main message element <div class="message">
    • **content-start** - element will be inserted in the beginning and direct child of the <div class="message-content"> element
    • **content-end** - element will be inserted in the end and direct child of the <div class="message-content"> element
    • **bubble-start** - element will be inserted in the beginning and direct child of the <div class="message-bubble"> element
    • **bubble-end** - element will be inserted in the end and direct child of the <div class="message-bubble"> element. Same as **default** slot
    • **header** - element will be inserted in message header
    • **footer** - element will be inserted in message footer
    • **text** - element will be inserted in message text
    • **name** - element will be inserted in message name
    • **image** - element will be inserted in message image (supposed tp be an <img> element)
    • **text-header** - element will be inserted in message text header
    • **text-footer** - element will be inserted in message text footer

    Access To Messages Instance

    If you use automatic initalization to init Messages (with init:true prop) and need to use you can access its initialized instance by accessing **.f7Messages** component’s property.

    1. <template>
    2. <f7-page>
    3. <f7-navbar title="Messsages"></f7-navbar>
    4. <f7-messagebar
    5. :placeholder="placeholder"
    6. ref="messagebar"
    7. :attachments-visible="attachmentsVisible"
    8. :sheet-visible="sheetVisible"
    9. >
    10. <f7-link
    11. icon-ios="f7:camera_fill"
    12. icon-aurora="f7:camera_fill"
    13. icon-md="material:camera_alt"
    14. slot="inner-start"
    15. @click="sheetVisible = !sheetVisible"
    16. ></f7-link>
    17. <f7-link
    18. icon-ios="f7:arrow_up_fill"
    19. icon-aurora="f7:arrow_up_fill"
    20. icon-md="material:send"
    21. slot="inner-end"
    22. @click="sendMessage"
    23. ></f7-link>
    24. <f7-messagebar-attachments>
    25. <f7-messagebar-attachment
    26. v-for="(image, index) in attachments"
    27. :key="index"
    28. :image="image"
    29. @attachment:delete="deleteAttachment(image)"
    30. ></f7-messagebar-attachment>
    31. </f7-messagebar-attachments>
    32. <f7-messagebar-sheet>
    33. <f7-messagebar-sheet-image
    34. v-for="(image, index) in images"
    35. :key="index"
    36. :image="image"
    37. :checked="attachments.indexOf(image) >= 0"
    38. @change="handleAttachment"
    39. ></f7-messagebar-sheet-image>
    40. </f7-messagebar-sheet>
    41. </f7-messagebar>
    42. <f7-messages ref="messages">
    43. <f7-messages-title><b>Sunday, Feb 9,</b> 12:58</f7-messages-title>
    44. <f7-message
    45. v-for="(message, index) in messagesData"
    46. :key="index"
    47. :type="message.type"
    48. :image="message.image"
    49. :name="message.name"
    50. :avatar="message.avatar"
    51. :first="isFirstMessage(message, index)"
    52. :last="isLastMessage(message, index)"
    53. :tail="isTailMessage(message, index)"
    54. >
    55. <span slot="text" v-if="message.text" v-html="message.text"></span>
    56. </f7-message>
    57. <f7-message v-if="typingMessage"
    58. type="received"
    59. :typing="true"
    60. :first="true"
    61. :last="true"
    62. :tail="true"
    63. :header="`${typingMessage.name} is typing`"
    64. :avatar="typingMessage.avatar"
    65. ></f7-message>
    66. </f7-messages>
    67. </f7-page>
    68. <script>
    69. data() {
    70. return {
    71. attachments: [],
    72. sheetVisible: false,
    73. typingMessage: null,
    74. messagesData: [
    75. {
    76. type: 'sent',
    77. text: 'Hi, Kate',
    78. },
    79. {
    80. type: 'sent',
    81. text: 'How are you?',
    82. },
    83. {
    84. name: 'Kate',
    85. type: 'received',
    86. text: 'Hi, I am good!',
    87. avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg',
    88. },
    89. {
    90. name: 'Blue Ninja',
    91. type: 'received',
    92. text: 'Hi there, I am also fine, thanks! And how are you?',
    93. avatar: 'https://cdn.framework7.io/placeholder/people-100x100-7.jpg',
    94. },
    95. {
    96. type: 'sent',
    97. text: 'Hey, Blue Ninja! Glad to see you ;)',
    98. },
    99. {
    100. type: 'sent',
    101. text: 'Hey, look, cutest kitten ever!',
    102. },
    103. {
    104. type: 'sent',
    105. image: 'https://cdn.framework7.io/placeholder/cats-200x260-4.jpg',
    106. },
    107. {
    108. name: 'Kate',
    109. type: 'received',
    110. text: 'Nice!',
    111. avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg',
    112. },
    113. {
    114. name: 'Kate',
    115. type: 'received',
    116. text: 'Like it very much!',
    117. avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg',
    118. },
    119. {
    120. name: 'Blue Ninja',
    121. type: 'received',
    122. text: 'Awesome!',
    123. avatar: 'https://cdn.framework7.io/placeholder/people-100x100-7.jpg',
    124. },
    125. ],
    126. images: [
    127. 'https://cdn.framework7.io/placeholder/cats-300x300-1.jpg',
    128. 'https://cdn.framework7.io/placeholder/cats-200x300-2.jpg',
    129. 'https://cdn.framework7.io/placeholder/cats-400x300-3.jpg',
    130. 'https://cdn.framework7.io/placeholder/cats-300x150-4.jpg',
    131. 'https://cdn.framework7.io/placeholder/cats-150x300-5.jpg',
    132. 'https://cdn.framework7.io/placeholder/cats-300x300-6.jpg',
    133. 'https://cdn.framework7.io/placeholder/cats-300x300-7.jpg',
    134. 'https://cdn.framework7.io/placeholder/cats-200x300-8.jpg',
    135. 'https://cdn.framework7.io/placeholder/cats-400x300-9.jpg',
    136. 'https://cdn.framework7.io/placeholder/cats-300x150-10.jpg',
    137. ],
    138. people: [
    139. {
    140. name: 'Kate Johnson',
    141. avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg',
    142. },
    143. {
    144. name: 'Blue Ninja',
    145. avatar: 'https://cdn.framework7.io/placeholder/people-100x100-7.jpg',
    146. },
    147. ],
    148. answers: [
    149. 'Yes!',
    150. 'No',
    151. 'Hm...',
    152. 'I am not sure',
    153. 'And what about you?',
    154. 'May be ;)',
    155. 'Lorem ipsum dolor sit amet, consectetur',
    156. 'What?',
    157. 'Are you sure?',
    158. 'Of course',
    159. 'Need to think about it',
    160. 'Amazing!!!',
    161. ],
    162. responseInProgress: false,
    163. };
    164. },
    165. computed: {
    166. attachmentsVisible() {
    167. const self = this;
    168. return self.attachments.length > 0;
    169. const self = this;
    170. return self.attachments.length > 0 ? 'Add comment or Send' : 'Message';
    171. },
    172. },
    173. mounted() {
    174. const self = this;
    175. self.$f7ready(() => {
    176. self.messagebar = self.$refs.messagebar.f7Messagebar;
    177. self.messages = self.$refs.messages.f7Messages;
    178. });
    179. },
    180. methods: {
    181. isFirstMessage(message, index) {
    182. const self = this;
    183. const previousMessage = self.messagesData[index - 1];
    184. if (message.isTitle) return false;
    185. if (!previousMessage || previousMessage.type !== message.type || previousMessage.name !== message.name) return true;
    186. return false;
    187. },
    188. isLastMessage(message, index) {
    189. const self = this;
    190. const nextMessage = self.messagesData[index + 1];
    191. if (message.isTitle) return false;
    192. if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
    193. return false;
    194. },
    195. isTailMessage(message, index) {
    196. const self = this;
    197. const nextMessage = self.messagesData[index + 1];
    198. if (message.isTitle) return false;
    199. if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
    200. return false;
    201. },
    202. deleteAttachment(image) {
    203. const self = this;
    204. const index = self.attachments.indexOf(image);
    205. self.attachments.splice(index, 1)[0]; // eslint-disable-line
    206. },
    207. handleAttachment(e) {
    208. const self = this;
    209. const index = self.$$(e.target).parents('label.checkbox').index();
    210. const image = self.images[index];
    211. if (e.target.checked) {
    212. // Add to attachments
    213. self.attachments.unshift(image);
    214. } else {
    215. // Remove from attachments
    216. self.attachments.splice(self.attachments.indexOf(image), 1);
    217. }
    218. },
    219. sendMessage() {
    220. const self = this;
    221. const text = self.messagebar.getValue().replace(/\n/g, '<br>').trim();
    222. const messagesToSend = [];
    223. self.attachments.forEach((attachment) => {
    224. messagesToSend.push({
    225. image: attachment,
    226. });
    227. });
    228. if (text.trim().length) {
    229. messagesToSend.push({
    230. text,
    231. });
    232. }
    233. if (messagesToSend.length === 0) {
    234. return;
    235. }
    236. // Reset attachments
    237. self.attachments = [];
    238. // Hide sheet
    239. self.sheetVisible = false;
    240. // Clear area
    241. self.messagebar.clear();
    242. // Focus area
    243. if (text.length) self.messagebar.focus();
    244. // Send message
    245. self.messagesData.push(...messagesToSend);
    246. // Mock response
    247. if (self.responseInProgress) return;
    248. self.responseInProgress = true;
    249. setTimeout(() => {
    250. const answer = self.answers[Math.floor(Math.random() * self.answers.length)];
    251. const person = self.people[Math.floor(Math.random() * self.people.length)];
    252. self.typingMessage = {
    253. name: person.name,
    254. avatar: person.avatar,
    255. };
    256. setTimeout(() => {
    257. self.messagesData.push({
    258. text: answer,
    259. type: 'received',
    260. name: person.name,
    261. avatar: person.avatar,
    262. });
    263. self.typingMessage = null;
    264. self.responseInProgress = false;
    265. }, 4000);
    266. }, 1000);
    267. },
    268. },
    269. </script>