preface
Vue surrounding ecological of official documentation is brushed again recently, because before learning are watching video with the document, but largely through video learning, so it doesn’t understand a lot of knowledge, since the last time to brush the Vuex official documentation is realized through the benefits of a document, learning a foreign technology in the “learning” after the best or go to the official documentation, In this way, you will have a thorough understanding of this technology and a comprehensive knowledge point. Therefore, after brushing Vuex documents, I wrote an article called “In-depth Vuex Best Practices”, and then spent two days (no time for scratching at work, I studied at night) brushing vuE-Router official documents, so I have this article. Therefore, there will be an article about the configuration of VUe-CLI in the future, so the whole article is mainly from a practical perspective. In the next part, I will try to implement the core part of VUe-Router, and finally interpret the source code of the core function
Online humble, if you think this article is helpful to you welcome everyone to click 👻
Introduction to the
Vue-router is the official vue. js route manager. Its deep integration with the vue.js core makes building a single page application a breeze
Let’s start with two things
- Single Page Application (SPA)
- Route manager
Single page application
Single-page applications limit all activity to a Single Web page, loading the appropriate HTML, JavaScript, and CSS only when the Web page is initialized. Once the page is loaded, SPA does not reload or redirect the page because of user actions. Instead, JavaScript is used to dynamically transform HTML content to enable UI interaction with the user.
Route manager
The route manager here is not the hardware router in our daily life, the route here is the single page application (SPA) path manager, is to solve the vue. js single page application can not be linked to jump, we through the path of the way to manage different pages
After understanding the problems that vue-Router solves, we began to learn some of the functions that vue-Router commonly uses in projects
- Nested routing/viewing diagrams
- Modular, component-based routing configuration
- Route parameters, queries, and wildcards
- Fine-grained navigation control
start
Let’s start by looking at some of the functions of the Vue-Router:
- Dynamic route matching
- Embedded routines by
- Declarative/programmatic navigation
- Name route/name view
- Redirects and aliases
- Routing components pass parameters
The addresses of all the sample repositories in this article are given at the end of this article
Dynamic route matching
router.js
import Vue from 'vue' / / into the Vue
import Router from 'vue-router' Vue / / in the router
import Home from '@/pages/Home' // Import the hello.vue component from the root directory
// Vue uses Router globally
Vue.use(Router)
/* Build a single page application using vue.js + Vue-router, as long as we compose our application by combining the components, we introduce vue-router, as long as we map the components to routes, telling Vue-router where to render them */
let routes = [ // Configure routing, which is an array
{ // Each link is an object
path: '/'.// Link the path
name: 'Home'.// Route name,
component: Home // The corresponding component template
},
// Dynamic path parameters start with a colon
{ path: '/user/:username'.// Dynamic routing
component: () = > import('.. /pages/User1'), // To load the components corresponding to the route on demand, you need to download polyfill compatible with ES6 syntax
},
{ // Multisegment path parameters
path: '/user/:id/post/:post_id'.// Dynamic routing
component: () = > import('.. /pages/User2'), // To load the components corresponding to the route on demand, you need to download polyfill compatible with ES6 syntax},]export default new Router({
routes
})
Copy the code
User1
This component is displayed when the user accesses /#/user/ XXX
<template>
<div class="User1">User1 - Single path parameter</div>
</template>
Copy the code
User2
/#/user/ XXX /post/ XXX
<template>
<div class="User2">User2 - Multisegment path parameter route</div>
</template
Copy the code
So how do we know which dynamic parameter route the user is accessing? This is the time to respond to changes in the routing parameters
Two ways: watch (monitor changes) $route object, beforeRouteUpdate navigation guard
Add the following code to user1.vue
<template>
<div class="User1">
<! The route attribute can be obtained from the router object. This way, the route attribute can be obtained from the router object.User1 -{{$route.params.username}} Single path parameter</div>
</template>
<script>
export default {
name: 'User1'.// Listen to route object mode
watch: {
$route (to, from) {
this.$message.success(`watch -> ${to.path}.The ${from.path}`)}},// Vue2.2 introduces navigation guards that are called when route parameters change
beforeRouteUpdate (to, from, next) {
this.$message.info('Navigation Guard ->${to.path}.The ${from.path}`)
// Be sure to call Next to continue parsing the routing component in the next pipeline
next()
}
}
</script>
Copy the code
demo
Note that the above ck->ks route parameter changes are heard in both ways, we can do some operations in these two functions when the route state changes
Routing components pass parameters
In the
template, the $router.prams. Username parameter passed by the route is already highly coupled to its corresponding route, limiting its flexibility. We can use props to decouple the component from the route
There are three ways to pass the routing component parameter:
- The Boolean model
- Object pattern
- The function mode
code
router.js
import Vue from 'vue'
import Router from 'vue-router'
import home from '@/pages/Home'
Vue.use(Router)
let routes = [
{
path: '/'.name: 'Home'.component: home
},
{ // Dynamic path parameters start with a colon
path: '/user1/:username'.// Dynamic routing
component: () = > import('.. /pages/User1'),
props: true // Boolean mode: if props is set to true, rout. params will be set as a component property.
},
{
path: '/user2'.component: () = > import('.. /pages/User2'),
props: {username: 'ck'} // Object mode: only static routes are valid and the parameters are write-dead
},
{
path: '/user3/:username'.component: () = > import('.. /pages/User3'),
// Return a parameter in the user URL such as /user3? Username ='ck' => {username: 'ck'
props: (route) = > ({username: route.query.username}) // Function mode}]export default new Router({
routes
})
Copy the code
User1
The Boolean model
<template>
<div class="User1">
User1 -{{username}}
</div>
</template>
<script>
export default {
name: 'User1'.props: ['username'] // Use props to get the parameters that the route passes to the corresponding component
}
</script>
Copy the code
User2
Object pattern
<template>
<div class="User2">
User2 - {{username}}
</div>
</template>
<script>
export default {
name: 'User2'.props: ['username'] // Use props to get the parameters that the route passes to the corresponding component
}
</script>
Copy the code
User3
The function mode
<template>
<div class="User3">
User3 - {{username}}
</div>
</template>
<script>
export default {
name: 'User3'.props: ['username'] // Use props to get the parameters that the route passes to the corresponding component
}
</script>
Copy the code
demo
From above we can see that because user2 is a static route, it does not support dynamic parameters and the parameters passed by its corresponding routing component are also written dead
Embedded routines by
Real-world application interfaces are typically composed of multiple layers of nested components. Similarly, the segments of the dynamic path in the URL correspond to nested layers of components in a certain structure, such as:
/user/ck/profile /user/ks/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
Copy the code
router.js
import Vue from 'vue'
import Router from 'vue-router'
import home from '@/pages/Home'
Vue.use(Router)
let routes = [
{
path: '/'.name: 'Home'.component: home,
},
{
path: '/user/:username'.// Dynamic routing
name: 'User'.component: () = > import('.. /components/User'),
children: [{// If '/user/:username/profile' matches successfully, the UserProfile will be rendered in the
of the user
path: 'profile'.// Can match /user/ks/profile
name: 'Profile'.component: () = > import('.. /components/Profile')}, {path: '/user/:usrname/posts'.// we can match /user/ks/posts, but we can match /user:username dynamic component to posts
name: 'Posts'.component: () = > import('.. /components/Posts')}, {path: ' '.name: 'UserHome'./ / when/user / : username matching success, such as/user/ks | | / user/ck
// The UserHome is rendered in the User
component: () = > import('.. /components/UserHome')},]}, {path: '/footer'.name: 'Foo'.component: () = > import('.. /components/Footer')}]export default new Router({
routes
})
Copy the code
demo
Declarative/programmatic navigation
declarative | programmatic |
---|---|
<router-link :to="..." replace> |
router.replace(...) |
<template>
<div class="home">
<! -- declarative -->
<router-link
to="footer"
tag="button"
>
to footer
</router-link>
<! -- program -->
<button @click="$router.push('footer')">String - The way to write the route path</button>
<button @click="$router.push({path: '/footer'})">Object - The way to write paths</button>
<button @click="$router.push({name: 'Foo', params: {'userId': '123'}})">Name and params-Write route name to carry parameters</button>
<button @click="$router.push({path: '/footer', query: {'userId': '456'}})">Queyr and path - Write the way routing paths carry parameters</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'home',
data () {
return{}},methods: {}}</script>
<style>
button {
display: block;
}
</style>
Copy the code
router.push(location, onComplete? , onAbort?)
router.replace(location, onComplete? , onAbort?)
These two methods are the same, the only difference is that push generates routing history, while repalce does not, which is consistent with the history in window
<! -- router-go -->
<template>
<button @click="goForward">Go (1)- One step forward</button>
<button @click="goBack">Go (-1)- Take a step back</button>
<button @click="gogogo">Go (100)- One white step forward</button>
</template>
<script>
export default {
name: 'home'
methods: {
goForward () {
// Forward from the historical route is equivalent to window.history.forward
this.$router.go(1);
},
goBack () {
// Taking a step back from the historical route is equivalent to window.history.back
this.$router.go(-1);
},
gogogo () {
// If there are not 100 steps in the historical route, nothing will be done
this.$router.go(100); }}}</script>
Copy the code
demo
Named route/named view/redirection and alias
router.js
import Vue from 'vue'
import Router from 'vue-router'
import UserSettings from '@/pages/UserSettings'
Vue.use(Router)
let routes = [
{
path: '/'.redirect: '/settings' / / redirection
},
{
path: '/settings'.name: 'Settings'.// Name the route
alias: '/a'.// If the url accesses /a ->, the Settings component is also accessed, but the route matches /a, as if the user were accessing /a
// You can also configure the named view on the top-level route
component: UserSettings,
children: [{path: 'emails'.component: () = > import('.. /pages/UserEmails')}, {path: 'profile'.components: {
default: () = > import('.. /pages/UserProfile'),
helper: () = > import('.. /pages/UserProfilePreview')}}]}]export default new Router({
routes
})
Copy the code
UserSetttings
<template>
<div class="UserSettings">
<h1>User Settings</h1>
<NavBar/>
<router-view/>
<! -- Name the view -->
<router-view name="helper"/>
</div>
</template>
<script>
import NavBar from '.. /components/NavBar'
export default {
name: 'UserSettings'.components: {
NavBar
}
}
</script>
Copy the code
Through the above study, I believe that you have held the functions commonly used by Vue-Router in the project. Now let’s start to learn the navigation guard of Vue-Router
The advanced
Navigation guard
Navigation indicates that the route is changing. Remember that changes to parameters or queries do not trigger entry/exit navigation guards. You can react to these changes by watching the $Route object respond to changes in the route parameters, or by using the component inside the beforeRouteUpdate.
The guardian of the whole
- Global front Guard (router.beforeeach)
- Global Resolution Guard (router.breForeresolve)
- Global afterhook (router-aftereach) Note: This hook does not have next
Route exclusive guard
You can define beforeEnter guards directly on the route configuration:
const router = new VueRouter({
routes: [{path: '/foo'.component: Foo,
beforeEnter: (to, from, next) = > {
// to -> to jump to the previous routing information
// from -> The current routing information
// next() => a function that resolves routing records in the next pipeline}}}])Copy the code
A guard inside a component
Finally, you can define the following route navigation guards directly within the routing component:
beforeRouteEnter
beforeRouteUpdate
(new) 2.2beforeRouteLeave
const Foo = {
template: `... `,
beforeRouteEnter (to, from, next) {
// Called before the rendering component's corresponding route is confirmed
/ / no! Can!!!! Get component instance 'this'
// Because the component instance was not created before the guard executed
},
beforeRouteUpdate (to, from, next) {
// called when the current route has changed but the component is being reused
// For example, for a path with dynamic parameters /foo/:id, jump between /foo/1 and /foo/2,
// Since the same Foo component is rendered, component instances are reused. The hook will be called in that case.
// Can access component instance 'this'
},
beforeRouteLeave (to, from, next) {
// called when navigating away from the corresponding route of the component
// Can access component instance 'this'}}Copy the code
BeforeRouteEnter The guard cannot access this because the guard is called before the navigation is confirmed, so the incoming component has not yet been created. However, you can access the component instance by passing a callback to next. The callback is performed when the navigation is confirmed, and the component instance is taken as a parameter to the callback method.
beforeRouteEnter (to, from, next) {
next(vm= > {
// After the instance is created, the callback passed by next is called and the instance is passed in as an argument, so the component instance can be accessed through 'vm'})}Copy the code
Note that beforeRouteEnter is the only guard that supports passing a callback to next. For beforeRouteUpdate and beforeRouteLeave, this is already available, so the passing callback is not supported because it is no longer necessary.
beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
Copy the code
This exit guard is usually used to prevent users from abruptly leaving without saving their changes. This navigation can be cancelled by next(false).
beforeRouteLeave (to, from, next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes! ')
if (answer) {
next()
} else {
next(false)}}Copy the code
practice
Above talk so much believe you are also muddle. what is the timing of these route calls, and what is the order, below we according to the official explanation to practice
Complete navigation parsing process
- Navigation is triggered.
- Called in an inactive component
beforeRouteLeave
The guards. - Call global
beforeEach
The guards. - Called in a reused component
beforeRouteUpdate
Guard (+ 2.2). - Called in the routing configuration
beforeEnter
. - Resolve the asynchronous routing component.
- Called in an activated component
beforeRouteEnter
. - Call global
beforeResolve
Guard (+ 2.5). - Navigation is confirmed.
- Call global
afterEach
Hook. - Triggers a DOM update.
- Called with the created instance
beforeRouteEnter
Guard passnext
Callback function.
router.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/pages/Home'
import {message} from 'ant-design-vue'
Vue.use(VueRouter)
let routes = [
{
path: '/'.name: 'Home'.component: Home,
},
{
path: '/index'.name: 'Index'.component: () = > import('.. /pages/Index'),}, {path: '/user/:id'.name: 'User'.props: true.component: () = > import('.. /pages/User'),
beforeEnter: (to, from, next) = > {
message.success(Route exclusive guard [beforeEnter] -> FromThe ${from.path} 到 ${to.path}`);
next()
}
}
]
let router = new VueRouter({
routes
})
router.beforeEach((to, from, next) = > {
message.success('Global front guard [beforeEach] -> FromThe ${from.path} 到 ${to.path}`.5)
next();
})
router.beforeResolve((to, from, next) = > {
message.success('Global resolution guard [beforeResolve] -> fromThe ${from.path} 到 ${to.path}`.5)
next();
})
router.afterEach((to, from) = > {
// The hook has no next and does not change the navigation itself
message.success(Global afterhook [afterEach] -> fromThe ${from.path} 到 ${to.path}`.5)})export default router
Copy the code
Home.vue
<template> <div class="Home"> <div class="title">Home</div> <a-button type="primary" @click="toIndexHanlder"> to Index </a-button> </div> </template> <script> export default { name: 'Home', beforeRouteLeave(to, from, next) {this.$message. Success (' component inside guard[leave] -> from ${from. next(); }, methods: { toIndexHanlder() { this.$router.push({ path: '/index' }); ,}}}; </script>Copy the code
Index.vue
<template> <div class="Index"> <div class="title">Index</div> <a-button class="my-btn" type="primary" </a-button> <a-button class="my-btn" type="primary" @click="toUserHanlder"> </a-button> </div> </template> <script> export default { name: 'Index', beforeRouteLeave (to, from, next) { console.log(to); next() }, methods: { BackHanlder () { this.$router.go(-1) }, toUserHanlder () { this.$router.push({path: 'user/ck'}) } } } </script>Copy the code
User.vue
<template>
<div class="User">
<div class="title">User - {{id}}</div>
<a-button class="my-btn" type="primary" @click="toUserJump">Forward dynamic routing</a-button>
</div>
</template>
<script>
export default {
name: 'User',
data () {
return {
names: ['a'.'b'.'c'.'d'.'e'.'f'].// Random routing
curNameIndex: 0.lastNameIndex: 0,}},props: ['id'],
beforeRouteUpdate (to, from, next) {
this.$message.success('Component inside guard [beforeRouteUpdate] -> fromThe ${from.path} 到 ${to.path}`.5)
next()
},
beforeRouteEnter (to, from, next) {
// Cannot get this, because the component instance was not created before the guard executed,
// But in this guard next supports passing callbacks that are called after the instance has been created
next((vm) = > {
// vm => Create a Vue instance
vm.$message.success(Component inside the guard [beforeRouteEnter] -> fromThe ${from.path} 到 ${to.path}`.5)})},methods: {
// Obtain the method of random route
getRandomArbitrary (min, max) {
this.curNameIndex = Math.round(Math.random() * (max - min) + min);
return this.curNameIndex === this.lastNameIndex
? this.getRandomArbitrary(min, max)
: this.curNameIndex;
},
toUserJump () {
this.getRandomArbitrary(0.this.names.length -1)
this.lastNameIndex = this.curNameIndex;
this.$router.push({path: `/user/The ${this.names[this.curNameIndex]}`})}}}</script>
Copy the code
demo
The GIF above may be too fast, so take a screenshot of each step and analyze it
The numbers in the upper indices correspond to the order given by the authorities
Route guard triggered by jumping from home.vue to index.vue
-
- Click the button to trigger navigation
-
- Called in the deactivated component guard (home.vue)
beforeRouterLeave
To leave the component
- Called in the deactivated component guard (home.vue)
-
- Call the global front guard
beforeEach
From the route object, we can get the route information before and after the jump
- Call the global front guard
-
- Route resolution is complete
The numbers in the upper indices correspond to the order given by the authorities
Route guard triggered by jumping from index. vue to user/ck
-
- Call the global front guard
beforeEach
- Call the global front guard
-
- Called in the routing configuration (user.vue)
befreEnter
- Called in the routing configuration (user.vue)
-
- Call global
afterEach
Hook.
- Call global
-
- Called with the created instance
beforeRouteEnter
Guard passnext
And passes the created instance in
- Called with the created instance
Route guard triggered by jumping from User /ck to User/C
-
- slightly
-
- Because this component is dynamically routed in
/user/ck
->user/c
The reuse of the same component is triggeredbeforeRoteUpdate
- Because this component is dynamically routed in
-
- slightly
-
- slightly
case
The case involves
- Dynamically modify routing meta information and document title
- Dynamic routing based transition
- Intercepting user login status based on navigation guard
- A 404 page is returned for components that are not defined
- The exit guard of the route is used to confirm that the user goes to the login page
If you want to go to GitHub, please go to Start👻
Imitation vue-Router source implementation
-
Implement THE SPA page (the page is not refreshed)
-
hash #/beige
-
Hisotry API /beige
-
-
The corresponding content is displayed according to the URL
- router-view
- Data response: the current variable holds the URL address, once changed, dynamically re-execute render corresponding components
Let’s start implementing the Vue-Router plug-in
install
main.js
// Import the vue-router routing table
import router from './my-router'
new Vue({
router,
store,
render: h= > h(App)
}).$mount('#app')
Copy the code
@/vue-router/index.js
// Introduce your own vue-router
import VueRouter from "./my-vue-router";
// Introduce vue-router as a plug-in
Vue.use(VueRouter);
/ / the routing table
letRoutes = [...]const router = new VueRouter({
routes,
});
export default router;
Copy the code
@/vue-router/my-vue-router
let Vue;
// Vue plug-in format:
// Implement an install method, which will be called during use
myVueRouter.install = function install(_Vue) {
// _Vue => Vue. Use The constructor passed in
// Pass in the constructor, which we can modify to extend the prototype
// this => myVueRouter
Vue.mixin({
beforeCreate() {
// This refers to the component instance
if (this.$options.router) {
Vue.prototype.$router = this.$options.router; }}});Vue-router provides two global components
Vue.component('router-link', Link)
Vue.component('router-view', View)
}
Copy the code
Here we go. Why do we have to mix it up? The use code is first, the Router instance is created later, and the install logic needs to use the instance. The hook can be mixed with the mixin, and the hook can be mixed with any component instance built by the new Vue. We determine whether the optionsAPi is the root instance by determining whether the router configuration item is passed by the optionsAPi, and then mount the routing configuration item passed by the root instance to the prototype chain for all component instances to share
myVueRouter constructor
constructor(options) {
// The save option contains the route configuration information
this.$options = options;
// Cache the mapping between path and route.
this.routeMap = {}
this.$options.routes.forEach(route= > {
this.routeMap[route.path] = route
});
// The current attribute needs to be declared responsive
// defineReactive is Vue's ability to make the specified data responsive
Vue.util.defineReactive(
this."current".window.location.hash.slice(1) | |"/"
);
// This in turn does not use Set reason -> the Set method to receive obj must be responsive
// Vue.set(obj, key, val)
// 2. Listen for hashChang events and respond when they change
window.addEventListener("hashchange".() = > {
// hash: #/about
console.log(this.current);
this.current = window.location.hash.slice(1);
});
}
Copy the code
We only implement route jumps by listening for hash changes, mainly through the HashChange API
router-view
The next step is to implement the most critical router-view, the route attempt to render the routing component of the corresponding path on the page
Vue.component("router-view", {
render(h) {
// Get the router instance to get the path
// Obtain components from the routing table according to path
const {routeMap, current} = this.$router
const component = routeMap[current] ? routeMap[current].component : null;
returnh(component); }});Copy the code
This is a good explanation of why we want to change current to responsive data during initialization. Data responsive: Data changes can be listened to, using these data components will have a dependency on the responsive data in the future if the responsive data changes, the components will be rerendered
router-link
Vue.component("router-link", {
props: {
to: {
type: String.required: true,}},render(h) {
// h is createElement and returns vNode
// Get the slot contents
return h(
"a",
{
attrs: {
href: "#" + this.to,
},
},
this.$slots.default ); }});Copy the code
Router-link works in a very simple way. It essentially renders a hyperlink, converts to an HREF, and accesses the component’s content through the default slot
Rendering 💗
The source code interpretation
View the official vue-router source address
Vue-router Implementation principle
When the vue-router is instantiated, this. History is initialized. If the mode is passed, the history will be different
constructor (options: RouterOptions = {}) {
this.mode = mode // Do not pass mode, the default is hash
switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base)
break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback)
break
case 'abstract':
this.history = new AbstractHistory(this, options.base)
break
default:
if(process.env.NODE_ENV ! = ='production') {
assert(false.`invalid mode: ${mode}`)}}}// => We'll get an example of this. We'll call some of the push, replace, and go methods on this
Copy the code
Here, taking HashHistory as an example, the push method of Vue-Router is implemented as follows:
push (location: RawLocation, onComplete? :Function, onAbort? :Function) {
// $flow-disable-line
if(! onComplete && ! onAbort &&typeof Promise! = ='undefined') {
return new Promise((resolve, reject) = > {
this.history.push(location, resolve, reject)
})
} else {
this.history.push(location, onComplete, onAbort)
}
}
// The push method of this.history is called after the push method is called
Copy the code
HashHistory implements the push method:
function pushHash (path) {
if (supportsPushState) {
pushState(getUrl(path))
} else {
window.location.hash = path // This is essentially an encapsulation of the window.location.hash method}}Copy the code
Listening on routes is implemented by listening on events corresponding to the hash:
window.addEventListener(
supportsPushState ? 'popstate' : 'hashchange'.() = > {
const current = this.current
if(! ensureSlash()) {return
}
this.transitionTo(getHash(), route= > {
if (supportsScroll) {
handleScroll(this.router, route, current, true)}if(! supportsPushState) { replaceHash(route.fullPath) } }) } )// We also listen to the popstate and hashChange events provided by the window object to respond to the hash listening
Copy the code
Therefore, the core of Vue-router isto use History to instantiate the corresponding function, and the History is determined by the mode passed in. Different History calls have different underlying methods, but the underlying methods are all instances provided by window.location. For example, hash changes are supported through the hashChange event listener, so vue-Router is essentially a wrapper around native events
In addition, vue-Router provides two components:
Vue.component('RouterView', View)
Vue.component('RouterLink', Link)
Copy the code
Write in the last
Since this is a practical article, the whole article will be written in code, and there will be less talk about concepts and basic syntax. If this post helped you, please like 🤓
Practice makes perfect, shortage in one
If there is a piece of writing in the article is not very good or there are questions welcome to point out, I will also keep modifying in the following article. I hope I can grow with you as I progress. Those who like my article can also pay attention to it
I’ll be grateful to the first people to pay attention. At this time, you and I, young, packed lightly; And then, rich you and I, full of it.