book.vue 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <template>
  2. <dl :class="['x-book',{'x-book--multi': multi}]"
  3. :style="multi ? '' : `width: ${coverStyle.width}`"
  4. @click="click(book)">
  5. <dt class="x-book__coverbox">
  6. <img v-if="book.cover"
  7. class="x-book__cover"
  8. :style="coverStyle"
  9. :key="book.cover"
  10. v-lazy="book.cover"
  11. lazy="loading">
  12. <img v-else
  13. :style="coverStyle"
  14. class="x-book__cover"
  15. src="https://zhuishuyun.oss-cn-hangzhou.aliyuncs.com/book/cover/loading.png">
  16. <slot name="shadow"></slot>
  17. </dt>
  18. <dd v-if="multi"
  19. class="x-book__text--multi"
  20. :style="textStyle">
  21. <slot></slot>
  22. </dd>
  23. <dd v-else
  24. class="x-book__text--normal">{{book.name}}</dd>
  25. </dl>
  26. </template>
  27. <script>
  28. export default {
  29. props: {
  30. book: {
  31. // {name,cover}
  32. required: true,
  33. type: Object
  34. },
  35. multi: {
  36. type: Boolean,
  37. default: false
  38. },
  39. width: {
  40. type: String,
  41. default: "2rem"
  42. },
  43. prevent: {
  44. type: Boolean,
  45. default: false
  46. }
  47. },
  48. name: "XBook",
  49. data() {
  50. const size = this.width.match(/[\d-.]+/g);
  51. const unit = this.width.match(/[^\d-.]+/g);
  52. return {
  53. coverStyle: {
  54. width: size + unit,
  55. height: (size / 3) * 4 + unit
  56. },
  57. textStyle: {
  58. width: `calc(100% - ${size + unit})`,
  59. height: (size / 3) * 4 + unit
  60. }
  61. };
  62. },
  63. methods: {
  64. click(book) {
  65. if (
  66. !this.prevent &&
  67. this.customClick &&
  68. typeof this.customClick === "function"
  69. )
  70. this.customClick(book);
  71. this.$emit("click", book);
  72. }
  73. },
  74. install(Vue, options) {
  75. //可以传入click事件
  76. if (options && typeof options.click === "function") {
  77. this.methods.customClick = options.click;
  78. }
  79. Vue.component(this.name, this);
  80. }
  81. };
  82. </script>