shwaterfall.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <template>
  2. <view class="water-flow-box" >
  3. <view class="water-flow-column" :style="{ 'margin-right': columnGap + 'px' }" v-for="(col, c) in colunmList" :key="c">
  4. <view class="item" :id="col.id" style="width: 100%;">
  5. <view
  6. v-for="(item, index) in col.list"
  7. :key="index"
  8. class="item_content"
  9. :style="{ 'margin-bottom': columnGapTwo + 'px', background: item.background }"
  10. @click="goTodetails(item)"
  11. >
  12. <image :src="item.cover" style="width: 100%;" :mode='"widthFix"'></image>
  13. <view class="waterfall">
  14. <view class="waterfallitem">
  15. {{item.title}}
  16. </view>
  17. <view class="image">
  18. <view class="nickImg">
  19. <image :src="item.head_photo" class="tuxiang" mode=""></image>
  20. <view class="contentname">
  21. {{item.nickname?item.nickname:item.mobile}}
  22. </view>
  23. </view>
  24. <view class="fabulous">
  25. <image class="good" :src="imgUrl+'/delImg/good.png'" mode=""></image>
  26. <view class="contentnumber">
  27. {{item.like_num}}
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. <text class="iconfont video" v-if="item.opus_type==1">
  33. &#xe631;
  34. </text>
  35. </view>
  36. </view>
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. export default {
  42. name: 'grass-water-flow',
  43. props: {
  44. fieldKey: {
  45. //关键比对key
  46. type: String,
  47. default: 'id'
  48. },
  49. idPrefix: {
  50. //前缀
  51. type: String,
  52. default: 'water-flow-'
  53. },
  54. colunmNumber: {
  55. //瀑布流列数
  56. type: Number,
  57. default: 2
  58. },
  59. columnGap: {
  60. //列间隔
  61. type: Number,
  62. default: 10
  63. },
  64. columnGapTwo:{
  65. type:Number,
  66. default:30
  67. },
  68. flowList: {
  69. // 瀑布流数据
  70. type: Array,
  71. required: true,
  72. default: function() {
  73. return [];
  74. }
  75. }
  76. },
  77. data() {
  78. return {
  79. colunmList: [], //列
  80. internalDataList: [], //内部操作数据
  81. refrenshColunmDataList: [], //记录加载的数据
  82. imgUrl: this.$mConfig.staticUrl
  83. };
  84. },
  85. watch: {
  86. colunmNumber: function(v) {
  87. this.internalDataList = Object.assign([], this.refrenshColunmDataList);
  88. this.calculateColumn(v, false);
  89. },
  90. flowList: function(v) {
  91. this.internalDataList = Object.assign(this.internalDataList, v);
  92. if (this.internalDataList.length > 0) {
  93. this.getPushContainer();
  94. }
  95. },
  96. colunmList: {
  97. handler() {
  98. this.$nextTick(function() {
  99. var _this = this; setTimeout(function() { _this.getPushContainer(); }, 200);
  100. });
  101. },
  102. deep: true
  103. }
  104. },
  105. created() {
  106. this.internalDataList = Object.assign([], this.flowList);
  107. this.calculateColumn(this.colunmNumber, true);
  108. },
  109. mounted() {
  110. if (this.internalDataList.length > 0) {
  111. this.colunmList[0].list.push(this.internalDataList[0]);
  112. let shiftObj = this.internalDataList.shift();
  113. this.pushLoadData(shiftObj);
  114. }
  115. },
  116. methods: {
  117. /**
  118. * 计算列
  119. * @param {Object} size 列数
  120. * @param {Object} isCreate 是否初始化创建(created生命周期)
  121. */
  122. calculateColumn: function(size, isCreate) {
  123. this.colunmList = [];
  124. for (let i = 1; i <= size; i++) {
  125. let obj = {};
  126. obj.id = this.idPrefix + i;
  127. obj.list = [];
  128. this.colunmList.push(obj);
  129. }
  130. if (!isCreate) {
  131. if (this.internalDataList.length > 0) {
  132. this.colunmList[0].list.push(this.internalDataList[0]);
  133. let shiftObj = this.internalDataList.shift();
  134. this.pushLoadData(shiftObj);
  135. }
  136. }
  137. },
  138. /**
  139. * 获取节点信息
  140. */
  141. getPushContainer() {
  142. let sortList = [];
  143. const query = uni.createSelectorQuery().in(this);
  144. query
  145. .selectAll('.item')
  146. .boundingClientRect()
  147. .exec(res => {
  148. if (res) {
  149. sortList = res[0];
  150. sortList.sort(function(a, b) {
  151. return a.height - b.height;
  152. });
  153. this.pushShiftData(sortList[0]);
  154. }
  155. });
  156. },
  157. //商品跳详情
  158. goTodetails(item){
  159. console.log(item)
  160. uni.navigateTo({
  161. url:"../recommend/details?id="+item.id
  162. })
  163. // uni.navigateTo({
  164. // url:"../../pages/research/recommend/details?id="+item.id
  165. // })
  166. },
  167. /**
  168. * 处理数据
  169. * @param {Object} pushObj
  170. */
  171. pushShiftData(pushObj) {
  172. if (this.internalDataList.length > 0) {
  173. for (let i = 0; i < this.colunmList.length; i++) {
  174. if (this.colunmList[i].id == pushObj.id) {
  175. this.colunmList[i].list.push(this.internalDataList[0]);
  176. let shiftObj = this.internalDataList.shift();
  177. this.pushLoadData(shiftObj);
  178. }
  179. }
  180. }
  181. },
  182. /**
  183. * 记录加载的数据
  184. * @param {Object} obj
  185. */
  186. pushLoadData(obj) {
  187. if (this.refrenshColunmDataList.length > 0) {
  188. let result = this.refrenshColunmDataList.some(item => {
  189. if (item[this.fieldKey] == obj[this.fieldKey]) {
  190. return true;
  191. }
  192. });
  193. if (!result) {
  194. this.refrenshColunmDataList.push(obj);
  195. }
  196. } else {
  197. this.refrenshColunmDataList.push(obj);
  198. }
  199. },
  200. /**
  201. * 外部刷新数据时,调用此方法,清理掉原有加载数据
  202. */
  203. externalRefrensh() {
  204. this.refrenshColunmDataList = [];
  205. for (let i = 0; i < this.colunmList.length; i++) {
  206. this.colunmList[i].list = [];
  207. }
  208. }
  209. }
  210. };
  211. </script>
  212. <style scoped>
  213. .video {
  214. color: red;
  215. position: absolute;
  216. right: 26rpx;
  217. top: 26rpx;
  218. font-size: 50rpx;
  219. color: #FFFFFF;
  220. }
  221. uni-view.water-flow-column{
  222. background-color: transparent;
  223. margin: transparent;
  224. }
  225. .item_content{
  226. border-radius: 18rpx;
  227. margin-bottom: 42rpx;
  228. overflow: hidden;
  229. background-color: #fff;
  230. position: relative;
  231. }
  232. .black{
  233. height: 30rpx;
  234. background-color: #f5f5f5;
  235. }
  236. .contentnumber{
  237. border-radius: 16rpx;
  238. font-size: 24rpx;
  239. font-family: PingFang SC, PingFang SC-Regular;
  240. font-weight: 400;
  241. color: #999999;
  242. margin-left: 10rpx;
  243. }
  244. .good{
  245. width: 29rpx;
  246. height: 31rpx;
  247. margin-left: 62rpx;
  248. }
  249. .contentname{
  250. width: 90rpx;
  251. flex: 1;
  252. color: #1a1a1a;
  253. font-size: 24rpx;
  254. font-family: PingFang SC, PingFang SC-Regular;
  255. font-weight: 400;
  256. white-space: nowrap;
  257. text-overflow: ellipsis;
  258. overflow: hidden;
  259. margin-left: 13rpx;
  260. }
  261. .tuxiang{
  262. width: 50rpx;
  263. height: 50rpx;
  264. border-radius: 50%;
  265. }
  266. .image{
  267. display: flex;
  268. padding: 9rpx 18rpx 22rpx 22rpx ;
  269. justify-content: space-between;
  270. align-items: center;
  271. }
  272. .image .nickImg,.image .fabulous{
  273. display: flex;
  274. justify-content: space-between;
  275. align-items: center;
  276. }
  277. .waterfallitem{
  278. padding: 15rpx 20rpx;
  279. font-size: 24rpx;
  280. line-height: 40rpx;
  281. color: #333333;
  282. overflow: hidden;
  283. text-overflow: ellipsis;
  284. display: -webkit-box;
  285. -webkit-line-clamp: 2;
  286. -webkit-box-orient: vertical;
  287. word-wrap: break-word;
  288. word-break: break-all;
  289. white-space: normal !important;
  290. }
  291. /* 瀑布流最外层 */
  292. .water-flow-box {
  293. /* margin: 10px; */
  294. background-color: #F5F5F5;
  295. display: flex;
  296. flex-direction: row;
  297. height: auto;
  298. border-radius: 18rpx;
  299. padding: 30rpx 20rpx 42rpx 29rpx;
  300. }
  301. .water-flow-column {
  302. /* margin-right: 10px; */
  303. display: flex;
  304. flex-flow: column wrap;
  305. width: 100%;
  306. border-radius: 18rpx;
  307. /* background-color: white; */
  308. /* margin-bottom: 42rpx; */
  309. }
  310. .water-flow-box .water-flow-column:last-child {
  311. margin-right: 0px !important;
  312. }
  313. .water-flow-column > .item > .item_content {
  314. /* margin-bottom: 10px; */
  315. color: #ffffff;
  316. /* text-align: center; */
  317. width: 100%;
  318. }
  319. </style>