askbot-dragon 0.6.17 → 0.6.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -27
- package/babel.config.js +5 -5
- package/dragon.iml +7 -7
- package/package.json +54 -52
- package/public/index.html +27 -26
- package/src/App.vue +31 -31
- package/src/api/index.js +1 -1
- package/src/api/mock.http +2 -2
- package/src/api/requestUrl.js +185 -185
- package/src/assets/less/common.css +6760 -6760
- package/src/assets/less/converSationContainer/common.less +4751 -4751
- package/src/assets/less/converSationContainer/converSatonContainer.less +492 -492
- package/src/assets/less/ticketMessage.less +319 -319
- package/src/components/ActionAlertIframe.vue +117 -117
- package/src/components/AskIFrame.vue +15 -15
- package/src/components/ConversationContainer.vue +1388 -1388
- package/src/components/FileType.vue +88 -88
- package/src/components/Message.vue +27 -27
- package/src/components/ask-components/DissatisfactionOptions.vue +57 -57
- package/src/components/ask-components/Msgloading.vue +37 -37
- package/src/components/ask-components/SatisfactionV2.vue +15 -15
- package/src/components/chatContent.vue +512 -512
- package/src/components/feedBack.vue +133 -133
- package/src/components/file/AliyunOssComponents.vue +109 -109
- package/src/components/formTemplate.vue +1898 -2039
- package/src/components/message/ActionAlertIframe.vue +116 -116
- package/src/components/message/ShopMessage.vue +168 -168
- package/src/components/message/TextMessage.vue +895 -895
- package/src/components/message/TicketMessage.vue +173 -173
- package/src/components/message/swiper/index.js +4 -4
- package/src/components/message/swiper/ticketSwiper.vue +530 -530
- package/src/components/message/swiper/ticketSwiperItem.vue +61 -61
- package/src/components/selector/hOption.vue +20 -20
- package/src/components/selector/hSelector.vue +199 -199
- package/src/components/selector/hWrapper.vue +216 -216
- package/src/components/source/BotMessage.vue +24 -24
- package/src/components/source/CustomMessage.vue +24 -24
- package/src/components/test.vue +260 -260
- package/src/components/utils/AliyunIssUtil.js +72 -72
- package/src/components/utils/ckeditor.js +124 -0
- package/src/components/utils/format_date.js +18 -18
- package/src/components/utils/index.js +6 -6
- package/src/components/utils/math_utils.js +15 -15
- package/src/main.js +44 -43
- package/vue.config.js +34 -28
|
@@ -1,217 +1,217 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="h-selector-wrapper" :style="{height: parentHeight+'px'}">
|
|
3
|
-
<!-- 级联选择器的真实节点,无序列表
|
|
4
|
-
ref属性用来获取真实的DOM节点
|
|
5
|
-
style通过数据去设置样式
|
|
6
|
-
监听需要用到的事件
|
|
7
|
-
touchstart 触摸开始
|
|
8
|
-
touchmove 触摸移动
|
|
9
|
-
touchend 触摸结束
|
|
10
|
-
transitionend 过渡结束
|
|
11
|
-
-->
|
|
12
|
-
<ul
|
|
13
|
-
ref="wrapper"
|
|
14
|
-
:style="style"
|
|
15
|
-
@touchstart="touchStart($event)"
|
|
16
|
-
@touchmove="touchMove($event)"
|
|
17
|
-
@touchend="touchEnd($event)"
|
|
18
|
-
@transitionend="transitionEnd($event)"
|
|
19
|
-
>
|
|
20
|
-
<!-- 使用四个空的option来保证可选项的位置,无需动态的通过js修改 -->
|
|
21
|
-
<li class="h-selector-option">
|
|
22
|
-
</li>
|
|
23
|
-
<li class="h-selector-option">
|
|
24
|
-
请选择
|
|
25
|
-
</li>
|
|
26
|
-
<!-- 插槽位置,所有的option可选项都会显示在这里 -->
|
|
27
|
-
<slot></slot>
|
|
28
|
-
<li class="h-selector-option">
|
|
29
|
-
</li>
|
|
30
|
-
<li class="h-selector-option">
|
|
31
|
-
</li>
|
|
32
|
-
</ul>
|
|
33
|
-
</div>
|
|
34
|
-
</template>
|
|
35
|
-
|
|
36
|
-
<script>
|
|
37
|
-
export default {
|
|
38
|
-
name: "hWrapper",
|
|
39
|
-
props: {
|
|
40
|
-
prop: {
|
|
41
|
-
type: String,
|
|
42
|
-
required: true
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
// 定义初始化数据
|
|
46
|
-
data() {
|
|
47
|
-
return {
|
|
48
|
-
// 初始化样式
|
|
49
|
-
style: {
|
|
50
|
-
transform: 'translate3d(0px,0px,0px)',
|
|
51
|
-
transition: 'transform .3s',
|
|
52
|
-
},
|
|
53
|
-
activeIndex: 0, // 当前激活的索引
|
|
54
|
-
startY: 0, // 开始距离
|
|
55
|
-
startTime: 0, // 开始时间
|
|
56
|
-
endY: 0, // 结束距离
|
|
57
|
-
endTime: 0, // 结束时间
|
|
58
|
-
prevY: 0, // 上一次移动的距离
|
|
59
|
-
direction: 0, // 滑动方向
|
|
60
|
-
maxY: 0, // 滑动最大距离
|
|
61
|
-
minY: 0, // 滑动最小距离
|
|
62
|
-
optionHeight: 0, // 每一个选项的高度
|
|
63
|
-
parentHeight: 0, // 父容器的高度
|
|
64
|
-
optionLength: 0 // 选项的长度
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
// 计算属性
|
|
68
|
-
computed: {
|
|
69
|
-
// 得到父组件中,当前级联选择器所绑定的那一条数据
|
|
70
|
-
propValue() {
|
|
71
|
-
return this.$parent.value[this.prop];
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
// 侦听器
|
|
75
|
-
watch: {
|
|
76
|
-
// 侦听activeIndex的变化
|
|
77
|
-
activeIndex(newValue) {
|
|
78
|
-
// 当activeIndex发生变化,并且可以通过这个新的索引找到对应子组件时
|
|
79
|
-
if (this.$children[newValue]) {
|
|
80
|
-
// 调用父组件的$emit方法,发布changeSelected事件
|
|
81
|
-
// 将当前绑定的属性和当前的值发布出去
|
|
82
|
-
// 由于父组件的mounted函数中,使用$on订阅了这个事件
|
|
83
|
-
// 所以父组件能够正确的收到通信
|
|
84
|
-
this.$parent.$emit('changeSelected', this.prop, this.$children[newValue].value);
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
// 侦听当前级联选择器的数据
|
|
88
|
-
propValue(newValue) {
|
|
89
|
-
// 当数据发生改变的时候,向外发布change事件,并将新的值发布在外
|
|
90
|
-
this.$emit('change', newValue);
|
|
91
|
-
// 重置当前级联选择器的位置
|
|
92
|
-
this.formatAddress();
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
// 实例挂载完成
|
|
96
|
-
mounted() {
|
|
97
|
-
// 调用Vue的$nextTick方法,在下一次DOM刷新完成之后调用方法
|
|
98
|
-
this.$nextTick(() => {
|
|
99
|
-
// 重置数据
|
|
100
|
-
this.formatData();
|
|
101
|
-
// 重置当前级联选择器的位置
|
|
102
|
-
this.formatAddress();
|
|
103
|
-
});
|
|
104
|
-
// 由于是移动端的demo、所以顺便订阅resize事件,当屏幕大小发生改变的时候再次重置选择器
|
|
105
|
-
/* window.addEventListener('resize', () => {
|
|
106
|
-
this.formatData();
|
|
107
|
-
this.formatAddress();
|
|
108
|
-
})*/
|
|
109
|
-
},
|
|
110
|
-
// 当组件数据更新完成
|
|
111
|
-
updated() {
|
|
112
|
-
// 调用Vue的$nextTick方法,在下一次DOM刷新完成之后调用方法
|
|
113
|
-
this.$nextTick(() => {
|
|
114
|
-
// 重置数据
|
|
115
|
-
this.formatData();
|
|
116
|
-
// 重置当前级联选择器的位置
|
|
117
|
-
this.formatAddress();
|
|
118
|
-
})
|
|
119
|
-
},
|
|
120
|
-
methods: {
|
|
121
|
-
// 重置数据的方法
|
|
122
|
-
formatData() {
|
|
123
|
-
// 保存当前的子组件,使用this.$children获取到的是当前组件所有的子组件(子Vue实例)
|
|
124
|
-
let children = this.$children;
|
|
125
|
-
// 保存当前选项的长度
|
|
126
|
-
this.optionLength = children.length;
|
|
127
|
-
// try {
|
|
128
|
-
// this.optionHeight = children[0].$el.offsetHeight;
|
|
129
|
-
// } catch {
|
|
130
|
-
// 保存当前option的高度
|
|
131
|
-
this.optionHeight = this.$refs['wrapper'].children[0].offsetHeight;
|
|
132
|
-
// }
|
|
133
|
-
// 为最外层的父元素设置高度,高度为option的5倍,即一次显示5个option
|
|
134
|
-
this.parentHeight = this.optionHeight * 5;
|
|
135
|
-
// 保存滑动的最大高度
|
|
136
|
-
this.maxY = -this.optionHeight * (this.optionLength - 1);
|
|
137
|
-
},
|
|
138
|
-
// 重置级联选择器位置
|
|
139
|
-
formatAddress() {
|
|
140
|
-
// 保存当前组件的子组件
|
|
141
|
-
let children = this.$children;
|
|
142
|
-
// 查询到当前组件中与外层传入的数据对应的子组件的索引值
|
|
143
|
-
let index = children.findIndex(item => item.value === this.$parent.value[this.prop]);
|
|
144
|
-
// 将索引值赋予activeIndex,如果能查找到对应的,说明外部传值了,
|
|
145
|
-
// 就自动滑动到当前索引的位置,否则就显示请选择
|
|
146
|
-
this.activeIndex = index > -1 ? index : -1;
|
|
147
|
-
// 通过索引值与当前option的高度计算距离,并执行动画
|
|
148
|
-
this.style.transform = `translate3d(0px,${-this.activeIndex * this.optionHeight}px,0px)`;
|
|
149
|
-
},
|
|
150
|
-
// 触碰开始
|
|
151
|
-
touchStart(e) {
|
|
152
|
-
// 保存触碰开始的位置
|
|
153
|
-
this.startY = e.touches[0].pageY;
|
|
154
|
-
// 保存触碰开始的时间
|
|
155
|
-
this.startTime = e.timeStamp;
|
|
156
|
-
// 清除过渡动画
|
|
157
|
-
this.style.transition = 'none';
|
|
158
|
-
},
|
|
159
|
-
// 触碰移动
|
|
160
|
-
touchMove(e) {
|
|
161
|
-
// 保存当前移动的位置
|
|
162
|
-
let moveY = e.changedTouches[0].pageY;
|
|
163
|
-
// 保存当前移动的方向,往下拉的话,moveY - this.startY为正,往上拉的话为负
|
|
164
|
-
this.direction = moveY - this.startY;
|
|
165
|
-
// 设置拖拽移动
|
|
166
|
-
this.style.transform = `translate3d(0px,${this.prevY + this.direction}px,0px)`;
|
|
167
|
-
},
|
|
168
|
-
// 触碰结束
|
|
169
|
-
touchEnd(e) {
|
|
170
|
-
// 设置过渡动画
|
|
171
|
-
this.style.transition = 'transform .4s';
|
|
172
|
-
// 保存结束位置
|
|
173
|
-
this.endY = e.changedTouches[0].pageY;
|
|
174
|
-
// 保存结束时间
|
|
175
|
-
this.endTime = e.timeStamp;
|
|
176
|
-
// 保存上一次移动的距离
|
|
177
|
-
this.prevY = this.style.transform.split(',')[1].slice(0, -2) * 1;
|
|
178
|
-
// 计算当前移动到的位置索引
|
|
179
|
-
let activeIndex = -Math.round(this.prevY / this.optionHeight);
|
|
180
|
-
// 计算当前手指从触碰开始到结束移动的距离
|
|
181
|
-
let distance = Math.abs(this.endY - this.startY);
|
|
182
|
-
// 计算当前手指从触碰开始到结束的时间差
|
|
183
|
-
let interval = this.endTime - this.startTime;
|
|
184
|
-
// 根据方向不同来计算应该移动到对应的索引值上
|
|
185
|
-
// 大于0 为向下拉
|
|
186
|
-
if (this.direction > 0) {
|
|
187
|
-
// 通过距离与时间差来计算最新的坐标索引
|
|
188
|
-
activeIndex = this.activeIndex - Math.round(distance / interval) * 2;
|
|
189
|
-
// 小于 0 为向上拉
|
|
190
|
-
} else if (this.direction < 0) {
|
|
191
|
-
// 通过距离与时间差来计算最新的坐标索引
|
|
192
|
-
activeIndex = this.activeIndex + Math.round(distance / interval) * 2;
|
|
193
|
-
}
|
|
194
|
-
// 判断当前移动距离特别小,判定为触碰事件,而不是滑动
|
|
195
|
-
if (distance <= 1) {
|
|
196
|
-
// e.path 保存了触发当前事件的源数组、0号元素代表当前点击的option
|
|
197
|
-
// 通过当前点击的元素的offsetTop计算当前元素正确的索引值
|
|
198
|
-
activeIndex = Math.round((e.path[0].offsetTop - this.optionHeight * 2) / this.optionHeight);
|
|
199
|
-
}
|
|
200
|
-
// 对activeIndex值进行进一步处理,保证其不会超出选项范围
|
|
201
|
-
activeIndex = activeIndex < 0 ? 0 : activeIndex > this.optionLength - 1 ? this.optionLength - 1 : activeIndex;
|
|
202
|
-
// 执行判断并赋值索引
|
|
203
|
-
this.activeIndex = activeIndex;
|
|
204
|
-
// 通过索引值计算位移,并执行动画
|
|
205
|
-
this.style.transform = `translate3d(0px,${-this.activeIndex * this.optionHeight}px,0px)`;
|
|
206
|
-
},
|
|
207
|
-
// 过渡结束
|
|
208
|
-
transitionEnd() {
|
|
209
|
-
// 保存上一次移动的距离
|
|
210
|
-
this.prevY = -this.activeIndex * this.optionHeight;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
</script>
|
|
215
|
-
<style scoped>
|
|
216
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<div class="h-selector-wrapper" :style="{height: parentHeight+'px'}">
|
|
3
|
+
<!-- 级联选择器的真实节点,无序列表
|
|
4
|
+
ref属性用来获取真实的DOM节点
|
|
5
|
+
style通过数据去设置样式
|
|
6
|
+
监听需要用到的事件
|
|
7
|
+
touchstart 触摸开始
|
|
8
|
+
touchmove 触摸移动
|
|
9
|
+
touchend 触摸结束
|
|
10
|
+
transitionend 过渡结束
|
|
11
|
+
-->
|
|
12
|
+
<ul
|
|
13
|
+
ref="wrapper"
|
|
14
|
+
:style="style"
|
|
15
|
+
@touchstart="touchStart($event)"
|
|
16
|
+
@touchmove="touchMove($event)"
|
|
17
|
+
@touchend="touchEnd($event)"
|
|
18
|
+
@transitionend="transitionEnd($event)"
|
|
19
|
+
>
|
|
20
|
+
<!-- 使用四个空的option来保证可选项的位置,无需动态的通过js修改 -->
|
|
21
|
+
<li class="h-selector-option">
|
|
22
|
+
</li>
|
|
23
|
+
<li class="h-selector-option">
|
|
24
|
+
请选择
|
|
25
|
+
</li>
|
|
26
|
+
<!-- 插槽位置,所有的option可选项都会显示在这里 -->
|
|
27
|
+
<slot></slot>
|
|
28
|
+
<li class="h-selector-option">
|
|
29
|
+
</li>
|
|
30
|
+
<li class="h-selector-option">
|
|
31
|
+
</li>
|
|
32
|
+
</ul>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script>
|
|
37
|
+
export default {
|
|
38
|
+
name: "hWrapper",
|
|
39
|
+
props: {
|
|
40
|
+
prop: {
|
|
41
|
+
type: String,
|
|
42
|
+
required: true
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
// 定义初始化数据
|
|
46
|
+
data() {
|
|
47
|
+
return {
|
|
48
|
+
// 初始化样式
|
|
49
|
+
style: {
|
|
50
|
+
transform: 'translate3d(0px,0px,0px)',
|
|
51
|
+
transition: 'transform .3s',
|
|
52
|
+
},
|
|
53
|
+
activeIndex: 0, // 当前激活的索引
|
|
54
|
+
startY: 0, // 开始距离
|
|
55
|
+
startTime: 0, // 开始时间
|
|
56
|
+
endY: 0, // 结束距离
|
|
57
|
+
endTime: 0, // 结束时间
|
|
58
|
+
prevY: 0, // 上一次移动的距离
|
|
59
|
+
direction: 0, // 滑动方向
|
|
60
|
+
maxY: 0, // 滑动最大距离
|
|
61
|
+
minY: 0, // 滑动最小距离
|
|
62
|
+
optionHeight: 0, // 每一个选项的高度
|
|
63
|
+
parentHeight: 0, // 父容器的高度
|
|
64
|
+
optionLength: 0 // 选项的长度
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
// 计算属性
|
|
68
|
+
computed: {
|
|
69
|
+
// 得到父组件中,当前级联选择器所绑定的那一条数据
|
|
70
|
+
propValue() {
|
|
71
|
+
return this.$parent.value[this.prop];
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
// 侦听器
|
|
75
|
+
watch: {
|
|
76
|
+
// 侦听activeIndex的变化
|
|
77
|
+
activeIndex(newValue) {
|
|
78
|
+
// 当activeIndex发生变化,并且可以通过这个新的索引找到对应子组件时
|
|
79
|
+
if (this.$children[newValue]) {
|
|
80
|
+
// 调用父组件的$emit方法,发布changeSelected事件
|
|
81
|
+
// 将当前绑定的属性和当前的值发布出去
|
|
82
|
+
// 由于父组件的mounted函数中,使用$on订阅了这个事件
|
|
83
|
+
// 所以父组件能够正确的收到通信
|
|
84
|
+
this.$parent.$emit('changeSelected', this.prop, this.$children[newValue].value);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
// 侦听当前级联选择器的数据
|
|
88
|
+
propValue(newValue) {
|
|
89
|
+
// 当数据发生改变的时候,向外发布change事件,并将新的值发布在外
|
|
90
|
+
this.$emit('change', newValue);
|
|
91
|
+
// 重置当前级联选择器的位置
|
|
92
|
+
this.formatAddress();
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
// 实例挂载完成
|
|
96
|
+
mounted() {
|
|
97
|
+
// 调用Vue的$nextTick方法,在下一次DOM刷新完成之后调用方法
|
|
98
|
+
this.$nextTick(() => {
|
|
99
|
+
// 重置数据
|
|
100
|
+
this.formatData();
|
|
101
|
+
// 重置当前级联选择器的位置
|
|
102
|
+
this.formatAddress();
|
|
103
|
+
});
|
|
104
|
+
// 由于是移动端的demo、所以顺便订阅resize事件,当屏幕大小发生改变的时候再次重置选择器
|
|
105
|
+
/* window.addEventListener('resize', () => {
|
|
106
|
+
this.formatData();
|
|
107
|
+
this.formatAddress();
|
|
108
|
+
})*/
|
|
109
|
+
},
|
|
110
|
+
// 当组件数据更新完成
|
|
111
|
+
updated() {
|
|
112
|
+
// 调用Vue的$nextTick方法,在下一次DOM刷新完成之后调用方法
|
|
113
|
+
this.$nextTick(() => {
|
|
114
|
+
// 重置数据
|
|
115
|
+
this.formatData();
|
|
116
|
+
// 重置当前级联选择器的位置
|
|
117
|
+
this.formatAddress();
|
|
118
|
+
})
|
|
119
|
+
},
|
|
120
|
+
methods: {
|
|
121
|
+
// 重置数据的方法
|
|
122
|
+
formatData() {
|
|
123
|
+
// 保存当前的子组件,使用this.$children获取到的是当前组件所有的子组件(子Vue实例)
|
|
124
|
+
let children = this.$children;
|
|
125
|
+
// 保存当前选项的长度
|
|
126
|
+
this.optionLength = children.length;
|
|
127
|
+
// try {
|
|
128
|
+
// this.optionHeight = children[0].$el.offsetHeight;
|
|
129
|
+
// } catch {
|
|
130
|
+
// 保存当前option的高度
|
|
131
|
+
this.optionHeight = this.$refs['wrapper'].children[0].offsetHeight;
|
|
132
|
+
// }
|
|
133
|
+
// 为最外层的父元素设置高度,高度为option的5倍,即一次显示5个option
|
|
134
|
+
this.parentHeight = this.optionHeight * 5;
|
|
135
|
+
// 保存滑动的最大高度
|
|
136
|
+
this.maxY = -this.optionHeight * (this.optionLength - 1);
|
|
137
|
+
},
|
|
138
|
+
// 重置级联选择器位置
|
|
139
|
+
formatAddress() {
|
|
140
|
+
// 保存当前组件的子组件
|
|
141
|
+
let children = this.$children;
|
|
142
|
+
// 查询到当前组件中与外层传入的数据对应的子组件的索引值
|
|
143
|
+
let index = children.findIndex(item => item.value === this.$parent.value[this.prop]);
|
|
144
|
+
// 将索引值赋予activeIndex,如果能查找到对应的,说明外部传值了,
|
|
145
|
+
// 就自动滑动到当前索引的位置,否则就显示请选择
|
|
146
|
+
this.activeIndex = index > -1 ? index : -1;
|
|
147
|
+
// 通过索引值与当前option的高度计算距离,并执行动画
|
|
148
|
+
this.style.transform = `translate3d(0px,${-this.activeIndex * this.optionHeight}px,0px)`;
|
|
149
|
+
},
|
|
150
|
+
// 触碰开始
|
|
151
|
+
touchStart(e) {
|
|
152
|
+
// 保存触碰开始的位置
|
|
153
|
+
this.startY = e.touches[0].pageY;
|
|
154
|
+
// 保存触碰开始的时间
|
|
155
|
+
this.startTime = e.timeStamp;
|
|
156
|
+
// 清除过渡动画
|
|
157
|
+
this.style.transition = 'none';
|
|
158
|
+
},
|
|
159
|
+
// 触碰移动
|
|
160
|
+
touchMove(e) {
|
|
161
|
+
// 保存当前移动的位置
|
|
162
|
+
let moveY = e.changedTouches[0].pageY;
|
|
163
|
+
// 保存当前移动的方向,往下拉的话,moveY - this.startY为正,往上拉的话为负
|
|
164
|
+
this.direction = moveY - this.startY;
|
|
165
|
+
// 设置拖拽移动
|
|
166
|
+
this.style.transform = `translate3d(0px,${this.prevY + this.direction}px,0px)`;
|
|
167
|
+
},
|
|
168
|
+
// 触碰结束
|
|
169
|
+
touchEnd(e) {
|
|
170
|
+
// 设置过渡动画
|
|
171
|
+
this.style.transition = 'transform .4s';
|
|
172
|
+
// 保存结束位置
|
|
173
|
+
this.endY = e.changedTouches[0].pageY;
|
|
174
|
+
// 保存结束时间
|
|
175
|
+
this.endTime = e.timeStamp;
|
|
176
|
+
// 保存上一次移动的距离
|
|
177
|
+
this.prevY = this.style.transform.split(',')[1].slice(0, -2) * 1;
|
|
178
|
+
// 计算当前移动到的位置索引
|
|
179
|
+
let activeIndex = -Math.round(this.prevY / this.optionHeight);
|
|
180
|
+
// 计算当前手指从触碰开始到结束移动的距离
|
|
181
|
+
let distance = Math.abs(this.endY - this.startY);
|
|
182
|
+
// 计算当前手指从触碰开始到结束的时间差
|
|
183
|
+
let interval = this.endTime - this.startTime;
|
|
184
|
+
// 根据方向不同来计算应该移动到对应的索引值上
|
|
185
|
+
// 大于0 为向下拉
|
|
186
|
+
if (this.direction > 0) {
|
|
187
|
+
// 通过距离与时间差来计算最新的坐标索引
|
|
188
|
+
activeIndex = this.activeIndex - Math.round(distance / interval) * 2;
|
|
189
|
+
// 小于 0 为向上拉
|
|
190
|
+
} else if (this.direction < 0) {
|
|
191
|
+
// 通过距离与时间差来计算最新的坐标索引
|
|
192
|
+
activeIndex = this.activeIndex + Math.round(distance / interval) * 2;
|
|
193
|
+
}
|
|
194
|
+
// 判断当前移动距离特别小,判定为触碰事件,而不是滑动
|
|
195
|
+
if (distance <= 1) {
|
|
196
|
+
// e.path 保存了触发当前事件的源数组、0号元素代表当前点击的option
|
|
197
|
+
// 通过当前点击的元素的offsetTop计算当前元素正确的索引值
|
|
198
|
+
activeIndex = Math.round((e.path[0].offsetTop - this.optionHeight * 2) / this.optionHeight);
|
|
199
|
+
}
|
|
200
|
+
// 对activeIndex值进行进一步处理,保证其不会超出选项范围
|
|
201
|
+
activeIndex = activeIndex < 0 ? 0 : activeIndex > this.optionLength - 1 ? this.optionLength - 1 : activeIndex;
|
|
202
|
+
// 执行判断并赋值索引
|
|
203
|
+
this.activeIndex = activeIndex;
|
|
204
|
+
// 通过索引值计算位移,并执行动画
|
|
205
|
+
this.style.transform = `translate3d(0px,${-this.activeIndex * this.optionHeight}px,0px)`;
|
|
206
|
+
},
|
|
207
|
+
// 过渡结束
|
|
208
|
+
transitionEnd() {
|
|
209
|
+
// 保存上一次移动的距离
|
|
210
|
+
this.prevY = -this.activeIndex * this.optionHeight;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
</script>
|
|
215
|
+
<style scoped>
|
|
216
|
+
|
|
217
217
|
</style>
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
<!-- 机器人消息 -->
|
|
2
|
-
<template>
|
|
3
|
-
<div class="bot-message">
|
|
4
|
-
|
|
5
|
-
<div >
|
|
6
|
-
|
|
7
|
-
</div>
|
|
8
|
-
|
|
9
|
-
</div>
|
|
10
|
-
</template>
|
|
11
|
-
|
|
12
|
-
<script>
|
|
13
|
-
export default {
|
|
14
|
-
name: 'BotMessage',
|
|
15
|
-
props: {
|
|
16
|
-
message : Object
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
22
|
-
<style scoped>
|
|
23
|
-
|
|
24
|
-
</style>
|
|
1
|
+
<!-- 机器人消息 -->
|
|
2
|
+
<template>
|
|
3
|
+
<div class="bot-message">
|
|
4
|
+
|
|
5
|
+
<div >
|
|
6
|
+
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script>
|
|
13
|
+
export default {
|
|
14
|
+
name: 'BotMessage',
|
|
15
|
+
props: {
|
|
16
|
+
message : Object
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
22
|
+
<style scoped>
|
|
23
|
+
|
|
24
|
+
</style>
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
<!-- 机器人消息 -->
|
|
2
|
-
<template>
|
|
3
|
-
<div class="custom-message">
|
|
4
|
-
|
|
5
|
-
<div >
|
|
6
|
-
|
|
7
|
-
</div>
|
|
8
|
-
|
|
9
|
-
</div>
|
|
10
|
-
</template>
|
|
11
|
-
|
|
12
|
-
<script>
|
|
13
|
-
export default {
|
|
14
|
-
name: 'CustomMessage',
|
|
15
|
-
props: {
|
|
16
|
-
message : Object
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
22
|
-
<style scoped>
|
|
23
|
-
|
|
24
|
-
</style>
|
|
1
|
+
<!-- 机器人消息 -->
|
|
2
|
+
<template>
|
|
3
|
+
<div class="custom-message">
|
|
4
|
+
|
|
5
|
+
<div >
|
|
6
|
+
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script>
|
|
13
|
+
export default {
|
|
14
|
+
name: 'CustomMessage',
|
|
15
|
+
props: {
|
|
16
|
+
message : Object
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
22
|
+
<style scoped>
|
|
23
|
+
|
|
24
|
+
</style>
|