1 安装
步骤一:安装vue-router
npm install vue-router --save
步骤二:在模块化工程中使用它(因为是一个插件,所以可以通过Vue.use()来安装路由功能)
-
导入路由对象,并且调用Vue.use(VueRouter)
-
创建路由实例,并且传入路由映射配置
-
在Vue实例中挂载创建的路由实例
2 使用vue-router的步骤
-
创建路由组件
-
配置路由映射:组件和路径映射的关系
-
使用路由:通过<router-link>和<router-view>
<router-link>:该标签是一个vue-router中已经内置的组件,它会被渲染成一个<a>标签
<router-view>:该标签会根据当前路径,渲染出不同的组件
网页中其他的内容,比如顶部的标题/导航,或者底部的一些版权信息会和<router-view>出于同一个等级
在路由切换时,切换的是<router-view>挂载的组件,其他内容不会发生改变
3 history模式
index.js的export中添加
mode: 'history'
4 router-link补充
tag属性
:渲染为指定元素
<router-link to="/home" tag="button">首页</router-link>
replace属性
:该属性不会留下history记录,所以指定replace的情况下,后退键返回不能返回到上一个页面中
<router-link to="/home" tag="button" replace>首页</router-link>
active-class
:当<router-link>对应的路由匹配成功时,会自动给当前元素设置一个router-link-active的class,设置active-class可以修改默认的名称
router-link-active
属性修改为active
<router-link to="/home" tag="button" replace active-class="active">首页</router-link>
5 代码跳转路由
<button @click="homeClick">首页</button>
methods: {
homeClick() {
// 通过代码的范式修改路径 vue-router
this.$router.push('/home')
console.log('homeClick');
}
}
6 动态路由
{
path: '/user/:userId',
name: 'User',
component: User
}
子路由获取参数
<template>
<div>
<h2>我是用户界面</h2>
<p>用户信息</p>
<h2>{{ userId }}</h2>
<h2>{{ $route.params.userId }}</h2>
</div>
</template>
<script>
export default {
name: "User",
computed: {
userId() {
return this.$route.params.userId
}
}
}
</script>
7 路由的懒加载
路由懒加载做了什么
index.js
方式一:
const Home = resolve => {
require.ensurre(['../components/Home.vue'],()=>{
resolve(require('../components/Home.vue'))
})
}
方式二:AMD写法
const About = resolve => require(['../compontents/About.vue'], resolve);
方式三:在ES6中,我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割
// 懒加载方法导入(一个懒加载对应一个js文件)
const Home = () => import('../components/Home')
8 嵌套路由
Home.vue
<router-link to="/home/news">新闻</router-link>
<router-link to="/home/message">消息</router-link>
<router-view></router-view>
index.js
{
path: '/home',
name: 'Home',
component: Home,
children: [
{
path: '',
redirect: '/news'
},
{
path: 'news',
component: HomeNews
},
{
path: 'message',
component: HomeMessage
},
]
},
9 传递参数
-
params类型:/route/:id
-
query:类型 /router?id=123
button
和router-link
方法二选一
http://localhost:8080/profile?id=1&name=charles
# router-link
<router-link :to="{ path: '/profile',query:{id:'1',name:'charles'}}">个人资料</router-link>
# button
<button @click="userClick">用户</button>
<button @click="profileClick">个人资料</button>
<router-view></router-view>
userClick() {
this.$router.push('/user/' + this.userId)
},
profileClick() {
this.$router.push({
path: '/profile',
query: {
id: 2,
name: 'tom'
}
})
}
profile.vue
<h2>{{ $route.query.id }}</h2>
<h2>{{ $route.query.name }}</h2>
10 导航守卫
// 前置守卫(guard)
router.beforeEach((to, from, next) => {
document.title = to.matched[0].meta.title
next()
})
// 后置钩子(hook)
router.afterEach((to,from)=>{
})
index.js
{
path: '/about',
name: 'About',
meta: {
title: '关于'
},
component: About
},
About.vue
<script>
export default {
name: "Home",
created() {
console.log('created');
document.title = to.matched[0].meta.title
},
}
</script>
11 keep-alive遇见vue-router
- keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染
(1)include:字符串或正则表达式,只有匹配的组件会被缓存
(2)exclude:字符串或正则表达式,任何匹配的组件都不会被缓存
- router-view:也是一个组件,如果直接被包在
keep-alive
里面,所有路径匹配到的视图组件都会被缓存
// 这两个函数,只有该组件被保持了装填使用keep-alive时,才是有效的
activated() {
this.$router.push(this.path)
},
beforeRouteLeave(to, from, next) {
this.path = this.$route.path;
next()
}
<keep-alive>
<router-view/>
</keep-alive>
<h2><a id="1__0"></a>1 安装</h2>
<p>步骤一:安装vue-router</p>
<pre><div class="hljs"><code class="lang-shell">npm install vue-router --save
</code></div></pre>
<p>步骤二:在模块化工程中使用它(因为是一个插件,所以可以通过Vue.use()来安装路由功能)</p>
<ol>
<li>
<p>导入路由对象,并且调用Vue.use(VueRouter)</p>
</li>
<li>
<p>创建路由实例,并且传入路由映射配置</p>
</li>
<li>
<p>在Vue实例中挂载创建的路由实例</p>
</li>
</ol>
<h2><a id="2_vuerouter_15"></a>2 使用vue-router的步骤</h2>
<ol>
<li>
<p>创建路由组件</p>
</li>
<li>
<p>配置路由映射:组件和路径映射的关系</p>
</li>
<li>
<p>使用路由:通过<router-link>和<router-view></p>
</li>
</ol>
<pre><div class="hljs"><code class="lang-shell"><router-link>:该标签是一个vue-router中已经内置的组件,它会被渲染成一个<a>标签
<router-view>:该标签会根据当前路径,渲染出不同的组件
网页中其他的内容,比如顶部的标题/导航,或者底部的一些版权信息会和<router-view>出于同一个等级
在路由切换时,切换的是<router-view>挂载的组件,其他内容不会发生改变
</code></div></pre>
<h2><a id="3_history_33"></a>3 history模式</h2>
<p>index.js的export中添加</p>
<pre><div class="hljs"><code class="lang-js"><span class="hljs-attr">mode</span>: <span class="hljs-string">'history'</span>
</code></div></pre>
<h2><a id="4_routerlink_41"></a>4 router-link补充</h2>
<p><code>tag属性</code>:渲染为指定元素</p>
<pre><div class="hljs"><code class="lang-js"><router-link to=<span class="hljs-string">"/home"</span> tag=<span class="hljs-string">"button"</span>>首页</router-link>
</code></div></pre>
<p><code>replace属性</code>:该属性不会留下history记录,所以指定replace的情况下,后退键返回不能返回到上一个页面中</p>
<pre><div class="hljs"><code class="lang-js"><router-link to=<span class="hljs-string">"/home"</span> tag=<span class="hljs-string">"button"</span> replace>首页</router-link>
</code></div></pre>
<p><code>active-class</code>:当<router-link>对应的路由匹配成功时,会自动给当前元素设置一个router-link-active的class,设置active-class可以修改默认的名称</p>
<ul>
<li>
<p>在进行高亮显示的导航菜单挥着底部tabbar时,会使用到该类</p>
</li>
<li>
<p>但是通常不会修改类的属性,会直接使用默认的router-link-active即可</p>
</li>
</ul>
<p><code>router-link-active</code>属性修改为<code>active</code></p>
<pre><div class="hljs"><code class="lang-html"><span class="hljs-tag"><<span class="hljs-name">router-link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/home"</span> <span class="hljs-attr">tag</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">replace</span> <span class="hljs-attr">active-class</span>=<span class="hljs-string">"active"</span>></span>首页<span class="hljs-tag"></<span class="hljs-name">router-link</span>></span>
</code></div></pre>
<h2><a id="5__67"></a>5 代码跳转路由</h2>
<pre><div class="hljs"><code class="lang-html"><span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"homeClick"</span>></span>首页<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
</code></div></pre>
<pre><div class="hljs"><code class="lang-html">methods: {
homeClick() {
// 通过代码的范式修改路径 vue-router
this.$router.push('/home')
console.log('homeClick');
}
}
</code></div></pre>
<h2><a id="6__83"></a>6 动态路由</h2>
<pre><div class="hljs"><code class="lang-html">{
path: '/user/:userId',
name: 'User',
component: User
}
</code></div></pre>
<p>子路由获取参数</p>
<pre><div class="hljs"><code class="lang-html"><span class="hljs-tag"><<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">h2</span>></span>我是用户界面<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>
<span class="hljs-tag"><<span class="hljs-name">p</span>></span>用户信息<span class="hljs-tag"></<span class="hljs-name">p</span>></span>
<span class="hljs-tag"><<span class="hljs-name">h2</span>></span>{{ userId }}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>
<span class="hljs-tag"><<span class="hljs-name">h2</span>></span>{{ $route.params.userId }}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">template</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="language-javascript">
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
<span class="hljs-attr">name</span>: <span class="hljs-string">"User"</span>,
<span class="hljs-attr">computed</span>: {
<span class="hljs-title function_">userId</span>(<span class="hljs-params"></span>) {
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">params</span>.<span class="hljs-property">userId</span>
}
}
}
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
</code></div></pre>
<h2><a id="7__118"></a>7 路由的懒加载</h2>
<ul>
<li>
<p>当导包构建应用时,javascript包会变得非常大,影响页面加载</p>
</li>
<li>
<p>如果我们能把不同路由的对应组件分割成不同的代码块,然后当路由被访问的时候才能加载对应的组件,这样就更高效了</p>
</li>
</ul>
<p>路由懒加载做了什么</p>
<ul>
<li>
<p>主要所用是将路由的对应组件打包成一个个的js代码块</p>
</li>
<li>
<p>只有在这个路由被访问到的时候,才加载对应的组件</p>
</li>
</ul>
<p><code>index.js</code></p>
<p>方式一:</p>
<pre><div class="hljs"><code class="lang-html">const Home = resolve => {
require.ensurre(['../components/Home.vue'],()=>{
resolve(require('../components/Home.vue'))
})
}
</code></div></pre>
<p>方式二:AMD写法</p>
<pre><div class="hljs"><code class="lang-html">const About = resolve => require(['../compontents/About.vue'], resolve);
</code></div></pre>
<p>方式三:在ES6中,我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割</p>
<pre><div class="hljs"><code class="lang-html">// 懒加载方法导入(一个懒加载对应一个js文件)
const Home = () => import('../components/Home')
</code></div></pre>
<h2><a id="8__155"></a>8 嵌套路由</h2>
<p>Home.vue</p>
<pre><div class="hljs"><code class="lang-html"><span class="hljs-tag"><<span class="hljs-name">router-link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/home/news"</span>></span>新闻<span class="hljs-tag"></<span class="hljs-name">router-link</span>></span>
<span class="hljs-tag"><<span class="hljs-name">router-link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/home/message"</span>></span>消息<span class="hljs-tag"></<span class="hljs-name">router-link</span>></span>
<span class="hljs-tag"><<span class="hljs-name">router-view</span>></span><span class="hljs-tag"></<span class="hljs-name">router-view</span>></span>
</code></div></pre>
<p>index.js</p>
<pre><div class="hljs"><code class="lang-js">{
<span class="hljs-attr">path</span>: <span class="hljs-string">'/home'</span>,
<span class="hljs-attr">name</span>: <span class="hljs-string">'Home'</span>,
<span class="hljs-attr">component</span>: <span class="hljs-title class_">Home</span>,
<span class="hljs-attr">children</span>: [
{
<span class="hljs-attr">path</span>: <span class="hljs-string">''</span>,
<span class="hljs-attr">redirect</span>: <span class="hljs-string">'/news'</span>
},
{
<span class="hljs-attr">path</span>: <span class="hljs-string">'news'</span>,
<span class="hljs-attr">component</span>: <span class="hljs-title class_">HomeNews</span>
},
{
<span class="hljs-attr">path</span>: <span class="hljs-string">'message'</span>,
<span class="hljs-attr">component</span>: <span class="hljs-title class_">HomeMessage</span>
},
]
},
</code></div></pre>
<h2><a id="9__191"></a>9 传递参数</h2>
<ul>
<li>
<p>params类型:/route/:id</p>
</li>
<li>
<p>query:类型 /router?id=123</p>
</li>
</ul>
<p><code>button</code>和<code>router-link</code>方法二选一</p>
<p>http://localhost:8080/profile?id=1&name=charles</p>
<pre><div class="hljs"><code class="lang-html"># router-link
<span class="hljs-tag"><<span class="hljs-name">router-link</span> <span class="hljs-attr">:to</span>=<span class="hljs-string">"{ path: '/profile',query:{id:'1',name:'charles'}}"</span>></span>个人资料<span class="hljs-tag"></<span class="hljs-name">router-link</span>></span>
# button
<span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"userClick"</span>></span>用户<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-tag"><<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"profileClick"</span>></span>个人资料<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-tag"><<span class="hljs-name">router-view</span>></span><span class="hljs-tag"></<span class="hljs-name">router-view</span>></span>
userClick() {
this.$router.push('/user/' + this.userId)
},
profileClick() {
this.$router.push({
path: '/profile',
query: {
id: 2,
name: 'tom'
}
})
}
</code></div></pre>
<p>profile.vue</p>
<pre><div class="hljs"><code class="lang-html"><span class="hljs-tag"><<span class="hljs-name">h2</span>></span>{{ $route.query.id }}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>
<span class="hljs-tag"><<span class="hljs-name">h2</span>></span>{{ $route.query.name }}<span class="hljs-tag"></<span class="hljs-name">h2</span>></span>
</code></div></pre>
<h2><a id="10__232"></a>10 导航守卫</h2>
<pre><div class="hljs"><code class="lang-html">// 前置守卫(guard)
router.beforeEach((to, from, next) => {
document.title = to.matched[0].meta.title
next()
})
// 后置钩子(hook)
router.afterEach((to,from)=>{
})
</code></div></pre>
<p>index.js</p>
<pre><div class="hljs"><code class="lang-html">{
path: '/about',
name: 'About',
meta: {
title: '关于'
},
component: About
},
</code></div></pre>
<p>About.vue</p>
<pre><div class="hljs"><code class="lang-js"><script>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
<span class="hljs-attr">name</span>: <span class="hljs-string">"Home"</span>,
<span class="hljs-title function_">created</span>(<span class="hljs-params"></span>) { <span class="hljs-comment">// 创建组件</span>
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'created'</span>);
<span class="hljs-comment">// document.title = '首页'</span>
<span class="hljs-variable language_">document</span>.<span class="hljs-property">title</span> = to.<span class="hljs-property">matched</span>[<span class="hljs-number">0</span>].<span class="hljs-property">meta</span>.<span class="hljs-property">title</span>
},
<span class="hljs-comment">// mounted() { // 挂载到dom</span>
<span class="hljs-comment">// console.log('mounted');</span>
<span class="hljs-comment">// },</span>
<span class="hljs-comment">// updated() { // 界面发生刷新</span>
<span class="hljs-comment">// console.log('updated');</span>
<span class="hljs-comment">// }</span>
}
</script>
</code></div></pre>
<h2><a id="11_keepalivevuerouter_280"></a>11 keep-alive遇见vue-router</h2>
<ul>
<li>keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染</li>
</ul>
<p>(1)include:字符串或正则表达式,只有匹配的组件会被缓存</p>
<p>(2)exclude:字符串或正则表达式,任何匹配的组件都不会被缓存</p>
<ul>
<li>router-view:也是一个组件,如果直接被包在<code>keep-alive</code>里面,所有路径匹配到的视图组件都会被缓存</li>
</ul>
<pre><div class="hljs"><code class="lang-html">// 这两个函数,只有该组件被保持了装填使用keep-alive时,才是有效的
activated() {
this.$router.push(this.path)
},
beforeRouteLeave(to, from, next) {
this.path = this.$route.path;
next()
}
</code></div></pre>
<pre><div class="hljs"><code class="lang-html"><span class="hljs-tag"><<span class="hljs-name">keep-alive</span>></span>
<span class="hljs-tag"><<span class="hljs-name">router-view</span>/></span>
<span class="hljs-tag"></<span class="hljs-name">keep-alive</span>></span>
</code></div></pre>
留言