Toast.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { use, isDef } from '../utils';
  2. import { PopupMixin } from '../mixins/popup';
  3. import Icon from '../icon';
  4. import Loading from '../loading';
  5. const [sfc, bem] = use('toast');
  6. const STYLE = ['success', 'fail', 'loading'];
  7. export default sfc({
  8. mixins: [PopupMixin],
  9. props: {
  10. className: null,
  11. forbidClick: Boolean,
  12. message: [String, Number],
  13. type: {
  14. type: String,
  15. default: 'text'
  16. },
  17. loadingType: {
  18. type: String,
  19. default: 'circular'
  20. },
  21. position: {
  22. type: String,
  23. default: 'middle'
  24. },
  25. lockScroll: {
  26. type: Boolean,
  27. default: false
  28. }
  29. },
  30. data() {
  31. return {
  32. clickable: false
  33. };
  34. },
  35. mounted() {
  36. this.toggleClickale();
  37. },
  38. destroyed() {
  39. this.toggleClickale();
  40. },
  41. watch: {
  42. value() {
  43. this.toggleClickale();
  44. },
  45. forbidClick() {
  46. this.toggleClickale();
  47. }
  48. },
  49. methods: {
  50. toggleClickale() {
  51. const clickable = this.value && this.forbidClick;
  52. if (this.clickable !== clickable) {
  53. this.clickable = clickable;
  54. const action = clickable ? 'add' : 'remove';
  55. document.body.classList[action]('van-toast--unclickable');
  56. }
  57. }
  58. },
  59. render(h) {
  60. const { type, message } = this;
  61. const style = STYLE.indexOf(type) !== -1 ? 'default' : type;
  62. const Content = () => {
  63. switch (style) {
  64. case 'text':
  65. return <div>{message}</div>;
  66. case 'html':
  67. return <div domPropsInnerHTML={message} />;
  68. default:
  69. return [
  70. type === 'loading' ? (
  71. <Loading color="white" type={this.loadingType} />
  72. ) : (
  73. <Icon class={bem('icon')} name={type} />
  74. ),
  75. isDef(message) && <div class={bem('text')}>{message}</div>
  76. ];
  77. }
  78. };
  79. return (
  80. <transition name="van-fade">
  81. <div vShow={this.value} class={[bem([style, this.position]), this.className]}>
  82. {Content()}
  83. </div>
  84. </transition>
  85. );
  86. }
  87. });