8.1.2 Vue Router原理实现

本文为拉勾网大前端高薪训练营第一期笔记


8.1.2 Vue Router原理实现

Vue router

初始化vue的时候选择router,会自动生成router相关代码

Vue.use(VueRouter)

use传参如果是函数,会调用函数注册组件,如果是对象的话会调用对象的install方法

import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
// 1. 注册路由插件
Vue.use(VueRouter)

// 路由规则
const routes = [
  {
    path: '/',
    name: 'Index',
    component: Index
  },
  {
    path: '/blog',
    name: 'Blog',
    // 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: "blog" */ '../views/Blog.vue')
  },
  {
    path: '/photo',
    name: 'Photo',
    // 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: "photo" */ '../views/Photo.vue')
  }
]
// 2. 创建 router 对象
const router = new VueRouter({
  routes
})

export default router

//template部分代码


//main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
  // 3. 注册 router 对象,这里注册的话Vue实例会增加$route和$router属性
	//$route包括路由参数 $router是VueRouter实例提供很多方法,常用push replace go
	//插件里经常拿不到$route,但是能拿到$router,currentRoute可以获取当前路由规则
  router,
  render: h => h(App)
}).$mount('#app')

动态路由

路由配置

const routes = [
  {
    path: '/',
    name: 'Index',
    component: Index
  },
  {
    path: '/blog',
    name: 'Blog',
    // 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: "blog" */ '../views/Blog.vue')
  },
  {
    path: '/photo',
    name: 'Photo',
    // 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: "photo" */ '../views/Photo.vue')
  }
]

两种方式获得id,推荐第二个,前面的配置开启props:true


嵌套路由

//layout.vue


//router/index.js
const routes = [
  {
    name: 'login',
    path: '/login',
    component: Login
  },
  // 嵌套路由
  {
    path: '/',
    component: Layout,
    children: [
      {
        name: 'index',
        path: '',
        component: Index
      },
      {
        name: 'detail',
        path: 'detail/:id',
        props: true,
        component: () => import('@/views/Detail.vue')
      }
    ]
  }
]

编程式导航




hash模式和history模式区别

  • Hash模式是基于锚点,以及onhashchange事件

  • History模式是基于HTML5中的History API

    • history.pushState() IE10以后才支持
    • history.replaceState()

    history模式如果后端不支持,会出现刷新页面找不到页面的express提醒

    后端express支持的写法

    const path = require('path')
    // 导入处理 history 模式的模块
    const history = require('connect-history-api-fallback')
    // 导入 express
    const express = require('express')
    
    const app = express()
    // 注册处理 history 模式的中间件
    app.use(history())
    // 处理静态资源的中间件,网站根目录 ../web
    app.use(express.static(path.join(__dirname, '../web')))
    
    // 开启服务器,端口是 3000
    app.listen(3000, () => {
      console.log('服务器开启,端口:3000')
    })
    

    静态文件后端nginx支持的方法

    location / {
    	root html;
    	index index.html index.htm;
    	try_files $uri $uri/ /index.html;
    }
    

Vue带编译器版本

会大10K左右,支持template,会把template编译成render函数

//vue.config.js
module.exports = {
	runtimeCompiler: true
}

如果不用带编译版本的

render(h){
    return h("a",{
        attrs:{
            href:this.to
        },
        on:{
            click:this.clickhander
        }
    },[this.$slots.default])
},
methods:{
    clickhander(e){
        history.pushState({},"",this.to)
        this.$router.data.current=this.to
        e.preventDefault()
    }
}

//用带编译器版本的写法 template:"<>"

你可能感兴趣的:(vue.js,vue.js)