这里写自定义目录标题
嵌套路由编程式导航History 模式Hash模式Hash和history的区别history的使用history需要后台支持解说nginx文件夹
Vue Router实现原理过程
{
path:'/detail/:id',
name:'Detail',
// 非动态路由
//compontent:'details',
// 开启prop传参功能
props:true,
//实现懒加载 用户点击才进行加载
compontent = ()=>{'../views/Details.vue'}
}
// 获取方式
第一种 $route.params.id第二种通过props进行接收
export default{
name:'Detail',
props:['id'];
}
嵌套路由
使用场景 // layout.vue
Header
router view
footer
// index.vue 首页 // details.vue 详情页
文件结构
src
components 文件夹
layout.vue
views 文件夹
Details.vue
Index.vue
Login.vue
路由配置
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/Details.vue')
}
]
}
]
编程式导航
路由跳转
1)、this.$router.push('/');
2)、this.$router.push({name:'Home'})
3)、this.$router.replace('/login') //和push的区别不记录历史记录
4)、this.$router.push({name:'Detail',params:{id:1}})
5)、this.$router.go(-2) //退回2步
History 模式
通过history.pushState()方法改变地址栏监听popstate事件根据当前路由地址找到对应组建重新渲染
Hash模式
URL中#后面的内容作为路径地址监听hashchange事件根据当前路由地址找到对应的组建进行重新渲染
Hash和history的区别
不管那种模式 都是客户端的模式
Hash模式 # 基于锚点以及onhashchange事件History 需要服务端配合
history模式基于HTML5中的historyAPIhistory.oushState() IE10以后才支持 路径放生变化像服务器发生请求history.replaceState() 不会发生请求 只会在路由发生变化
history的使用
//router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path:'/',
name:'Home',
component:Home
},
{
path:'/about',
name:'About',
component:()=>import('./view/about.vue')
},
{
path:'*',
name:'404',
component:()=>import('./view/404.vue')
}
]
const router = new VueRouter({
mode:'history',
routes
})
export default router
//App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link>
<router-link to="/about">About</rout-link>
<rout-link to="/video">Video</router-link>
</div>
<router-view/>
</div>
</template>
history需要后台支持
node中需要配置
const app = express();
app.use(history())
*nginx服务配置
从官网下载nginx的压缩包把压缩包解压到c盘目录,打开命令行,切换到英文目录下进行启动修改配置文件
server{
listen:80; //监听端口号
server_name localhost; //服务器的域名
location / {
root html;
index index.html index.htm //回车所访问的文件
try_files $uri $uri/ /index.html; //$uri 当前请求的路径 $uri/ 请求文件夹下的默认文件
}
}
//启动
start nginx.exe
开启loglhost可查看是否成功启动 默认80端口号
//重启
nginx -s reload
//停止
nginx -s stop
解说nginx文件夹
html存放静态文件conf中可以配置nginx.conf进行配置
Vue Router实现原理过程
创建VueRouter的类
VueRouter
//属性
options //参数
data //记录当前地址 响应式对象 vue.observer
routeMap //将路由规则记录在里面
// 方法
Constructor(Options):VueRouter //初始化属性
_install(Vue):void //静态方法 构建插件机制
init():void //调用下面三个方法
initEvent():void //监听浏览器地址发生变化
createRouteMap():void // 初始化routeMap转化键值对
initComponents(Vue):void //创建routevue routlink组建
实现VueRouter-install
export defaule class VueRouter{
var _Vue;
static install(Vue){
//1、判断当前插件是否已经被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed=true
//2、把Vue构造器记录到全局变量
_Vue=Vue
//3、把创建Vue实例时候传入的router对象注入到Vue实例上
_Vue.mixin({
beforecreat(){
if(this.$option.router){ this.prototype.$router = this.$option.router;
//调用写好的init方法
this.$option.router.init();
}
})
}
constructor(options){
this.options=options;
this.routeMap={};
this.data=_Vue.observable({
current:"/"
})
}
createRouteMap(){
this.options.routes.filter(route=>{
this.routeMap[route.path] = route.comonpent
})
}
init(_Vue){
this.createRouteMap();
this.initComponent(_Vue);
this.initEvent(); //此内容在下面
}
//创建initComponent 创建router-link组建
initComponent(Vue){
Vue.component('router-link',{
props:{
to:String
},
template:'<a :href="to"><slot></slot></a>'
})
//实现 router-view 根据路由地址渲染对应的路由组建不进行请求后台只是前台进行路由切换 不刷新页面
let self = this;
Vue.compontent('router-view',{
render(h){
//当前的路由地址
let component = self.routeMap[self.data.current]
return component;
}
})
}
}
运行报错 原因是cli没有预编译解析以下是解决办法在根目录下创建vue.config.js进行配置
module.exports={
runtimeCompiler:true
}
使用render函数 如果你有疑问,为什么平时写单页面没有报错不需要写render,因为打包的过程中把component解析成render函数 预编译。
将router-link中的template直接用render来进行书写
render(h){
// h是虚拟dom
// a选择器/是标签名称,第二个参数 一些属性,attrs:{href:this.to} attrs代表dom的属性 第三个参数接受数组形式代表子元素插槽没有名称就是default 调用方法 this.$slots.default
return h('a',{
attrs:{
href:this.to
},
on:{
click:this.clickHandler
}
}
,[this.$slots.default]
})
},
methods:{
clickHandler(e){
//data,title,超链接跳转的地址
history.pushState({},'',this.to)
this.$router.data.current = this.to
e.preventDefault()
}
}
实现initEvent方法实现浏览器前进和后退的功能 触发popState当历史发生变化
initEvent(){
window.addEventListener('popstate',()=>{
this.data.current = window.localhost.pathname
})
}
别忘接在init中调用偶!