1 | <template>
|
2 | <div class="mychat" :class="data.dir">
|
3 | <div class="mychat-avatar" :class="data.dir" :style="avatarStyle"></div>
|
4 | <div class="mychat-content" :class="data.dir">
|
5 | <div class="mychat-top">
|
6 | <slot name="top"></slot>
|
7 | </div>
|
8 | <div class="mychat-center">
|
9 | <div class="mychat-triangle" :style="triangle"></div>
|
10 | <div class="mychat-wrod" :class="data.dir" :style="data.style">
|
11 | <slot name="content"></slot>
|
12 | </div>
|
13 | <div class="mychat-action" :class="data.dir">
|
14 | <slot name="action"></slot>
|
15 | </div>
|
16 | </div>
|
17 | <div class="mychat-bottom">
|
18 | <slot name="bottom"></slot>
|
19 | </div>
|
20 | </div>
|
21 | </div>
|
22 | </template>
|
23 | <script>
|
24 | /**
|
25 | * 聊天对话框
|
26 | *
|
27 | * 数据格式
|
28 | * {
|
29 | dir: "left",
|
30 | avatar: "/yngpProduct/manage/common/images/avatar.jpg",
|
31 | style: {
|
32 | background: "red",
|
33 | color: "white"
|
34 | }
|
35 | }
|
36 |
|
37 | * 使用方法
|
38 | * <yn-chat v-for="item in chats" :data="item" :key="item.id">
|
39 | <div slot="top">{{item.name}}</div>
|
40 | <div slot="content">{{item.content}}</div>
|
41 | <div slot="bottom">{{item.time}}</div>
|
42 | <div slot="action" @click="onReply(item)">回复</div>
|
43 | </yn-chat>
|
44 | */
|
45 | export default {
|
46 | props: {
|
47 | data: {
|
48 | type: Object,
|
49 | default: () => {
|
50 | return {
|
51 | dir: "left",
|
52 | avatar: "@common/images/avatar.png"
|
53 | };
|
54 | }
|
55 | }
|
56 | },
|
57 | computed: {
|
58 | avatarStyle() {
|
59 | return {
|
60 | backgroundImage: `url('${this.data.avatar}')`
|
61 | };
|
62 | },
|
63 | triangle() {
|
64 | let bg = "#e6e6e6";
|
65 | const { style, dir } = this.data;
|
66 | if (style && style.background) {
|
67 | bg = style.background;
|
68 | }
|
69 | const isRight = dir == "right";
|
70 | const reverse = isRight ? "left" : "right";
|
71 | const angle = isRight ? -10 : 10;
|
72 | return {
|
73 | border: "8px solid transparent",
|
74 | [`border-${reverse}-color`]: bg,
|
75 | position: "absolute",
|
76 | [dir]: "-13px",
|
77 | top: "7px",
|
78 | transform: `rotate(${angle}deg)`
|
79 | };
|
80 | }
|
81 | }
|
82 | };
|
83 | </script>
|
84 | <style lang="scss" scoped>
|
85 | .mychat {
|
86 | margin: 25px 0;
|
87 | overflow: hidden;
|
88 | .left {
|
89 | float: left;
|
90 | }
|
91 | .right {
|
92 | float: right;
|
93 | &.mychat-content {
|
94 | text-align: right;
|
95 | .mychat-center {
|
96 | text-align: left;
|
97 | flex-direction: row-reverse;
|
98 | }
|
99 | }
|
100 | }
|
101 | .mychat-avatar {
|
102 | width: 40px;
|
103 | height: 40px;
|
104 | position: relative;
|
105 | top: 15px;
|
106 | overflow: hidden;
|
107 | background: rgb(230, 230, 230);
|
108 | border-radius: 50%;
|
109 | background-size: 100% auto;
|
110 | background-position: center center;
|
111 | }
|
112 | .mychat-content {
|
113 | line-height: 1.7em;
|
114 | max-width: 60%;
|
115 | margin: 0 15px;
|
116 | color: rgb(61, 61, 61);
|
117 | .mychat-top {
|
118 | color: gray;
|
119 | }
|
120 | .mychat-center {
|
121 | align-items: center;
|
122 | margin: 5px 0;
|
123 | position: relative;
|
124 | min-width: 80px;
|
125 | display: flex;
|
126 | .mychat-wrod {
|
127 | color: rgb(60, 60, 60);
|
128 | border-radius: 4px;
|
129 | background: rgb(230, 230, 230);
|
130 | padding: 15px;
|
131 | flex-grow: 1;
|
132 | }
|
133 | .mychat-action {
|
134 | flex-shrink: 0;
|
135 | cursor: pointer;
|
136 | margin: 0 5px;
|
137 | }
|
138 | }
|
139 | .mychat-bottom {
|
140 | color: gray;
|
141 | }
|
142 | }
|
143 | }
|
144 | </style>
|
145 |
|