Vue2点击router-link按首字母展示API数据,如何实现无需页面刷新?
问题解决:路由参数变化时无需刷新页面更新数据
问题原因
点击字母router-link切换路由参数时,由于组件实例被复用,created钩子仅在组件首次创建时执行,不会随路由参数变化重新触发数据请求,导致必须刷新页面才能加载新数据。
解决方案
- 封装数据请求方法:把获取啤酒数据的逻辑抽成独立方法,方便在组件创建和路由参数变化时复用。
- 监听路由参数变化:通过
watch监听$route.params.letter的变化,参数更新时自动调用请求方法。 - 响应式获取当前字母:用计算属性实时获取路由中的字母参数,保证数据响应式更新。
修改后的完整代码
<template> <div> <div class="d-flex px-2 pt-5 flex-wrap justify-center"> <div class="text-style mb-5"> <p class="text-center text-body-1 font-weight-bold">Choose letter...</p> <v-divider></v-divider> <router-link class="mx-1 router-text text-h4 font-weight-bold amber--text text-darken-5" :to="{ name: 'byLetter', params: { letter } }" v-for="letter in letters" :key="letter" > {{ letter }} </router-link> </div> </div> <v-row> <v-col v-for="beer in filteredBeers" :key="beer.id" cols="6"> <v-card outlined class="d-flex flex-column justify-space-around"> <v-card-item> <h2 class="ml-3 text-h5 font-weight-bold mt-3 mb-3"> {{ beer.name }} <v-avatar> <v-img :src="beer.image_url" alt="John"></v-img> </v-avatar> </h2> <v-divider></v-divider> <v-card-text class="mb-0 d-flex flex-row align-center justify-space-around"> <p class="text-h6 mb-0"><v-icon color="orange">mdi-percent-outline</v-icon> Volume: {{ beer.abv }}%</p> <p class="text-h6 mb-0"> <v-icon color="orange">mdi-silverware-fork-knife</v-icon> Food pairing: {{ beer.food_pairing[0] }} </p> </v-card-text> <v-divider></v-divider> <v-card-actions class="d-flex justify-center"> <v-hover v-slot="{ hover }"> <router-link class="router" :to="{ name: 'details', params: beer }"> <v-btn style="transition: 0.3s" :style="{ 'background-color': hover ? 'orange' : 'white' }" outlined> <v-icon>mdi-magnify</v-icon> Szczegóły </v-btn> </router-link> </v-hover> </v-card-actions> </v-card-item> </v-card> </v-col> </v-row> </div> </template> <script> import axiosClient from '@/axiosClient' export default { data() { const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('') return { beers: [], letters, } }, computed: { letter() { return this.$route.params.letter }, filteredBeers: function () { return this.beers.filter(beer => { return beer.name.startsWith(this.letter) }) }, }, created() { this.fetchBeers() }, watch: { '$route.params.letter'(newLetter) { this.fetchBeers(newLetter) } }, methods: { async fetchBeers(letter = this.letter) { const response = await axiosClient.get(`beers?beer_name=${letter}`) this.beers = response.data } } } </script>
关键修改说明
- 移除
data中的letter,改用计算属性实时获取路由参数,确保参数变化时视图自动更新。 - 新增
fetchBeers方法封装请求逻辑,支持自定义传入字母,默认使用当前路由参数。 - 添加
watch监听路由参数变化,参数更新时自动重新请求对应数据。 - 用
async/await简化异步代码,提升可读性。
内容的提问来源于stack exchange,提问作者Feli
相关产品推荐
相关产品推荐

