Studio 11
Part 1: Components and Routing
As your chat apps get larger, breaking things out into isolated components will help you keep your code organized. Components can be used for reusable pieces of UI, like a "like" button, but they can also be used for larger pieces like whole pages.
In your personal homepage you have been breaking up your code into multiple HTML files. Unforutunately, that will not work well in our chat app because the browser will have to reload everything on the page and clear out any state that you are managing. Additionally, as you have probably found, breaking up your code into multiple HTML files means you need to copy and paste the same header and footer code into each file, which is difficult to maintain.
This studio is going to walk you through a common pattern called "client-side routing" that usually uses components to break out your code into smaller pieces that appear to be multiple pages---even to the end-user who will see the URL change, which can be useful for sharing links to specific pages, bookmarking them, and navigating with the browser's built-in back and forward buttons. However, the app itself will not have to reload, making it single page application (SPA).
To get started, clone the starter code for this studio.
The starter app includes two components for you,
ChatList
and Chat
. These include very little functionality, they are just
here as placeholders to represent two pages of your app.
These components are already broken out into separate files,
chat-list.js
, chat-list.html
, chat.js
, and chat.html
.
Take a look at all of thes files to get a sense of how things are wired together.
Currently, the main app imports the ChatList component and displays it in the
main page and the ChatList app imports the Chat component and displays it.
Importantly, a prop
is passed to the Chat component that contains the
chatId
of the chat that is being displayed.
We're going to use a "router" to manage the state automatically for us
and change the URL when we switch between components.
The router package, Vue Router
includes its own custom components,
<router-view>
and <router-link>
, that we will use to
make this work.
Step 1: Adding a home route.
We have included some basic boiler plate in index.html
,
that installs the router into Vue, but it is up to you to configure it.
Start by modifying the routes
property,
which is a mapping from URL paths to components.
Start by just defining a single route for the home page that displays the ChatList
component in the route "/".
const router = createRouter({
history: createWebHashHistory(),
routes: [
{ path: "/", component: ChatList },
]
});
Once that is done,
change the <chat-list></chat-list>
component in index.html
to
<router-view></router-view>
. The <router-view>
component will
basically be replaced with whatever component matches the current path.
If you do everything right, nothing should change!
This is because currently our router only includes one route, which is
the <chat-list>
component that we had before.
Step 2: Adding a chat route.
Now things are going to get more interesting. Let's add another route
that maps paths of the form /chat/:chatId
to the Chat
component.
Note that the notation :chatId
, means that part of the path is a variable,
that will be passed to the Chat
component as a prop.
The added route should look like this, with props
set to true
so that the chatId
is passed as a prop to the component.
{ path: "/chat/:chatId", component: Chat, props: true },
Make sure to import the Chat
component, just like we have already
imported the ChatList
component.
Next, go into the chat-list.html
file and replace the button with
a <router-link>
component that links to the chat page.
<router-link :to="`/chat/${chat}`"> Chat {{ chat }} </router-link>
Try it out! Does the component and URL change when you click the link?
At this point you can also delete the <chat>
component from the
chat-list.html
file, since when you click the chat link, the entire
<chat-list>
component will be replaced with the <chat>
component.
Step 3: Adding a back button.
Once you clicked into a chat, you currently can't get back without
going and clicking the browser's back button or manually changing the URL.
It is nice that you now support these, but your app should also provide
a way to go back on its own without these external tools.
Add a <router-link>
component with an appropriate path within the <h1>
tag within index.html
to allow you to always click the title to go back to the home page.
Step 4: Adding a "profile" page
Add another link, using <router-link>
to add a "Profile" page
at the path /profile
and with a new profile component that you create - it
does not need to include much, just a placeholder like the Chat
component.
Make sure you can navigate between all the pages.
Step 5: Signifying the current page
Imagine the user navigates to their "profile" page, goes off and makes lunch, and then returns back to the app. When they return, they may not remember which page they were on, and currently the only way to work out the page they are on is to try and parse out the content on the page. For example, they might see their name and a profile picture and then guess "oh, I must be on the profile page". This is inefficient and can potentially lead to errors if there are pages that contain similar content.
Instead, a common pattern used in many apps is to highlight
or underline the page the user is currently on in the navigation
bar.
Fortunately, the Vue Router package automatically adds the class
router-link-active
to <router-link>
components that
point to the current page.
Use CSS to style the router-link-active
class to indicate
to the user which page they are on.