demo-block.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <template>
  2. <div
  3. class="demo-block"
  4. :class="[blockClass, { 'hover': hovering }]"
  5. @mouseenter="hovering = true"
  6. @mouseleave="hovering = false">
  7. <slot></slot>
  8. <div class="demo-block-control" @click="isExpanded = !isExpanded">
  9. <i :class="iconClass"></i>
  10. <span v-show="hovering">{{ controlText }}</span>
  11. </div>
  12. </div>
  13. </template>
  14. <style>
  15. .demo-block {
  16. border: solid 1px #eaeefb;
  17. border-radius: 4px;
  18. transition: .2s;
  19. &.hover {
  20. box-shadow: 0 6px 18px 0 rgba(232, 237, 250, .5);
  21. }
  22. .source {
  23. padding: 24px;
  24. }
  25. .meta {
  26. background-color: #fbfcfd;
  27. border-top: solid 1px #eaeefb;
  28. clear: both;
  29. overflow: hidden;
  30. height: 0;
  31. transition: height .2s;
  32. }
  33. .description {
  34. padding: 18px 24px;
  35. width: 40%;
  36. box-sizing: border-box;
  37. border-left: solid 1px #eaeefb;
  38. float: right;
  39. font-size: 14px;
  40. line-height: 1.5;
  41. color: #5e6d82;
  42. p {
  43. margin: 0;
  44. }
  45. code {
  46. background-color: #f4faff;
  47. border: solid 1px #eaeefb;
  48. margin: 0 4px;
  49. padding: 0 4px;
  50. font-size: 12px;
  51. }
  52. }
  53. .highlight {
  54. width: 60%;
  55. border-right: solid 1px #eaeefb;
  56. pre {
  57. margin: 0;
  58. }
  59. code.hljs {
  60. padding: 18px 24px;
  61. margin: 0;
  62. line-height: 1.4;
  63. background-color: #fbfcfd;
  64. border: none;
  65. max-height: none;
  66. border-radius: 0;
  67. &::before {
  68. content: none;
  69. }
  70. }
  71. }
  72. .demo-block-control {
  73. border-top: solid 1px #eaeefb;
  74. height: 36px;
  75. box-sizing: border-box;
  76. background-color: #fff;
  77. border-bottom-left-radius: 4px;
  78. border-bottom-right-radius: 4px;
  79. text-align: center;
  80. margin-top: -1px;
  81. color: #d3dce6;
  82. cursor: pointer;
  83. transition: .2s;
  84. i {
  85. font-size: 12px;
  86. line-height: 36px;
  87. }
  88. span {
  89. font-size: 14px;
  90. line-height: 36px;
  91. }
  92. &:hover {
  93. color: #20a0ff;
  94. background-color: rgba(32, 159, 255, .05);
  95. }
  96. }
  97. }
  98. </style>
  99. <script type="text/babel">
  100. export default {
  101. data() {
  102. return {
  103. hovering: false,
  104. isExpanded: false
  105. };
  106. },
  107. computed: {
  108. blockClass() {
  109. return `demo-${ this.$router.currentRoute.path.split('/').pop() }`;
  110. },
  111. iconClass() {
  112. return this.isExpanded ? 'el-icon-caret-top' : 'el-icon-caret-bottom';
  113. },
  114. controlText() {
  115. return this.isExpanded ? '隐藏代码' : '显示代码';
  116. },
  117. codeArea() {
  118. return this.$el.getElementsByClassName('meta')[0];
  119. },
  120. codeAreaHeight() {
  121. if (this.$el.getElementsByClassName('description').length > 0) {
  122. return Math.max(this.$el.getElementsByClassName('description')[0].clientHeight, this.$el.getElementsByClassName('highlight')[0].clientHeight);
  123. }
  124. return this.$el.getElementsByClassName('highlight')[0].clientHeight;
  125. }
  126. },
  127. watch: {
  128. isExpanded(val) {
  129. this.codeArea.style.height = val ? `${ this.codeAreaHeight + 1 }px` : '0';
  130. }
  131. },
  132. mounted() {
  133. this.$nextTick(() => {
  134. let highlight = this.$el.getElementsByClassName('highlight')[0];
  135. if (this.$el.getElementsByClassName('description').length === 0) {
  136. highlight.style.width = '100%';
  137. highlight.borderRight = 'none';
  138. }
  139. });
  140. }
  141. };
  142. </script>