search.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <template>
  2. <section class="catalog section">
  3. <div class="catalog__wrapper section-wrapper">
  4. <div class="catalog__container">
  5. <CatalogMenu />
  6. <main class="catalog__main">
  7. <div class="catalog-main">
  8. <div class="catalog-main__wrapper">
  9. <div class="catalog-main__topic">
  10. <ul class="catalog-main__topic-list">
  11. <li class="catalog-main__topic-item">
  12. <a
  13. class="catalog-main__topic-link"
  14. href="javascript:void(0)"
  15. >Новости</a
  16. >
  17. </li>
  18. <li class="catalog-main__topic-item">
  19. <nuxt-link
  20. :to="{
  21. name: 'news-category',
  22. params: {
  23. category: categoryNewsList.category
  24. ? categoryNewsList.category.alias
  25. : '',
  26. },
  27. }"
  28. class="catalog-main__topic-link"
  29. href="javascript:void(0)"
  30. >
  31. Поиск</nuxt-link
  32. >
  33. </li>
  34. </ul>
  35. </div>
  36. <div class="catalog-main__header">
  37. <h1>Поиск</h1>
  38. </div>
  39. <div class="catalog-main__list">
  40. <div class="catalog-list" id="catalogList">
  41. <BaseInput
  42. class="search__input"
  43. v-model="string"
  44. @input="searchTrigger"
  45. ></BaseInput>
  46. <li class="catalog-list__item" v-for="searchItem in searchList" :key="searchItem.id">
  47. <div class="catalog-item">
  48. <nuxt-link
  49. :to="{
  50. name: 'news-category-alias',
  51. params: {
  52. category: searchItem.category.alias,
  53. alias: searchItem.alias,
  54. },
  55. }"
  56. class="catalog-item__link"
  57. >
  58. <main class="catalog-item__main">
  59. <div class="catalog-item__main-top">
  60. <div class="catalog-item__main-title" v-html="searchItem.title"></div>
  61. </div>
  62. <div class="catalog-item__main-bottom">
  63. <div class="catalog-item__main-info">
  64. <div class="catalog-item__main-info-element">
  65. {{ searchItem.start_activity ? convertDate(searchItem.start_activity) : ''}}
  66. </div>
  67. </div>
  68. </div>
  69. </main></nuxt-link>
  70. </div>
  71. </li>
  72. </div>
  73. </div>
  74. <Pagination
  75. v-if="searchList.length"
  76. v-model="curPage"
  77. :length="paginationLength"
  78. @input="nextPage"
  79. :visible="10"
  80. ></Pagination>
  81. </div>
  82. </div>
  83. </main>
  84. </div>
  85. </div>
  86. </section>
  87. </template>
  88. <script>
  89. import { mapGetters } from "vuex";
  90. let delayTimer;
  91. export default {
  92. props: {
  93. query: {
  94. type: String
  95. }
  96. },
  97. data() {
  98. return {
  99. string: "",
  100. searchList: [],
  101. curPage: 1,
  102. totalPages: null
  103. };
  104. },
  105. computed: {
  106. ...mapGetters({
  107. categoryNewsList: "modules/news/categoryNewsList",
  108. }),
  109. paginationLength() {
  110. if(this.curPage < 10) return 10;
  111. return this.curPage + 5;
  112. }
  113. },
  114. props: {
  115. category: {
  116. type: Object,
  117. },
  118. },
  119. mounted() {
  120. this.string = this.$route.params.query
  121. this.searchTrigger()
  122. },
  123. methods: {
  124. nextPage() {
  125. this.searchTrigger();
  126. this.scrollTop();
  127. },
  128. scrollTop() {
  129. const element = document.getElementById("catalogList");
  130. const top = element.offsetTop;
  131. window.scrollTo(0, top - 230);
  132. },
  133. searchTrigger() {
  134. clearTimeout(delayTimer);
  135. delayTimer = setTimeout(() => {
  136. this.$axios
  137. .post("search", {
  138. request: this.string,
  139. page: this.curPage
  140. })
  141. .then((res) => {
  142. if (res.status == 200) {
  143. const { items, total_pages } = res.data.data;
  144. this.searchList = items;
  145. this.totalPages = total_pages;
  146. }
  147. });
  148. }, 600);
  149. },
  150. convertDate(dateTampstamp) {
  151. const date = new Date(dateTampstamp * 1000);
  152. const dateString =
  153. date.toLocaleString("ru", {
  154. day: 'numeric',
  155. month: 'long'
  156. }) +
  157. " " +
  158. date.getFullYear()
  159. + ", " +
  160. ("0" + date.getHours()).slice(-2) +
  161. ":" +
  162. ("0" + date.getMinutes()).slice(-2);
  163. return dateString;
  164. },
  165. },
  166. async fetch({ store, route }) {
  167. await store.dispatch("modules/news/setCategoriesList");
  168. },
  169. async asyncData({ store }) {
  170. await store.dispatch("modules/ads/getAds");
  171. },
  172. head() {
  173. return {
  174. title: 'Поиск по сайту — Амик.ру'
  175. }
  176. }
  177. };
  178. </script>
  179. <style lang="less" scoped>
  180. .catalog-list{
  181. list-style: none;
  182. &__item{
  183. }
  184. }
  185. .search {
  186. &__input {
  187. width: 100%;
  188. max-width: 100%;
  189. height: 41px;
  190. display: flex;
  191. align-items: center;
  192. margin-bottom: 20px;
  193. input {
  194. width: 100%;
  195. outline: none;
  196. height: 100%;
  197. }
  198. }
  199. }
  200. </style>