contacts.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <template>
  2. <view class="list-wrapper">
  3. <view class="list">
  4. <view class="list-item"
  5. v-for="item in items"
  6. :hover-start-time="20"
  7. :hover-stay-time="70"
  8. :key="item.id"
  9. hover-class="commonly-hover"
  10. @tap="handleClick(item)"
  11. >
  12. <image class="avatar"
  13. mode="aspectFill"
  14. :src="image_cache(item.avatar)"
  15. @tap.stop="handleAvatar(item)"
  16. />
  17. <view class="info">
  18. <view class="nickname">{{item.nickname || item.name}}</view>
  19. </view>
  20. <checkbox
  21. v-if="selectMode"
  22. :checked="selectedMap[item.id]"
  23. :disabled="disabledMap[item.id]"
  24. @tap.stop="handleClick(item)"
  25. />
  26. </view>
  27. </view>
  28. </view>
  29. </template>
  30. <script>
  31. const hasOwn = Object.prototype.hasOwnProperty;
  32. import config from '../config.js'
  33. import action from '../library/action.js'
  34. export default {
  35. props: {
  36. items: {
  37. required: true,
  38. },
  39. selectMode: {
  40. type: Boolean,
  41. default: false
  42. },
  43. checkedMap: {
  44. type: Object,
  45. default: () => ({})
  46. },
  47. disabledMap: {
  48. type: Object,
  49. default: () => ({})
  50. },
  51. selectedMap: {
  52. type:[Array,Object],
  53. default: () => ({})
  54. }
  55. },
  56. data() {
  57. return {
  58. }
  59. },
  60. watch: {
  61. checkedMap() {
  62. this.lookCheckedMap();
  63. },
  64. disabledMap() {
  65. this.lookCheckedMap();
  66. }
  67. },
  68. methods: {
  69. img_path(path){
  70. console.log(path);
  71. },
  72. photo(path){
  73. // if(path.indexOf('http')<=-1) path=config.imgUri+path;
  74. // action.image_cache(path,this.img_path)
  75. return this.image_cache(path);
  76. },
  77. inDisabledMap(id) {
  78. return hasOwn.call(this.disabledMap, id);
  79. },
  80. inCheckedMap(id) {
  81. return hasOwn.call(this.checkedMap, id);
  82. },
  83. inSelected(id) {
  84. return typeof this.selectedMap[id] === 'boolean';
  85. },
  86. setToSelected(id) {
  87. const selected = Boolean(this.selectedMap[id]);
  88. this.$set(this.selectedMap, id, !selected);
  89. },
  90. handleAvatar(item) {
  91. if (this.selectMode) {
  92. this.handleClick(item);
  93. } else {
  94. this.$emit('avatar', item);
  95. }
  96. },
  97. handleClick(item) {
  98. if (!this.inDisabledMap(item.id)) {
  99. if (this.selectMode) {
  100. this.setToSelected(item.id);
  101. item.selected = this.selectedMap[item.id];
  102. this.$emit('select', item);
  103. } else {
  104. this.$emit('click', item);
  105. }
  106. }
  107. },
  108. lookCheckedMap() {
  109. Object.keys(this.checkedMap).forEach(id => {
  110. // if (!this.inDisabledMap(id)) {
  111. this.setToSelected(id);
  112. // }
  113. })
  114. }
  115. },
  116. created() {
  117. },
  118. onLoad() {
  119. this.lookCheckedMap();
  120. }
  121. }
  122. </script>
  123. <style lang="scss" scoped>
  124. $list-avatar-width: 88upx;
  125. .list-wrapper {
  126. position:relative;
  127. box-sizing: border-box;
  128. padding: $uni-spacing-col-base $uni-spacing-row-base;
  129. }
  130. .list {
  131. width: 100%;
  132. box-sizing: border-box;
  133. .list-title,
  134. .list-item {
  135. width: 100%;
  136. font-size: 32upx;
  137. padding: 0 20upx;
  138. box-sizing: border-box;
  139. }
  140. .list-title {
  141. background-color: #eee;
  142. height: 92upx;
  143. line-height: 92upx;
  144. font-weight: bold;
  145. }
  146. .list-item {
  147. display: flex;
  148. flex-direction: row;
  149. align-items: center;
  150. background-color: #fff;
  151. position: relative;
  152. padding: $uni-spacing-col-base $uni-spacing-row-base;
  153. .avatar {
  154. width: $list-avatar-width;
  155. height: $list-avatar-width;
  156. margin-right: $uni-spacing-row-base;
  157. border-radius: $uni-border-radius-base;
  158. overflow: hidden;
  159. display: flex;
  160. flex-flow: wrap;
  161. justify-content: center;
  162. background-color: #eee;
  163. align-items: center;
  164. flex-shrink: 0;
  165. &:not(image) {
  166. padding: 1upx;
  167. }
  168. view,
  169. image {
  170. width: ($list-avatar-width - 2upx * 4) / 3;
  171. height: ($list-avatar-width - 2upx * 4) / 3;
  172. margin: 1upx;
  173. }
  174. }
  175. &:last-child {
  176. border-bottom-left-radius: $uni-border-radius-base;
  177. border-bottom-right-radius: $uni-border-radius-base;
  178. }
  179. &:not(:last-child)::before {
  180. display: block;
  181. content: '';
  182. bottom: 0;
  183. left: $uni-spacing-row-base * 2 + $list-avatar-width;
  184. right: $uni-spacing-row-base;
  185. height: 1upx;
  186. position: absolute;
  187. background-color: #E6E6E6;
  188. transform: scaleY(0.5);
  189. }
  190. &.commonly-hover {
  191. background-color: #eee;
  192. }
  193. text {
  194. flex: 1;
  195. }
  196. }
  197. .nickname,
  198. .description {
  199. width: 750upx - $uni-spacing-row-base * 6 - $list-avatar-width - 44upx;
  200. text-overflow: ellipsis;
  201. white-space: nowrap;
  202. overflow: hidden;
  203. }
  204. .description {
  205. font-size: 28upx;
  206. color: #999;
  207. }
  208. .list-title + .list-item {
  209. border-top-left-radius: $uni-border-radius-base;
  210. border-top-right-radius: $uni-border-radius-base;
  211. }
  212. }
  213. </style>