vue路由详解

自己看 vue 文档,难免有些地方不懂,自己整理一下,主要是 vue-router 具体实现的操作步骤。

 

安装

直接下载 /CDN

https://unpkg.com/vue-router/dist/vue-router.js

Unpkg.com 提供了基于 NPM 的 CDN 链接。上面的链接会一直指向在 NPM 发布的最新版本。你也可以像 https://unpkg.com/vue-router@2.0.0/dist/vue-router.js 这样指定 版本号 或者 Tag。

在 Vue 后面加载 vue-router,它会自动安装的:

<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>

NPM

npm install vue-router

如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

如果使用全局的 script 标签,则无须如此(手动安装)。

#基础

开始

HTML:

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 to 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 &lt;a&gt; 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<router-view></router-view>
</div>

<router-view> 显示的当前路由的内容

<router-link to="/foo"> 实现路由的跳转

JavaScript:

// 0. 如果使用模块化机制编程,導入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)

// 1. 定义(路由)组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. 定义路由
// 每个路由应该映射一个组件。 其中 "component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]

// 3. 创建 router 实例,然后传 routes 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
routes // (缩写)相当于 routes: routes
})

// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
router
}).$mount('#app')

// 现在,应用已经启动了!

当 <router-link> 对应的路由匹配成功,将自动设置 class 属性值 .router-link-active

步骤:

1. 在 main.js 中引入 vue-router

import Vue from 'vue'
import VueRouter from 'vue-router'

2. 在 main.js 中使用这个 router 插件

Vue.use(VueRouter)

3. 生成这个 router 实例

export default new Router(){
    routes:[
        {
            path:'/',
            name:'home',
            component:Home
        },{
            path:'/list',
            name:'list',
            component:List
        }
    ]
}

4. 在 index.js 中把路由实例传递给 Vue 根组件

import router from './router'

new Vue({
el:'#app',
router,
template:'<APP/>',
components:{ APP }
})

静态路由

静态配置的 ---> import ....

固定路径路由的配置

{
    path:'/',
    name:'home',
    component:Home
},{
    path:'/list',
    name:'list',
    component:List
}

动态路由匹配

只有动态路由可以做到分页的效果

//localhost:8080/#/list/2 index,js

{
    path:'/list/:id',
    name:'list',
    component:List
}

list.vue

<template>
    <div>{{title}}</div>
</template>

<script>

<span class="hljs-title function_">data</span>(<span class="hljs-params"></span>){
    <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">title</span>:<span class="hljs-string">""</span>
    }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span>{
    <span class="hljs-title function_">mounted</span>(<span class="hljs-params"></span>){
        <span class="hljs-keyword">if</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">params</span>.<span class="hljs-property">id</span> == <span class="hljs-number">1</span>){
            <span class="hljs-comment">//请求第一页数据</span>
            <span class="hljs-variable language_">this</span>.<span class="hljs-property">title</span>=<span class="hljs-string">"第一页"</span>
        }
        <span class="hljs-keyword">if</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">params</span>.<span class="hljs-property">id</span> == <span class="hljs-number">2</span>){
            <span class="hljs-comment">//请求第二页数据</span>
            <span class="hljs-variable language_">this</span>.<span class="hljs-property">title</span>=<span class="hljs-string">"第二页"</span>
        }
    }
}

</script>

接收多个个参数

index.js

{
        path:'/list/:id/name/:name',
        name:'list',
        component:List
    }

list.vue

<template>
    <div>{{title}}{{name}}</div>
</template>

<script>

<span class="hljs-title function_">data</span>(<span class="hljs-params"></span>){
    <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">title</span>:<span class="hljs-string">""</span>,
        <span class="hljs-attr">name</span>:<span class="hljs-string">""</span>
    }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span>{
    <span class="hljs-title function_">mounted</span>(<span class="hljs-params"></span>){
        <span class="hljs-comment">//结构赋值写法</span>
        <span class="hljs-keyword">const</span> {name,id} = <span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">params</span>;
        <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = name;
        
        <span class="hljs-comment">//this.name = this.$route.params.name;</span>
        <span class="hljs-keyword">if</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">params</span>.<span class="hljs-property">id</span> == <span class="hljs-number">1</span>){
            <span class="hljs-comment">//请求第一页数据</span>
            <span class="hljs-variable language_">this</span>.<span class="hljs-property">title</span>=<span class="hljs-string">"第一页"</span>
        }
        <span class="hljs-keyword">if</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">$route</span>.<span class="hljs-property">params</span>.<span class="hljs-property">id</span> == <span class="hljs-number">2</span>){
            <span class="hljs-comment">//请求第二页数据</span>
            <span class="hljs-variable language_">this</span>.<span class="hljs-property">title</span>=<span class="hljs-string">"第二页"</span>
        }
    }
}

</script>

传递不同参数 显示不同数据

项目应用:详情页

watch 响应路由参数的变化

监听路由的变化

watch:{
    '$route'(to,from){
        this.name = to.params.name;
    }
}

在 2.2 中引入守卫( beforeRouteUpdate)

守卫 --> 钩子函数

beforeRouteUpdate (to, from, next) {
    this.name = to.params.name;
    next();// 走到下一个钩子
}

嵌套路由

头部左侧不变只有内容区改变 这样的需求可以用嵌套路由来做

{
        path:'/list',
        name:'list',
        component:List,
        childeren:[{
            path:'a',
            component:A
        }]
    }

再引入一个 A 组件 A.vue

在 list.vue 组件中通过,<router-view> 显示 A 组件的内容

在一个非 app 组件里面写 <router-view> 显示的是当前路由下子组件的内容

编程式的导航

除了 <router-link> 来创建 a 标签来定义导航链接,还可以借助 router 的实例方法

router.push(location,onCompelte?,onAbort?)

在 Vue 实例内部,可以通过 $route 访问路由实例,因此你可以调用 this.$route.push

想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

当你点击 <route-link> 时,这个方法会在内部调用,所以说,

点击 <route-link:to="..."> ---> 声明式

等同于

调用 router.push(...) ---> 编程式

可以在 Header 组件中跳转到 list 中

export defalut{
    methods:{
        handleClick(){
            this.$router.push({
                name:'list'
        })
    }
}

}

可以在 Header 组件中跳转到 list/123 中

export defalut{
    methods:{
        handleClick(){
            this.$router.push({
                // 一种方式
                //path:'/list/123',
            <span class="hljs-comment">//2种方式</span>
            <span class="hljs-attr">name</span>:<span class="hljs-string">'list'</span>
            <span class="hljs-attr">params</span>:{
                <span class="hljs-attr">id</span>:<span class="hljs-number">123</span>
            }
        })
    }
}

}

使用 router.push 或者 router.replace 里面都不能让 path 和 params 同时存在

// 字符串

router.push('home');

// 对象

router.push({path:'home'})

// 命名的路由

router.push({name:'user',params:{userId:123}})

// 带查询参数,变成 /register?plan=private
router.push({path:'register',query:{plan:'private'}})

router.replace

和 router.push 唯一的不同就是,不会向 history 添加新纪录,而是替换掉当前的 history 记录 不能返回

router.go

命名路由

定义名字跳转

命名视图

<router-view></router-view>
<router-view name="a"></router-view>
<router-view name="b"></router-view>

var app = new VueRouter({
routers:[{
path:'/',
componens:{
defaults:Foo,
a:Bar,
b:Baz
}
}]

})

重定向和别名

访问 /abc 重定向到 / 根路径

{
    path:'/abc',
    redirect:'/'
}

访问 /bieming 实际上还是访问的根路径

{
    path:'/',
    name:'home',
    component:Home,
    alias:'/bieming'
}

路由组件传参

解耦

动态路由传 id

{
        path:'/list/:id',
        name:'list',
        component:List,
        props:true
    }

在 list.vue 中

可以直接通过 props['id'] 获取数据

<template>
    <div>{{id}}</div>
</template>

<script>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span>{
   props[<span class="hljs-string">'id'</span>]
}

</script>

对象模式

props:{name:"dell"}

一般是写死的字符串静态数据

函数模式

index.js

{
        path:'/list/:id',
        name:'list',
        component:List,
        props : (route)=>({
            query:route.query.q
            id:route.params.id
        })
    }

list.vue

<template>
    <div>{{query}}</div>
    <div>{{id}}</div>
</template>

<script>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span>{
   props[<span class="hljs-string">'query'</span>,<span class="hljs-string">'id'</span>]
}

</script>

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1rr2npw3kickj