一个简单的Vue Router 实现原理

Vue Router 实现原理

Vue Router使用步骤

基础路由

接下来我会通过代码的形式为大家展现路由的基本用法

  1. 创建router对象,router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
// 路由组件
import index from '@/views/index'
// 组成插件
Vue.use(VueRouter)
// 路由规则
const routes = [
    {
   
        name: 'index',
        path: '/',
        component: index
    }
]
// 路由对象
const router = new VueRouter({
   
    routes
})
export default router
  1. 注册注册router对象,在main.js文件内操作
import router from './router'
new Vue({
   
render: h => h(App),
router
}).$mount('#app')
  1. 创建路由占位, 在需要用到路由的文件中,例如App.vue文件

<router-view></router-view>

  1. 最后一步创建链接
<router-link to="./">首页</router-link>
<router-link :to="{name: 'index'}">首页</router-link>

动态路由

<template>
    <div>
        // 方式一: 通过路由规则获取的数据
        通过当前路由规则匹配获取: {
   {
   $route.params.id}}

        // 方式二: 不仅可以通过路由,还有通过父组件传递(推荐)
        通过开启 props 获取: {
   {
   id}}
    </div>
</template>
<script>
export default {
   
    name: 'Detail',
    props: ['id']
}
</script>
const routes = [
    {
   
        name: 'Detail',
        path: '/detail/:id', // :id是占位符,传入对应的id,
        // 开启props会把url中的参数传递给组件,在组件内通过props来接收url参数
        props: true,
        // 路由懒加载,当需要访问该路由时加载组件
        // webpackChunkName 这个参数在我 前端模块打包工具Webpack中有介绍(魔法注释,自定义打包名)
        component: () => import(/* webpackChunkName: "detail" */ '../views/Detail.vue')
    }
]

嵌套路由

const routes = [
    {
        name: 'Login',
        path: '/login',
        component: () => import('@/views/Login.vue')
    },
    // 嵌套路由
    {
        path: '/',
        component: () => import('@/components/Layout.vue'), // 公共组件
        children: [
            {
                name: 'index',
                path: '', // 如果为空则访问父路径('/')时会默认将父组件合并加载该组件
                component: () => import('@/views/Index.vue'), // 跟上边公共组件合并
            },
            {
                name: 'detail',
                path: 'detail/:id', // 相对路径
                props: true,
                component: () => import('@/view/Detail.vue'), // 跟上边公共组件合并
            }
        ]
    }
]

编程式导航

  • 跳转路由但不记录历史
    this.$router.replace('/login')

  • 会记录历史跳转
    this.$router.push('/')

  • 会记录历史跳转切传递参数id为1
    this.$router.push({name: 'Detail', params: { id: 1 }})

  • 后退到上上一次页面,后退2次
    this.$router.go(-2)

Hash模式和History模式

表现形式区别

  • Hash模式
    https://xuanhe.com/#/detail?age=18

  • History模式
    https://xuanhe.com/detail/18

原理的区别

  • Hash模式是基于锚点,以及onhashchange事件,通过锚点的值作为路由地址,当地址发生变化后,发生onhashchange事件
  • History模式是基于HTML5中的History API
    • history.pushState() 不会向服务端发送请求,只会改变浏览器地址,并且将地址记录在历史记录中
    • history.replaceState() 同上,但是不会保存记录
    • 监听popstate事件监听浏览器的变化,但是调用history.pushState()和history.replaceState()不会触发该事件,只有在点击浏览器的回退按钮(或者在Javascript代码中调用history.back()或者history.forward()方法)才会出发

关于popstate的用法详情 popstate

注意: History模式需要服务器的支持

  • 单页应用中,服务端不存在的地址会返回找不到该页面(刷新页面的操作会向服务器发送请求)

  • 在服务器端要配置除了静态资源外都返回单页应用的index.html

  • node中使用一个插件处理history模式

connect-history-api-fallback

  • nginx中配置
server {
        listen       80;  # 端口号
        server_name  localhost; # 域名(一般是线上地址)

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html; # 根目录
            index  index.html ind
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值