简易demo
// routes注册
import Vue from "vue";
// import VueRouter from "vue-router";
import VueRouter from "./vueRouter"; // 自定义路由 js
import Home from "../views/Home.vue";
Vue.use(VueRouter;
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js for this route
// which is lazy-loaded when the route is visited.
component: ( =>
import(/* webpackChunkName: "about" */ "../views/About.vue",
},
];
const router = new VueRouter({
mode: "history",
routes,
};
export default router;
// vueRouter
var _Vue = null
export default class VueRouter {
// 一、 install方法
static install(Vue {
// 1、判断插件是否注册
if (VueRouter.install.installed return
VueRouter.install.installed = true
// 2、将Vue构造函数记录到全局变量
_Vue = Vue
// 3、把创建Vue实例的时候传入的router对象注入到Vue实例上
// _Vue.prototype.$router = this.$options.router;
// 混入
_Vue.mixin({
beforeCreate( {
if (this.$options.router {
_Vue.prototype.$router = this.$options.router
this.$options.router.init( // ?
}
}
}
}
// 二、构造函数
constructor(options {
this.options = options
this.routeMap = {}
this.data = _Vue.observable({
current: '/'
}
}
init( {
this.createRouteMap(
this.initComponents(_Vue
this.initEvent(
}
// 三、createRouteMap
createRouteMap( {
// 遍历所有的路由规则,把路由规则解析成键值对,保存在routeMap中
this.options.routes.forEach(route => {
this.routeMap[route.path] = route.component
}
}
// 四、initComponents
initComponents(Vue {
Vue.component('router-link', {
props: {
to: String
},
// template: '<a :href="to"><slot></slot></a>'
render(h {
return h(
'a',
{
attrs: {
href: this.to
},
on: {
click: this.clickHandler
}
},
[this.$slots.default]
},
methods: {
clickHandler(e {
history.pushState({}, '', this.to // 修改地址栏 - 不会发送请求
this.$router.data.current = this.to // 重新加载响应的组件
e.preventDefault( // 阻止发送请求
}
}
}
const self = this
Vue.component('router-view', {
render(h {
let component = self.routeMap[self.data.current]
return h(component
}
}
}
// 五、返回按钮、前进按钮问题
initEvent( {
window.addEventListener('popstate', ( => {
this.data.current = window.location.pathname
}
}
}
Vue-Router传参方式
一、普通、动态路由传参方式
// 路由代码传参
import About from 'about'
// routes 配置
{
path: '/about/:id', // 动态路由
component: About,
props: true // ①布尔模式
}
{
path: '/about', // 普通路由
component: 'About',
props: { id: 19 } // ②对象模式
}
// 接收方式 props
props;['id'] 或者
props: {
id: { type: Number, default: 12}
}
// ③函数模式
routes:[
{
path: '/about',
component: About,
// props: route => ({id:route.query.id} // url='/about?id="89"' 或者
props: route => ({id: route.params.id} // url='/about/:id' => '/about/89'
}
]
二、动态路由:将给定匹配模式的路由映射到同一个组件,复用一个组件,相对与销毁后重建更高效。
-
要对同一个组件中参数变化做出响应的话,可以通过watch 侦听$route对象上的任意属性
watch: { $route: { immediate: true, handler(route { // 处理事件 对路由变化做出响应 } } }
或者使用导航守卫,beforeRouteUpdate,也可以取消导航
四、路由的匹配语法
routes: [ { path: '/list/:id(\\d+'}, {path: '/list/:name'} ]
可以重复的参数 匹配多个部分的路由,可以用 * 号和 +号将参数标记为重复
五、嵌套路由、命名路由
-
Params: 字符串路径、路径对象、命名的路由并加上参数、带查询参数、带hash
'/users/detail' { path: '/users/detail' } { name: 'detail', params: {id: '0'}} { path: '/users/detail', query: {id: '0'} }
替换当前位置 router.replace({path: '/users'} 或者router.push({path:'users', replace: true}; 导航时不会向history添加记录
声明式(
七、命名视图:
// 通过routes配置来完成
const routes = [{ path: '/home', redirect: '/'}]
// 重定向的目标也可以是一个命名的路由 redirect: { name: 'Details'}
// 一个方法动态返回重定向目标
const routes = [
{
path: '/home/:id',
redirect: to => {
return {path:'Details', query: { q: to.params.searchText}}
}
}
]
// 别名
alias: '/home'
九、路由组件传参 props、$route.query$route.params
对象模式 props: { id: '0' } 当props为静态的时候很有用
props: route => ({ query: route.query.id } props: route => ({ params: route.params.id}
-
对于命名视图的路由,必须为每个命名视图定义props配置
const routes = [{ path: '/home', components: { default: Home, sidebar: Sidebar}, props: { default: true, sidebar: true} }]
十、不同的历史模式
Hash模式:history: createWebHashHistory( SEO受影响
HTML5模式:history:createWbeHistory( 如果没有适当的服务器配置,就会404,需要在服务器上添加一个简单的回退路由
进阶-路由导航
-
每个守卫都接收两个__参数__:to\from\next(可选
返回值 ①false:取消当前导航、②一个路由地址:通过一个路由地址跳转到不同的地址,类似于router.push(可配置,当前的 导航被中断然后进行一个新的导航。
next可选参数
全局后置守卫:afterEach 不接受next函数也不会改变导航本身
路由独享守卫:在routes中配置
组件内的守卫 可用配置API:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
beforeRouteEnter:唯一可传递next回调守卫;解决不可访问this;
next()里的内容执行时机在组件mounted周期之前;
beforeRouteUpdate: 该组件复用时被调用
方式:全局、单个路由独享、组件