NEXT craftinamerica.org. Base setup for headless wordpress https://www.craftinamerica.org
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

list.vue 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template lang="pug">
  2. .page--list.f-row.between
  3. article.f-grow
  4. header.f-row.center.t-up
  5. h1 {{ type }} list
  6. span(v-if="sortBy")
  7. h1 &nbsp;sorted by {{ sortBy.replace('-', ' ') }}
  8. .posts(:class="{ 'is-grid': grid }")
  9. section(v-for="post in posts" :key="post.slug").shadow.post
  10. router-link(:to="`/${type}/${post.slug}`")
  11. p {{post.featured}}
  12. ul.f-row
  13. img(v-if="post.featured" :src="post.featured" alt="post thumbnail")
  14. img(v-else-if="post.hero && JSON.parse(post.hero).url" :src="getThumbnailFromYt(JSON.parse(post.hero).url)" alt="post thumbnail from YouTube")
  15. p(v-else-if="post.hero") ERROR: {{ post.hero }}
  16. p(v-else) ERROR: no thumbnail
  17. li.f-col.between
  18. h2.t-up {{ post.title }}
  19. h4 {{ post.date }}
  20. p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras eu elit in ex pharetra volutpat ac at magna. Duis libero est, imperdiet non sollicitudin vel, eleifend at ante...
  21. //- posts not grid
  22. footer
  23. p {{ `${type} count: ${Object.values(posts).length}` }}
  24. p {{ `show sidebar: ${sidebar}` }}
  25. sidebar(v-if="sidebar" :type="`${type}`")
  26. .shadow
  27. h1.t-up slots stuff
  28. div
  29. p more body whatever
  30. p another line of stuff
  31. </template>
  32. <script>
  33. import sidebar from '@/components/sidebars/sidebar'
  34. import { postTypeGetters, scrollTop } from './mixin-post-types'
  35. import { convertTitleCase, typeFromRoute, sortTypes, ytThumbnail } from '@/utils/helpers'
  36. export default {
  37. components: { sidebar },
  38. props: {
  39. sidebar: { type: Boolean },
  40. grid: { type: Boolean },
  41. sortBy: { type: String }
  42. },
  43. mixins: [postTypeGetters, scrollTop],
  44. computed: {
  45. type() { // Checks for type and fixes Episodes route edge case
  46. return typeFromRoute(this.$route)
  47. },
  48. dispatchName() {
  49. let type = convertTitleCase(this.type)
  50. return this.sortBy ? `getAll${type.split('/')[0]}` : `getAll${type}`
  51. },
  52. posts() {
  53. let type = convertTitleCase(this.type)
  54. if(!type) return
  55. /**
  56. * We override the API to sort by date
  57. * because items are returned by ID so
  58. * we need to resort it by date
  59. */
  60. let unsortedOfType = Object.values(this[`all${type}`])
  61. let sortedByRecent = unsortedOfType.sort((postA, postB) => new Date(postB.date) - new Date(postA.date))
  62. /**
  63. * Sorting of this[`all${type}`] is also controlled by API
  64. * so if a sortBy is specified we return it sorted or
  65. * we fail over to sorted by date
  66. */
  67. return this.sortBy ? this[`all${type}`] : sortedByRecent
  68. },
  69. },
  70. methods: {
  71. getThumbnailFromYt(url) {
  72. return ytThumbnail(url, 'medium')
  73. },
  74. setHeroAndGetPosts() {
  75. let type = convertTitleCase(this.type)
  76. // Sorting
  77. let sort = this.sortBy ? this.sortBy : this.$route.path.split('/').pop()
  78. if(Object.values(sortTypes).includes(sort)) {
  79. console.log('trying to sort by:', sort)
  80. console.log(`sortTypes includes ${sort}:`, Object.values(sortTypes).includes(sort))
  81. }
  82. // Is this a sort type?
  83. if(this.type !== sort || !Object.values(sortTypes).includes(sort)) sort = null
  84. // Don't dispatch if there's no type
  85. if(this.type) {
  86. this.$store.dispatch(this.dispatchName, sort)
  87. }
  88. if(this.$store.state.hero.url !== type) this.$store.commit('SET_HERO', type)
  89. }
  90. },
  91. watch: {
  92. $route(to, from){
  93. let type = convertTitleCase(this.type)
  94. let sort = this.sortBy ? this.sortBy : to.path.split('/').pop()
  95. if(!this[`all${type}Loaded`] || sort) this.setHeroAndGetPosts()
  96. }
  97. },
  98. created() {
  99. let type = convertTitleCase(this.type)
  100. // console.log('already loaded ?:', this[`all${type}Loaded`])
  101. if(!this[`all${type}Loaded`]) this.setHeroAndGetPosts()
  102. }
  103. }
  104. </script>
  105. <style lang="postcss">
  106. .page--list
  107. article
  108. /* posts not grid list */
  109. ul
  110. img
  111. max-width: 50%
  112. li
  113. .is-grid
  114. display: flex
  115. flex-direction: row
  116. flex-wrap: wrap
  117. section
  118. width: 33%
  119. ul
  120. flex-wrap: wrap
  121. list-style: none
  122. img
  123. max-width: 100%
  124. </style>