Vue相似组件合并咨询:如何整合访问/心愿地点组件?
应该合并组件吗?绝对应该!
你的两个组件除了数据源请求和变量名称外,结构、逻辑、样式完全一致,合并是最优选择——这能大幅减少重复代码,提升维护效率,以后要修改展示逻辑只需要改一处就好。
如何判断发起哪个请求?
你提到的依据URL(路由)判断是完全可行的,这里给你两种更优雅的实现方式:
1. 利用路由元信息(Meta)
在路由配置里给两个路由添加meta字段标记类型,这种方式更清晰,后续修改路由路径也不会影响组件逻辑:
// 路由配置示例 const routes = [ { path: '/Admin/visited/:username', component: UserPlaceList, meta: { placeType: 'visited' } }, { path: '/Admin/wishlist/:username', component: UserPlaceList, meta: { placeType: 'wishlist' } } ]
然后在组件内直接读取元信息来区分请求:
// 组件内mounted钩子 mounted() { const placeType = this.$route.meta.placeType; const apiUrl = placeType === 'visited' ? '/getVisited/' : '/getWishlist/'; axios.get(apiUrl + this.username) .then(response => { this.placeList = placeType === 'visited' ? response.data.visitedPlaces : response.data.wishlistedPlaces; }) .catch(error => console.log(error)); }
2. 直接解析路由路径
如果不想修改路由配置,也可以直接从$route.path中提取关键词:
mounted() { const isVisited = this.$route.path.includes('visited'); const apiUrl = isVisited ? '/getVisited/' : '/getWishlist/'; axios.get(apiUrl + this.username) .then(response => { this.placeList = isVisited ? response.data.visitedPlaces : response.data.wishlistedPlaces; }) .catch(error => console.log(error)); }
组件命名建议
可以选择通用且贴合业务的名称,比如:
UserPlaceList.vue:直接点明是用户的地点列表,覆盖两种场景PlaceCollection.vue:强调这是一组地点集合,语义更宽泛UserSightList.vue:和你原组件里的sight术语保持一致,更贴合现有业务
数据属性命名
把原来的wishlist和visited统一为通用名称,推荐:
placeList:简洁通用,符合数据的本质(一组地点)sightList:和模板里的sight术语对应,语义更连贯
合并后的完整组件示例
<template> <!-- 统一class,因为CSS规则完全一致 --> <div class='user-place-list'> <div @click='selectSight(index)' class='user-place-item' v-if='placeList != null' v-for='(place, index) in placeList' > <img class='place-photo' :src="'https://maps.googleapis.com/maps/api/place/photo?maxwidth=300&photoreference=' + place.result.photos[0].photo_reference + '&key='"> <div> <p class='place-name'>{{ place.result.name }}</p> </div> </div> </div> </template> <script> import axios from 'axios' export default { data(){ return { placeList: null, // 统一数据属性 username: this.$route.params.username, } }, methods: { selectSight(index) { const placeId = this.placeList[index].result.place_id; this.$router.push('/' + this.username + '/' + placeId) } }, mounted() { const placeType = this.$route.meta.placeType; const apiUrl = placeType === 'visited' ? '/getVisited/' : '/getWishlist/'; axios.get(apiUrl + this.username) .then(response => { this.placeList = placeType === 'visited' ? response.data.visitedPlaces : response.data.wishlistedPlaces; }) .catch((error) => console.log(error)); } } </script> <style scoped> .user-place-list { /* 原wishlisted-sights-list和visited-sights-list的样式 */ } .user-place-item { /* 原wishlisted-sight和visited-sight的样式 */ } .place-photo { /* 原wishlisted-sight-photos和visited-sight-photos的样式 */ } .place-name { /* 原wishlisted-sights-name和visited-sights-name的样式 */ } </style>
内容的提问来源于stack exchange,提问作者Onyx
相关产品推荐
相关产品推荐

