waterflow.uvue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. <script>
  2. type ScrollEventTest = {
  3. type : string;
  4. target : UniElement | null;
  5. currentTarget : UniElement | null;
  6. direction ?: string
  7. }
  8. type flowItemData = {
  9. height : number,
  10. text : string
  11. }
  12. import { ItemType } from '@/components/enum-data/enum-data-types'
  13. export default {
  14. data() {
  15. return {
  16. refresher_triggered_boolean: false,
  17. refresher_enabled_boolean: false,
  18. scroll_with_animation_boolean: false,
  19. show_scrollbar_boolean: false,
  20. bounces_boolean: true,
  21. upper_threshold_input: 50,
  22. lower_threshold_input: 50,
  23. scroll_top_input: 0,
  24. scroll_left_input: 0,
  25. refresher_background_input: "#FFF",
  26. scrollData: [] as Array<flowItemData>,
  27. size_enum: [{ "value": 0, "name": "item---0" }, { "value": 3, "name": "item---3" }] as ItemType[],
  28. scrollIntoView: "",
  29. refresherrefresh: false,
  30. refresher_default_style_input: "black",
  31. text: ['继续下拉执行刷新', '释放立即刷新', '刷新中', ""],
  32. state: 3,
  33. reset: true,
  34. // 自动化测试
  35. isScrollTest: '',
  36. isScrolltolowerTest: '',
  37. isScrolltoupperTest: '',
  38. scrollDetailTest: null as UniScrollEventDetail | null,
  39. scrollEndDetailTest: null as UniScrollEventDetail | null,
  40. cross_axis_count: 2,
  41. main_axis_gap: 2,
  42. cross_axis_gap: 2,
  43. waterflowPadding: [10, 5, 10, 5] as Array<number>,
  44. loadMore: true,
  45. isLoadMore: true,
  46. waterflow: null as UniElement | null
  47. }
  48. },
  49. onLoad() {
  50. //静态瀑布流数据
  51. this.scrollData = [
  52. { height: 300, text: "item---0" },
  53. { height: 150, text: "item---1" },
  54. { height: 120, text: "item---2" },
  55. { height: 100, text: "item---3" },
  56. { height: 100, text: "item---4" },
  57. { height: 150, text: "item---5" },
  58. { height: 140, text: "item---6" },
  59. { height: 190, text: "item---7" },
  60. { height: 160, text: "item---8" },
  61. { height: 120, text: "item---9" },
  62. { height: 109, text: "item---10" },
  63. { height: 102, text: "item---11" },
  64. { height: 123, text: "item---12" },
  65. { height: 156, text: "item---13" },
  66. { height: 177, text: "item---14" },
  67. { height: 105, text: "item---15" },
  68. { height: 110, text: "item---16" },
  69. { height: 90, text: "item---17" },
  70. { height: 130, text: "item---18" },
  71. { height: 140, text: "item---19" },
  72. ] as Array<flowItemData>
  73. },
  74. onReady() {
  75. // 组件ready时,获取组件实例
  76. this.waterflow = this.$refs["waterflow"] as UniElement
  77. },
  78. methods: {
  79. waterflow_click() { console.log("组件被点击时触发") },
  80. waterflow_touchstart() { console.log("手指触摸动作开始") },
  81. waterflow_touchmove() { console.log("手指触摸后移动") },
  82. waterflow_touchcancel() { console.log("手指触摸动作被打断,如来电提醒,弹窗") },
  83. waterflow_touchend() { console.log("手指触摸动作结束") },
  84. waterflow_tap() { console.log("手指触摸后马上离开") },
  85. waterflow_longpress() { console.log("如果一个组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。") },
  86. waterflow_refresherpulling(e : RefresherEvent) {
  87. console.log("下拉刷新控件被下拉")
  88. if (this.reset) {
  89. if (e.detail.dy > 45) {
  90. this.state = 1
  91. } else {
  92. this.state = 0
  93. }
  94. }
  95. },
  96. waterflow_refresherrefresh() {
  97. console.log("下拉刷新被触发 ")
  98. this.refresherrefresh = true
  99. this.refresher_triggered_boolean = true
  100. this.state = 2
  101. this.reset = false;
  102. setTimeout(() => {
  103. this.refresher_triggered_boolean = false
  104. }, 1500)
  105. },
  106. waterflow_refresherrestore() {
  107. this.refresherrefresh = false
  108. this.state = 3
  109. this.reset = true
  110. console.log("下拉刷新被复位")
  111. },
  112. waterflow_refresherabort() { console.log("下拉刷新被中止") },
  113. waterflow_scrolltoupper(e : UniScrollToUpperEvent) {
  114. console.log("滚动到顶部/左边,会触发 scrolltoupper 事件 direction=" + e.detail.direction)
  115. this.checkEventTest({
  116. type: e.type,
  117. target: e.target,
  118. currentTarget: e.currentTarget,
  119. direction: e.detail.direction,
  120. } as ScrollEventTest, 'scrolltoupper')
  121. },
  122. waterflow_scrolltolower(e : UniScrollToLowerEvent) {
  123. console.log("滚动到底部/右边,会触发 scrolltolower 事件 direction=" + e.detail.direction)
  124. this.checkEventTest({
  125. type: e.type,
  126. target: e.target,
  127. currentTarget: e.currentTarget,
  128. direction: e.detail.direction,
  129. } as ScrollEventTest, 'scrolltolower')
  130. },
  131. waterflow_scroll(e : UniScrollEvent) {
  132. console.log("滚动时触发,event.detail = ", e.detail)
  133. this.scrollDetailTest = e.detail
  134. this.checkEventTest({
  135. type: e.type,
  136. target: e.target,
  137. currentTarget: e.currentTarget
  138. } as ScrollEventTest, 'scroll')
  139. },
  140. waterflow_scrollend(e : UniScrollEvent) {
  141. console.log("滚动结束时触发", e.detail)
  142. this.scrollEndDetailTest = e.detail
  143. this.checkEventTest({
  144. type: e.type,
  145. target: e.target,
  146. currentTarget: e.currentTarget
  147. } as ScrollEventTest, 'scrollend')
  148. },
  149. flow_item_click() { console.log("flow-item组件被点击时触发") },
  150. flow_item_touchstart() { console.log("手指触摸flow-item组件动作开始") },
  151. flow_item_touchmove() { console.log("手指触摸flow-item组件后移动") },
  152. flow_item_touchcancel() { console.log("手指触摸flow-item组件动作被打断,如来电提醒,弹窗") },
  153. flow_item_touchend() { console.log("手指触摸flow-item组件动作结束") },
  154. flow_item_tap() { console.log("手指触摸flow-item组件后马上离开") },
  155. flow_item_longpress() { console.log("flow-item组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。") },
  156. change_refresher_triggered_boolean(checked : boolean) { this.refresher_triggered_boolean = checked },
  157. change_refresher_enabled_boolean(checked : boolean) { this.refresher_enabled_boolean = checked },
  158. change_scroll_with_animation_boolean(checked : boolean) { this.scroll_with_animation_boolean = checked },
  159. change_show_scrollbar_boolean(checked : boolean) { this.show_scrollbar_boolean = checked },
  160. change_bounces_boolean(checked : boolean) { this.bounces_boolean = checked },
  161. confirm_upper_threshold_input(value : number) { this.upper_threshold_input = value },
  162. confirm_lower_threshold_input(value : number) { this.lower_threshold_input = value },
  163. confirm_scroll_top_input(value : number) { this.scroll_top_input = value },
  164. confirm_scroll_left_input(value : number) { this.scroll_left_input = value },
  165. confirm_refresher_background_input(value : string) { this.refresher_background_input = value },
  166. item_change_size_enum(index : number) { this.scrollIntoView = "item---" + index },
  167. //自动化测试专用
  168. setScrollIntoView(id : string) { this.scrollIntoView = id },
  169. // 自动化测试专用(由于事件event参数对象中存在循环引用,在ios端JSON.stringify报错,自动化测试无法page.data获取)
  170. checkEventTest(e : ScrollEventTest, eventName : String) {
  171. const isPass = e.type === eventName && e.target instanceof UniElement && e.currentTarget instanceof UniElement;
  172. const result = isPass ? `${eventName}:Success` : `${eventName}:Fail`;
  173. switch (eventName) {
  174. case 'scroll':
  175. this.isScrollTest = result
  176. break;
  177. case 'scrolltolower':
  178. this.isScrolltolowerTest = result + `-${e.direction}`
  179. break;
  180. case 'scrolltoupper':
  181. this.isScrolltoupperTest = result + `-${e.direction}`
  182. break;
  183. default:
  184. break;
  185. }
  186. },
  187. //自动化测试例专用
  188. check_scroll_height() : Boolean {
  189. var listElement = this.$refs["waterflow"] as UniElement
  190. console.log("check_scroll_height--" + listElement.scrollHeight)
  191. if (listElement.scrollHeight > 1400) {
  192. return true
  193. }
  194. return false
  195. },
  196. getScrollTop() : number {
  197. var ret = this.waterflow?.scrollTop ?? 0
  198. console.log(ret)
  199. return ret
  200. },
  201. change_refresher_style_boolean(checked : boolean) {
  202. if (checked) {
  203. this.refresher_default_style_input = "none"
  204. } else {
  205. this.refresher_default_style_input = "black"
  206. }
  207. },
  208. change_load_more_boolean(checked : boolean) {
  209. this.isLoadMore = checked
  210. },
  211. handleChangeCrossAxisCount(value : number) {
  212. if (value < 1) {
  213. uni.showToast({ title: "cross-axis-count 最小值为 1 请重新设置" })
  214. return
  215. }
  216. this.cross_axis_count = value
  217. },
  218. handleChangeCrossAxisGap(e : UniSliderChangeEvent) {
  219. this.cross_axis_gap = e.detail.value
  220. },
  221. handleChangeMainAxisGap(e : UniSliderChangeEvent) {
  222. this.main_axis_gap = e.detail.value
  223. },
  224. //仅自动化测试调用
  225. testModifyWaterflowProps() {
  226. this.cross_axis_count = 4
  227. this.main_axis_gap = 6
  228. this.cross_axis_gap = 6
  229. this.waterflowPadding = [5, 10, 5, 10] as Array<number>
  230. },
  231. //仅自动化测试调用
  232. testModifyWaterflowSingleRow() {
  233. this.cross_axis_count = 1
  234. this.main_axis_gap = 6
  235. this.cross_axis_gap = 6
  236. }
  237. }
  238. }
  239. </script>
  240. <template>
  241. <view class="main">
  242. <waterflow :cross-axis-count="cross_axis_count" :main-axis-gap="main_axis_gap" :cross-axis-gap="cross_axis_gap"
  243. :bounces="bounces_boolean" :upper-threshold="upper_threshold_input" :lower-threshold="lower_threshold_input"
  244. :scroll-top="scroll_top_input" :scroll-left="scroll_left_input" :show-scrollbar="show_scrollbar_boolean"
  245. :scroll-into-view="scrollIntoView" :scroll-with-animation="scroll_with_animation_boolean"
  246. :refresher-enabled="refresher_enabled_boolean" :refresher-background="refresher_background_input"
  247. :refresher-triggered="refresher_triggered_boolean" :refresher-default-style="refresher_default_style_input"
  248. @click="waterflow_click" @touchstart="waterflow_touchstart" @touchmove="waterflow_touchmove"
  249. @touchcancel="waterflow_touchcancel" @touchend="waterflow_touchend" @tap="waterflow_tap"
  250. @longpress="waterflow_longpress" @refresherpulling="waterflow_refresherpulling"
  251. @refresherrefresh="waterflow_refresherrefresh" @refresherrestore="waterflow_refresherrestore"
  252. @refresherabort="waterflow_refresherabort" @scrolltoupper="waterflow_scrolltoupper" ref="waterflow"
  253. @scrolltolower="waterflow_scrolltolower" @scroll="waterflow_scroll" @scrollend="waterflow_scrollend"
  254. style="width:100%; " id="waterflow" :padding="waterflowPadding">
  255. <flow-item v-for="(item, index) in scrollData" :key="index" :id="item.text" @click="flow_item_click"
  256. :style="{'height' : item.height}" @touchstart="flow_item_touchstart" @touchmove="flow_item_touchmove"
  257. @touchcancel="flow_item_touchcancel" @touchend="flow_item_touchend" @tap="flow_item_tap"
  258. @longpress="flow_item_longpress" class="flow-item" type=1>
  259. <text>{{item.text}}</text>
  260. </flow-item>
  261. <flow-item slot="refresher" id="refresher" type=2 class="refresh-box">
  262. <text class="tip-text">{{text[state]}}</text>
  263. </flow-item>
  264. <flow-item v-show="isLoadMore" slot="load-more" id="loadmore" type=6 class="load-more-box">
  265. <text>加载更多</text>
  266. </flow-item>
  267. </waterflow>
  268. </view>
  269. <scroll-view style="flex:1" direction="vertical">
  270. <view class="content">
  271. <boolean-data :defaultValue="false" title="设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发"
  272. @change="change_refresher_triggered_boolean"></boolean-data>
  273. <boolean-data :defaultValue="false" title="开启下拉刷新" @change="change_refresher_enabled_boolean"></boolean-data>
  274. <boolean-data :defaultValue="false" title="开启自定义样式" @change="change_refresher_style_boolean"></boolean-data>
  275. <boolean-data :defaultValue="false" title="是否在设置滚动条位置时使用滚动动画,设置false没有滚动动画"
  276. @change="change_scroll_with_animation_boolean"></boolean-data>
  277. <boolean-data :defaultValue="false" title="控制是否出现滚动条" @change="change_show_scrollbar_boolean"></boolean-data>
  278. <boolean-data :defaultValue="true" title="控制是否回弹效果" @change="change_bounces_boolean"></boolean-data>
  279. <boolean-data :defaultValue="true" title="是否显示加载更多" @change="change_load_more_boolean"></boolean-data>
  280. <input-data defaultValue="2" title="设置cross-axis-count,触发 scrolltoupper 事件" type="number"
  281. @confirm="handleChangeCrossAxisCount"></input-data>
  282. <view class="uni-slider uni-list-cell-padding">
  283. <text>拖动设置cross-axis-gap</text>
  284. </view>
  285. <view class="uni-slider uni-list-cell-padding">
  286. <slider :max="20" :min="0" :step="1" :value="cross_axis_gap" :show-value="true"
  287. @change="handleChangeCrossAxisGap" />
  288. </view>
  289. <view class="uni-slider uni-list-cell-padding">
  290. <text>拖动设置main-axis-gap</text>
  291. </view>
  292. <view class="uni-slider uni-list-cell-padding">
  293. <slider :max="20" :min="0" :step="1" :value="main_axis_gap" :show-value="true"
  294. @change="handleChangeMainAxisGap" />
  295. </view>
  296. <input-data defaultValue="50" title="距顶部/左边多远时(单位px),触发 scrolltoupper 事件" type="number"
  297. @confirm="confirm_upper_threshold_input"></input-data>
  298. <input-data defaultValue="50" title="距底部/右边多远时(单位px),触发 scrolltolower 事件" type="number"
  299. @confirm="confirm_lower_threshold_input"></input-data>
  300. <input-data defaultValue="0" title="设置竖向滚动条位置" type="number" @confirm="confirm_scroll_top_input"></input-data>
  301. <input-data defaultValue="#FFF" title="设置下拉刷新区域背景颜色" type="text"
  302. @confirm="confirm_refresher_background_input"></input-data>
  303. <enum-data :items="size_enum" title="通过id位置跳转" @change="item_change_size_enum"></enum-data>
  304. <navigator url="/pages/component/waterflow/waterflow-fit-height">
  305. <button type="primary" class="button">
  306. item高度自适应
  307. </button>
  308. </navigator>
  309. </view>
  310. </scroll-view>
  311. </template>
  312. <style>
  313. .main {
  314. max-height: 250px;
  315. padding: 5px 0;
  316. border-bottom: 1px solid rgba(0, 0, 0, .06);
  317. flex-direction: row;
  318. justify-content: center;
  319. }
  320. .flow-item {
  321. width: 100%;
  322. height: 200px;
  323. border: 1px solid #666;
  324. background-color: #66ccff;
  325. align-items: center;
  326. justify-content: center;
  327. }
  328. .tip-text {
  329. color: #888;
  330. font-size: 12px;
  331. }
  332. .refresh-box {
  333. justify-content: center;
  334. align-items: center;
  335. flex-direction: row;
  336. height: 45px;
  337. width: 100%;
  338. }
  339. .load-more-box {
  340. justify-content: center;
  341. align-items: center;
  342. flex-direction: row;
  343. height: 45px;
  344. width: 100%;
  345. border-style: solid;
  346. }
  347. .button {
  348. margin-top: 15px;
  349. }
  350. </style>