метод по щелчку на кнопке, которая направляет на другой компонент - PullRequest
0 голосов
/ 08 мая 2020

У меня есть компонент главной страницы приложения с панелью поиска. Возвращаемые результаты поиска представлены в виде карточек. И я хочу настроить кнопку «Щелкните здесь, чтобы просмотреть более подробную информацию», которая будет размещена на каждой карточке. И это будет ссылка на страницу подробностей для одного нажатого результата. Как связать эти компоненты с Vue и можно ли передать идентификатор? Я надеюсь, что при нажатии кнопки компонент отображается на той же странице, а не на новой вкладке.

Спасибо!

Приложение. vue

 <template>
  <div id="app">
    <Header/>
    <SearchForm v-on:search="search"/>
    <SearchResults
      v-if="results.length > 0"
      v-bind:results="results"
      v-bind:reformattedSearchString="reformattedSearchString"/>

    <Pagination
      v-if="results.length > 0"
      v-bind:prevPageToken="api.prevPageToken"
      v-bind:next_page="api.scrollId"
      v-on:prev-page="prevPage"
      v-on:next-page="nextPage"
    />
  </div>
</template>

<script>
import Header from './components/layout/Header';
import SearchForm from './components/SearchForm';
import SearchResults from './components/SearchResults';
import Pagination from './components/Pagination';
import Details from './components/Details'
import axios from 'axios';

export default {
  name: 'app',
  components: {
    Header,
    SearchForm,
    SearchResults,
    Pagination,
    Details
  },

   data() {
    return {
      results: [],
      reformattedSearchString: '',
      api: {
        baseUrl: 'https://test.org/api/v1/articles?',
        max: 25,
        q: '',
        prevPageToken: '',
        scrollId: ''
      }
    };
  },


   methods: {
    search(searchParams) {
      this.reformattedSearchString = searchParams.join(' ');
      this.api.q = searchParams.join('+');
      const { baseUrl, q, max} = this.api;
      const apiUrl = `${baseUrl}&term=${q}&title_like=${q}&recent&max=${max}&full_results`;
      this.getData(apiUrl);

    },

    prevPage() {
      const { baseUrl, q, max, prevPageToken } = this.api;
      const apiUrl = `${baseUrl}&term=${q}&title_like=${q}&max=${max}&pageToken=${prevPageToken}`;
      this.getData(apiUrl);
    },

    nextPage() {
      const { baseUrl, q, max,scrollId } = this.api;
      const apiUrl = `${baseUrl}&term=${q}&title_like=${q}&max=${max}&recent&full_results&scroll_id=${scrollId}`;
      this.getData(apiUrl);
    },

    getData(apiUrl) {
      axios
        .get(apiUrl)

        .then(res => {
          this.results = res.data.success.data;
          this.api.prevPageToken = res.data.success.data.prevPageToken;
          this.api.next_page = res.data.scrollId;

        })
        .catch(error => console.log(error))
    }
  }
};
</script>

Результаты поиска. vue

<template>
  <div class="container mb-3">
    <div class="d-flex mb-3">
      <div class="mr-auto">
        <h3>Search Results for "{{ reformattedSearchString }}"</h3>
      </div>
      <div class="btn-group ml-auto" role="group">
        <button
          @click="changeDisplayMode('grid')"
          type="button"
          class="btn btn-outline-secondary"
          v-bind:class="{ active: displayMode === 'grid' }"
        >
          <i class="fas fa-th"></i>
        </button>
        <button
          @click="changeDisplayMode('list')"
          type="button"
          class="btn btn-outline-secondary"
          v-bind:class="{ active: displayMode === 'list' }"
        >
          <i class="fas fa-list"></i>
        </button>
      </div>
    </div>

    <div class="card-columns" v-if="displayMode === 'grid'">
      <div class="card" v-bind:key="result._gddid" v-for="result in results">
        <ArticleGridItem v-bind:result="result"/>
      </div>
    </div>
    <div v-else>
      <div class="card mb-2" v-bind:key="result._gddid" v-for="result in results">
        <ArticleListItem v-bind:result="result"/>
      </div>
    </div>
  </div>
</template>

<script>
import ArticleListItem from './ArticleListItem';
import ArticleGridItem from './ArticleGridItem';
import Details from './Details';

export default {
  name: 'SearchResults',
  components: {
    ArticleListItem,
    ArticleGridItem,
    Details,
  },
  data() {
    return {
      title: 'Search Results',
      displayMode: 'grid'
    };
  },
  methods: {
    changeDisplayMode(displayMode) {
      this.displayMode = displayMode;
    }
  },
  props: ['results', 'reformattedSearchString']
};
</script>

ArticleListItem. vue

<template>
  <div>
    <div class="card-body"> 
    <h6 class="card-text">{{ result.title }}</h6>

      <p
        class="card-subtitle mb-2 text-muted"
      >{{ result.publisher }} | {{ result.journal }} | {{ result.year }}</p>
      <a :href="'https://test.org/api/articles?docid=' + result._gddid" target="_blank">
        <i class="fa fa-download"  alt="Download"> </i>
      </a>
     <router-link>
    <v-btn dark to="{name:'Details', params: {id: article._gddid}}">
    Click here for more Details
    </v-btn>
  </router-link>
  <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ArticleListItem',
  props: ['result'],   
}

</script>

индекс. js

  import Vue from 'vue';
import Router from 'vue-router';
import Details from '@/components/Details';


Vue.use(Router)

export default new Router({
  routes: [
    {
     path: '/Details/:id',
     name: 'Details',
     component: Details
   }
 ]
});

основной. js

import Vue from 'vue'
import App from './App.vue'
import router from './router/index.js'
import moment from 'moment'


Vue.config.productionTip = false

Vue.filter('formatDate', function (value) {
  if (!value) return ''
  return moment(value.toString()).format('MM/DD/YYYY hh:mm')
})

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

Ответы [ 2 ]

1 голос
/ 09 мая 2020

используйте тег <router-link>, чтобы он работал

0 голосов
/ 09 мая 2020

При использовании маршрутизатора Vue вместо тегов <a> вы можете использовать теги <router-link>.

Вот базовый пример c, аналогичный в документации Vue Router для Dynami c сопоставление маршрутов .

Если у вас есть это ...

const router = new VueRouter({
  routes: [
    { path: '/Details/:id', component: DetailsPage, name: 'Details' }
  ]
})

Вы можете указать ссылки на маршрутизатор, скажем, в вашем файле ArticleListItem.vue, например :

<v-btn dark to="{name:'Details', params: {id: article.id}}">
  Click here for more Details
</v-btn>

Вы не можете просто go перейти на общую c страницу с подробностями. Должна быть некая динамическая c часть маршрута (которую я назвал id в моем примере), чтобы указать, на какую страницу статьи нужно go перейти.

Изменить

Дополнительная проблема в настройке вашего маршрутизатора:

Из Vue документации маршрутизатора :

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

... должно быть в вашем файле main. js. Объявление Vue.use в вашем файле index. js ничего не делает. Просто для краткости. Сделайте его одним файлом:

WhateverYourOneTrueFileIsGoingToBeCalled. js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router';
import Details from '@/components/Details';
import moment from 'moment'


Vue.config.productionTip = false

Vue.filter('formatDate', function (value) {
  if (!value) return ''
  return moment(value.toString()).format('MM/DD/YYYY hh:mm')
})

Vue.use(VueRouter)

router = new VueRouter({
  routes: [
    {
     path: '/Details/:id',
     name: 'Details',
     component: Details
   }
 ]
})

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')
...