So I’m new to Vue and have been learning for about the past week or two. I can’t seem to figure out how to get the specific physician data on the PhysicianProfile.vue
component. I have my mock data in the store and I’m passing that information to PhysicianListing.vue
, which is my main page to see the listing (loops through the data).
In PhysicianFullListing.vue
I’m passing a physician prop that is expecting an Object and is building out the listing cards on PhysicianListing.vue
. I have routes setup to build our SEO Friendly URLs (/physician/profile/firstName-lastName-designation
).
My question is how do only get the data back for the physician that I’m currently viewing on the profile page? It seems so simple but I’m completely missing what I need to do. Any help on this would be appreciated. Thanks.
store/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
physicians: [
{
id: 1,
name: 'Emily Been, MD',
firstName: 'Emily',
lastName: 'Been',
designation: 'MD',
specialty: 'Internal Medicine',
locationDistance: 14,
photo: 'https://placehold.it/75x75',
location: {
title: 'TriStar Centennial',
address: '2300 Patterson St',
city: 'Nashville',
state: 'TN',
zipCode: 37203
}
}, {
id: 2,
name: 'Lisa Gomez, MD',
firstName: 'Lisa',
lastName: 'Gomez',
designation: 'MD',
specialty: 'Internal Medicine',
locationDistance: 14,
photo: 'https://placehold.it/75x75',
location: {
title: 'TriStar Centennial',
address: '2300 Patterson St',
city: 'Nashville',
state: 'TN',
zipCode: 37203
}
}, {
id: 3,
name: 'Raymond Acevedo, MD',
firstName: 'Raymond',
lastName: 'Acevedo',
designation: 'MD',
specialty: 'Internal Medicine',
locationDistance: 14,
photo: 'https://placehold.it/75x75',
location: {
title: 'TriStar Centennial',
address: '2300 Patterson St',
city: 'Nashville',
state: 'TN',
zipCode: 37203
}
}, {
id: 4,
name: 'Christi Mancuso, MD',
firstName: 'Christi',
lastName: 'Mancuso',
designation: 'MD',
specialty: 'Internal Medicine',
locationDistance: 14,
photo: 'https://placehold.it/75x75',
location: {
title: 'TriStar Centennial',
address: '2300 Patterson St',
city: 'Nashville',
state: 'TN',
zipCode: 37203
}
}, {
id: 5,
name: 'Martin Mannings, MD',
firstName: 'Martin',
lastName: 'Mannings',
designation: 'MD',
specialty: 'Internal Medicine',
locationDistance: 14,
photo: 'https://placehold.it/75x75',
location: {
title: 'TriStar Centennial',
address: '2300 Patterson St',
city: 'Nashville',
state: 'TN',
zipCode: 37203
}
}
]
}
})
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Axios from '@/components/Axios'
import VueResource from '@/components/VueResource'
import PhysicianListing from '@/components/PhysicianListing'
import ProgressSteps from '@/components/ProgressSteps'
import PhysicianProfile from '@/components/PhysicianProfile'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Axios',
component: Axios
},
{
path: '/resource',
name: 'VueResource',
component: VueResource
},
{
path: '/physicians',
name: 'physician-listing',
component: PhysicianListing
},
{
path: '/physicians/profile/:firstName-:lastName-:designation',
name: 'pd-profile',
component: PhysicianProfile
},
{
path: '/progress',
name: 'progress-steps',
component: ProgressSteps
}
]
})
PhysicianFullListing.vue Reusable Component
<template>
<li class="pd-item">
<div class="pd-header d-flex align-items-start">
<div class="pd-number">{{physician.id}}</div>
<img :src="physician.photo" alt="" class="pd-photo rounded-circle mr-4">
<div class="pd-info">
<h2 class="pd-title">{{physician.name}}</h2>
<p>{{physician.specialty}}</p>
<p class="pd-location">
<span class="pd-miles">
<i class="material-icons">place</i> {{physician.locationDistance}} miles away
</span><br>
{{physician.location.title}}<br>
{{physician.location.address}},<br>
{{physician.location.city}}, {{physician.location.state}} {{physician.location.zipCode}}
</p>
</div>
</div>
<div class="pd-footer d-flex justify-content-between">
<div class="pd-rating">
<span class="material-icons star-rating">star</span>
<span class="material-icons star-rating">star</span>
<span class="material-icons star-rating">star</span>
<span class="material-icons star-rating">star</span>
<span class="material-icons star-rating">star</span>
</div>
<router-link v-bind:to="{name: 'pd-profile', params: {firstName: physician.firstName, lastName: physician.lastName, designation: physician.designation}}">
View Profile
</router-link>
</div>
</li>
</template>
<script>
export default {
name: 'physician-full-listing',
props: {
physician: Object
},
data () {
return {
msg: 'Physicians Full Listing'
}
}
}
</script>
PhysicianListing.vue Reusing Components
<template>
<div class="physician-listing">
<h1 class="mt-3 mb-3 text-center">{{msg}}</h1>
<physician-filters></physician-filters>
<physician-search></physician-search>
<div class="row">
<div class="pd-list-column col-4">
<p class="results-txt">Showing 1-5 of {{physicians.length}} results</p>
<ul class="pd-listing list-unstyled">
<physician-full-listing v-for="physician in physicians" :key="physician.id" :physician="physician"></physician-full-listing>
</ul>
<div class="fixed-action-btn">
<router-link to="/progress" class="btn-floating blue">
<i class="material-icons">arrow_downward</i>
</router-link>
</div>
</div>
<div class="col-8">
<google-map name="example"></google-map>
</div>
</div>
</div>
</template>
<script>
import GoogleMap from '@/components/GoogleMap'
import PhysicianFilters from '@/components/physicians/PhysicianFilters'
import PhysicianSearch from '@/components/physicians/PhysicianSearch'
import PhysicianFullListing from '@/components/physicians/PhysicianFullListing'
export default {
name: 'physician-listing',
components: {
PhysicianFullListing,
GoogleMap,
PhysicianFilters,
PhysicianSearch
},
data () {
return {
msg: 'Make an Appointment',
}
},
computed: {
physicians() {
return this.$store.state.physicians
}
}
}
</script>
PhysicianProfile.vue
<template>
<div class="physician-profile">
<h1 class="mb-5">{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'pd-profile',
data () {
return {
msg: 'Physician Profile'
}
}
}
</script>
2
Answers
First, by adding
props: true
to your route object, you can pass in the route parameters as props to your PhysicianProfile componentThen you can add those three props to your PhysicianProfile component, and set up a Vuex getter to fetch the physician:
Check these out for further reading
https://medium.com/vue-by-example/learn-quickly-passing-params-as-props-with-vue-router-f4905735b747
https://vuex.vuejs.org/guide/getters.html
You can pass props through the URL, in this case, the Physician ID. Then you can fetch the physician in the created lifecycle hook 🙂
To make the explanation a bit easier I’ll add an id to your path (/physician/profile/id/firstName-lastName-designation). You can change the find method in the created hook to suite your needs 🙂
You then need to set the props and fetch the physician in PhisicianProfile.vue:
For more information about passing props, check out the vue router documentation 🙂