Appearance
Vue Router用法与基础
Vue Router基础回顾
当我们使用vue-cli创建项目的时候,选择项目特性时选择Router,会自动安装Vue Router插件并且生成Vue Router的基础代码结构。
- 创建路由视图(插件)
- 注册路由组件
- 创建路由对象
- 注册router对象,
<router-view/>
和<router-link>
完成模板配置
实现步骤
- 下载模板
- views视图文件夹中有几个和路由相关的vue文件
- router文件夹是路由模块
- main.js是项目入口文件
- App.vue主模板
- 在index.js中首先导入vue和vue-router,并且通过vue调用use方法注册路由组件
js
// 导入vue和vue-router
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
// 1. vue调用use方法注册路由组件
Vue.use(VueRouter)
Vue.use(VueRouter) Vue.use是用来注册插件的,它里面需要接收一个参数。
- 如果参数是函数的话,use内部会直接调用函数注册组件
- 如果传入的是对象的话,它会调用传入对象的install方法来注册插件。
- 注册路由规则,定义一个对象数组,对象就是我们对应的路由规则。路由组件对应路径,路径变化的时候会加载相应的组件。
- path:路由路径
- name:路由名称
- component:路径对应组件
js
const routes = [
{
path: '/',
name: 'Index',
component: Index
},
{
path: '/blog',
name: 'Blog',
...
}
...
]
- 创建路由对象,通过
new VueRouter
来创建一个router对象,创建的时候把路由规则传入,最后将路由对象导出。
js
const router = new VueRouter({
routes
})
export default router
- 在main.js中导入router对象,并在创建Vue实例的时候注册router对象
js
import Vue from 'vue'
import App from './App.vue'
// 导入router对象
import router from './router'
Vue.config.productionTip = false
new Vue({
// 注册 router 对象
router,
render: h => h(App)
}).$mount('#app')
这里传入router的作用:(这里可以通过打印new Vue那个vue实例在控制台中看到区别)
当我们创建vue实例的时候,配置router时它会给实例分别注册
$route
和$router
属性
$route
是路由规则$router
是VueRouter实例,路由对象,里面会提供一些和路由相关的方法(例如:router.push()、router.replace()、router.go()),和路由的相关信息(mode模式,currentRoute)
- hash模式:路径中用井号方式表示
- currentRoute : 当前路由规则(有时候我们无法获取
$route
,但是可以获取$router
,如果获取到了$router
就可以根据currentRoute获取当前路由规则)
- 在
App.vue
中会创建一个<router-view/>
的模板,这个<router-view/>
的作用是组件的占位符,当路径匹配到组件后会把一个组件加载进来,并且会替换<router-view/>
,并且通过<router-link>
创建一些链接
html
<template>
<div id="app">
<div>
<img src="@/assets/logo.png" alt="">
</div>
<div id="nav">
<!-- 通过router-link创建链接 -->
<router-link to="/">Index</router-link> |
<router-link to="/blog">Blog</router-link> |
<router-link to="/photo">Photo</router-link>
</div>
<!-- 通过router-view创建路由组件的占位 -->
<router-view/>
</div>
</template>
- 命令行输入
npm run serve
可以正常运行。
动态路由
- 下载模板
- 在router/index.js中,路由配置里,
:id
就是通过占位符匹配变化的位置,实现动态路由。
js
const routes = [
// 首页是固定的/,加载Index组件
{
path: '/',
name: 'Index',
// 固定路由直接加兹组件
component: Index
},
// 不同的详情页需要传id,后面的:id是占位符,将来在使用的时候要传入对象商品的id,这个就是动态路由
{
path: '/detail/:id',
name: 'Detail',
props: true,
// 使用路由懒加载,用户访问对应路由地址的时候才会下载对应的路由组件,如果不访问组件不会被加载,提高程序性能
component: () => import(/* webpackChunkName: "detail" */ '../views/Detail.vue')
}
]
- 组件如何接收参数
方式一:使用 $router
获取 params
这种方式不太好,因为当前组件强依赖于路由,使用的时候路由必须传递相应的参数。
html
<template>
<div>
<!-- 方式1: 通过当前路由规则,获取数据 -->
通过当前路由规则获取:{{ $route.params.id }}
</div>
</template>
方式二:配置props (推荐)
- 在router/index.js中配置开启props
js
// router/index.js
const routes = [
{
path: '/detail/:id',
name: 'Detail',
// 开启 props,会把 URL 中的参数传递给相应组件
// 在组件中通过 props 来接收 URL 参数,和父子组件传值的方式相同
props: true,
component: () => import(/* webpackChunkName: "detail" */ '../views/Detail.vue')
}
]
- 在子组件中使用id
html
<template>
<div>
<!-- 方式2:路由规则中开启 props 传参 -->
通过开启 props 获取:{{ id }}
</div>
</template>
<script>
export default {
name: 'Detail',
// 通过props获取id
props: ['id']
}
</script>
嵌套路由
当多个路由组件都有相同的内容,我们可以把相同的内容都提取到一个公共的组件中。
如果首页和详情页都有相同的Header和Footer,把相同的东西提取出来,做成一个Layout组件。其中变化的位置就用<router-view>
占位。
之后我们访问首页的时候,它会将首页和Layout合并输出。
- 下载模板
- 可以看到在components/Layout.vue文件中,加载的时候先加载Layout组件,然后加载首页的时候替换掉router-view。
html
<template>
<div>
<!--Header:图片-->
<div>
<img width="25%" src="@/assets/logo.png">
</div>
<!--中间不同的地方-->
<div>
<router-view></router-view>
</div>
<!--Footer-->
<div>
Footer
</div>
</div>
</template>
- views里面的Login.vue组件是不需要头和尾的,那如何配置路由呢?
js
const routes = [
// login是正常路由
{
name: 'login',
path: '/login',
component: Login
},
// 嵌套路由
{
// 访问/ 根目录的时候会先加载Layout
path: '/',
component: Layout,
children: [
{
name: 'index',
// children里的路径可以是先谷底路径也可以是绝对路径
path: '',
component: Index
},
{
name: 'detail',
// 相对路径,外部路径+里面路径 /detail/:id
path: 'detail/:id',
props: true,
component: () =>
// 动态加载,使用的时候再加载模块
import('@/views/Detail.vue')
}
]
}
]
编程式导航
之前页面跳转的时候,使用的是router-link生成超链接。登录页面是要点击按钮跳转首页,这里就用到编程式导航,$router.push方法。
- $router.push()
跳转路由,里面传参可以有两种路由方式
- 直接传跳转地址:this.$router.push('/'),
- 跳转路由名称:this.$router.push({ name: 'Home' })
添加参数
- 直接传完整跳转地址:this.$router.push('/detail/1'),
- 跳转路由名称+跳转参数:this.$router.push({ name: 'Detail', params: { id: 1 } })
- $router.replace()
replace方法和push方法都可以跳转到指定页面,参数内容也是一样的。
但是replace会替换跳转历史,会把上次的历史删除后替换掉。
- $router.go()
go方法可以指定跳转到历史中的某一次,可以是负数,表示后退
go(-1) 与 back()的效果是一样的,表示后退到上一次访问的页面
- 下载模板
- views/login.vue组件代码使用$router.push()
html
<template>
<div>
用户名:<input type="text" /><br />
密 码:<input type="password" /><br />
<button @click="push"> push </button>
</div>
</template>
<script>
export default {
name: 'Login',
methods: {
push () {
// 第一种方式是字符串,即跳转的路由地址
this.$router.push('/')
// 第二种方式是传对象,指定路由名称,这个name就是路由规则中命名的名字
// this.$router.push({ name: 'Home' })
}
}
}
- views/index.vue中$router.push的用法
html
<template>
<div class="home">
<div id="nav">
<router-link to="/">Index</router-link>
</div>
<button @click="replace"> replace </button>
<button @click="goDetail"> Detail </button>
</div>
</template>
<script>
export default {
name: 'Index',
methods: {
// replace方法和push方法都可以跳转到指定页面,参数内容也是一样的。
// replace不会记录本次历史,它会把当前历史改成/login
replace () {
this.$router.replace('/login')
},
// 这个使用push,并传递了参数,使用params传一个对象,键值就是路由参数
goDetail () {
this.$router.push({ name: 'Detail', params: { id: 1 } })
}
}
}
</script>
- views/Detail.vue中使用
html
<template>
<div>
路由参数:{{ id }}
<button @click="go"> go(-2) </button>
</div>
</template>
<script>
export default {
name: 'Detail',
props: ['id'],
methods: {
// go方法可以指定跳转到历史中的某一次,可以是负数,表示后退
// go(-1) 与 back()的效果是一样的,表示后退到上一次访问的页面
go () {
this.$router.go(-2)
}
}
}
</script>
- 命令行中执行npm run serve,可以感受跳转的不同。