index.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // Utils
  2. import { createNamespace } from '../utils'; // Components
  3. import Tab from '../tab';
  4. import Tabs from '../tabs';
  5. import Field from '../field';
  6. import Button from '../button';
  7. import Coupon from '../coupon';
  8. var _createNamespace = createNamespace('coupon-list'),
  9. createComponent = _createNamespace[0],
  10. bem = _createNamespace[1],
  11. t = _createNamespace[2];
  12. var EMPTY_IMAGE = 'https://img01.yzcdn.cn/vant/coupon-empty.png';
  13. export default createComponent({
  14. model: {
  15. prop: 'code'
  16. },
  17. props: {
  18. code: String,
  19. closeButtonText: String,
  20. inputPlaceholder: String,
  21. enabledTitle: String,
  22. disabledTitle: String,
  23. exchangeButtonText: String,
  24. exchangeButtonLoading: Boolean,
  25. exchangeButtonDisabled: Boolean,
  26. exchangeMinLength: {
  27. type: Number,
  28. default: 1
  29. },
  30. chosenCoupon: {
  31. type: Number,
  32. default: -1
  33. },
  34. coupons: {
  35. type: Array,
  36. default: function _default() {
  37. return [];
  38. }
  39. },
  40. disabledCoupons: {
  41. type: Array,
  42. default: function _default() {
  43. return [];
  44. }
  45. },
  46. displayedCouponIndex: {
  47. type: Number,
  48. default: -1
  49. },
  50. showExchangeBar: {
  51. type: Boolean,
  52. default: true
  53. },
  54. showCloseButton: {
  55. type: Boolean,
  56. default: true
  57. },
  58. showCount: {
  59. type: Boolean,
  60. default: true
  61. },
  62. currency: {
  63. type: String,
  64. default: '¥'
  65. },
  66. emptyImage: {
  67. type: String,
  68. default: EMPTY_IMAGE
  69. }
  70. },
  71. data: function data() {
  72. return {
  73. tab: 0,
  74. winHeight: window.innerHeight,
  75. currentCode: this.code || ''
  76. };
  77. },
  78. computed: {
  79. buttonDisabled: function buttonDisabled() {
  80. return !this.exchangeButtonLoading && (this.exchangeButtonDisabled || !this.currentCode || this.currentCode.length < this.exchangeMinLength);
  81. },
  82. listStyle: function listStyle() {
  83. return {
  84. height: this.winHeight - (this.showExchangeBar ? 140 : 94) + 'px'
  85. };
  86. }
  87. },
  88. watch: {
  89. code: function code(_code) {
  90. this.currentCode = _code;
  91. },
  92. currentCode: function currentCode(code) {
  93. this.$emit('input', code);
  94. },
  95. displayedCouponIndex: 'scrollToShowCoupon'
  96. },
  97. mounted: function mounted() {
  98. this.scrollToShowCoupon(this.displayedCouponIndex);
  99. },
  100. methods: {
  101. onClickExchangeButton: function onClickExchangeButton() {
  102. this.$emit('exchange', this.currentCode); // auto clear currentCode when not use vModel
  103. if (!this.code) {
  104. this.currentCode = '';
  105. }
  106. },
  107. // scroll to show specific coupon
  108. scrollToShowCoupon: function scrollToShowCoupon(index) {
  109. var _this = this;
  110. if (index === -1) {
  111. return;
  112. }
  113. this.$nextTick(function () {
  114. var _this$$refs = _this.$refs,
  115. card = _this$$refs.card,
  116. list = _this$$refs.list;
  117. /* istanbul ignore next */
  118. if (list && card && card[index]) {
  119. list.scrollTop = card[index].$el.offsetTop - 100;
  120. }
  121. });
  122. },
  123. genEmpty: function genEmpty() {
  124. var h = this.$createElement;
  125. return h("div", {
  126. "class": bem('empty')
  127. }, [h("img", {
  128. "attrs": {
  129. "src": this.emptyImage
  130. }
  131. }), h("p", [t('empty')])]);
  132. },
  133. genExchangeButton: function genExchangeButton() {
  134. var h = this.$createElement;
  135. return h(Button, {
  136. "attrs": {
  137. "plain": true,
  138. "type": "danger",
  139. "text": this.exchangeButtonText || t('exchange'),
  140. "loading": this.exchangeButtonLoading,
  141. "disabled": this.buttonDisabled
  142. },
  143. "class": bem('exchange'),
  144. "on": {
  145. "click": this.onClickExchangeButton
  146. }
  147. });
  148. }
  149. },
  150. render: function render() {
  151. var _this2 = this;
  152. var h = arguments[0];
  153. var coupons = this.coupons,
  154. disabledCoupons = this.disabledCoupons;
  155. var count = this.showCount ? " (" + coupons.length + ")" : '';
  156. var title = (this.enabledTitle || t('enable')) + count;
  157. var disabledCount = this.showCount ? " (" + disabledCoupons.length + ")" : '';
  158. var disabledTitle = (this.disabledTitle || t('disabled')) + disabledCount;
  159. var ExchangeBar = this.showExchangeBar && h("div", {
  160. "class": bem('exchange-bar')
  161. }, [h(Field, {
  162. "attrs": {
  163. "clearable": true,
  164. "border": false,
  165. "placeholder": this.inputPlaceholder || t('placeholder'),
  166. "maxlength": "20"
  167. },
  168. "class": bem('field'),
  169. "model": {
  170. value: _this2.currentCode,
  171. callback: function callback($$v) {
  172. _this2.currentCode = $$v;
  173. }
  174. }
  175. }), this.genExchangeButton()]);
  176. var onChange = function onChange(index) {
  177. return function () {
  178. return _this2.$emit('change', index);
  179. };
  180. };
  181. var CouponTab = h(Tab, {
  182. "attrs": {
  183. "title": title
  184. }
  185. }, [h("div", {
  186. "class": bem('list', {
  187. 'with-bottom': this.showCloseButton
  188. }),
  189. "style": this.listStyle
  190. }, [coupons.map(function (coupon, index) {
  191. return h(Coupon, {
  192. "ref": "card",
  193. "key": coupon.id,
  194. "attrs": {
  195. "coupon": coupon,
  196. "currency": _this2.currency,
  197. "chosen": index === _this2.chosenCoupon
  198. },
  199. "nativeOn": {
  200. "click": onChange(index)
  201. }
  202. });
  203. }), !coupons.length && this.genEmpty(), this.slots('list-footer')])]);
  204. var DisabledCouponTab = h(Tab, {
  205. "attrs": {
  206. "title": disabledTitle
  207. }
  208. }, [h("div", {
  209. "class": bem('list', {
  210. 'with-bottom': this.showCloseButton
  211. }),
  212. "style": this.listStyle
  213. }, [disabledCoupons.map(function (coupon) {
  214. return h(Coupon, {
  215. "attrs": {
  216. "disabled": true,
  217. "coupon": coupon,
  218. "currency": _this2.currency
  219. },
  220. "key": coupon.id
  221. });
  222. }), !disabledCoupons.length && this.genEmpty(), this.slots('disabled-list-footer')])]);
  223. return h("div", {
  224. "class": bem()
  225. }, [ExchangeBar, h(Tabs, {
  226. "class": bem('tab'),
  227. "attrs": {
  228. "border": false
  229. },
  230. "model": {
  231. value: _this2.tab,
  232. callback: function callback($$v) {
  233. _this2.tab = $$v;
  234. }
  235. }
  236. }, [CouponTab, DisabledCouponTab]), h("div", {
  237. "class": bem('bottom')
  238. }, [h(Button, {
  239. "directives": [{
  240. name: "show",
  241. value: this.showCloseButton
  242. }],
  243. "attrs": {
  244. "round": true,
  245. "type": "danger",
  246. "block": true,
  247. "text": this.closeButtonText || t('close')
  248. },
  249. "class": bem('close'),
  250. "on": {
  251. "click": onChange(-1)
  252. }
  253. })])]);
  254. }
  255. });