Vue路由相关

110 阅读3分钟

前言

后端渲染 ------存在性能问题

Ajax前端渲染---------提高了性能但不支持前进后退

SPA:单页页面程序,在前后端分离的基础上增加了一层前端路由,整个网站只有一个页面,内容的变化通过局部更新同时支持前进后退。

SPA实现原理之一:基于URL地址的hash,也就是锚点(#),本质上是改变window.location的href(hyper reference )属性(hash的变化会导致浏览器记录访问历史的变化,但是hash的变化不会触发新的请求。)

改变hash的两种方式

location.hash = 'url'

history.pushState({},'','url')//可撤回的操作,栈结构显示栈顶。
history.replaceState({},'','url')//不可撤回

histort.back 等同于history.go(-1)

前端路由:监听根据不同的用户事件,显示不同的页面内容

本质:用户事件与事件处理函数之间的对应关系。

<conponent :is="name"></component>

name变化显示不同组件

location.hash,取得hash值

htistory模式与hash模式 ?

Vue-router基本使用

1.引入相关库文件

2.添加路由链接

    <router-link to="/user">user</router-link>
    <router-link to="/register">register</router-link>

router-link默认被渲染为a标签,可以使用tag属性渲染为其他标签。

history模式下,如果要禁用前进后退,在router-link中加一个replace属性即可

    <router-link to="home" replace>首页</router-link>

当router-link对应路由匹配成功时,会给元素设置加上一个router-link-active的class,设置active-class属性可以修改类默认的名称,也可以在路由里写linkActiveClass:'name',

如果想用代码实现路由

this.$router.push('/')
this.$router.replace('/')

to属性被渲染为href,to后的值会被渲染为#开头的hash值

3.添加路由填充位(路由占位符)

<router-view></router-view>

通过路由规则匹配到的组件,将会被渲染到占位符所在位置

4.定义路由组件(2中to对应的)

5.配置路由规则并创建路由实例

var router = new VueRouter({
            rou	tes:[
                {path:"/user",component:user},
                {path:"/register",component:register}
            ]
        });
 const vm = new Vue({
            el:"#app", 
            router,
        });

在项目中使用:

1.导入路由依赖并且使用Vue.use(VueRouter)

2.创建对象引入映射规则

3.在组件中挂载实例

router是大对象

route当前活跃路由

路由重定向

比起直接写component,可以修改hash值

不会出现hash为空却渲染了组件的问题。

routes:[
                {path:"/",redirect:"/user"},
                {path:"/user",component:user},
                {path:"/register",component:register}
            ]

嵌套路由

​ 父组件中路由模板+通过children属性配置子级路由

  <template id="register">
        <div>
            <h1>register</h1>
            <router-link to="/register/tab1">tab1</router-link>
            <router-link to="/register/tab2">tab2</router-link>
            <router-view></router-view>
        </div>
    </template>
var router = new VueRouter({
            routes:[
                {path:"/",redirect:"/user"},
                {path:"/user",component:user},
                {
                    path:"/register",
                    component:register,
                    children:[ 
                        {path:"tab1",component:tab1}, //子路由不需要/
                        {path:"tab2",component:tab2}
                    ]
                },
            ]
        });

路由组件传递参数

1.props布尔值

let r = new VueRouter({
            routes: [
                {path:"/",redirect:"/user"},
                {path: "/user/:id", component: user ,props:true}
            ]
        });
const user = {
            template: "#user",
            props:["id"]
        };

2.this.$route.params.name

router-index.js

[
{
    path: '/user/:userId',
    component: User
  }
]

user.vue

 <h1>{{this.$route.params.userId}}</h1>

把router-link用其他元素实现,通过绑定方法

userclick(){
	this.$router.push('/user/'+this.userid) 	
}
profileclick(){
	this.$router.push({
	path: '/profile',
	query: {
	name: abc
	}
	}) 	
}

3.query

Home组件:

<router-link :to="{path:'/profile',query:{name:'abc',age:20}}">档案</router-link>

Profile组件:

  <h2>{{this.$route.query}}</h2>

路由懒加载

const Home = ()=>import('../components/Home')

{
path:'/home',
component: Home
}

命名路由

<div id="app">
        <router-link :to="{name:'user',params:{id:1}}">user1</router-link>
        <router-link to="/user/2">user2</router-link>
        <router-link to="/user/3">user3</router-link>
        <router-link to="/register">register</router-link>
        <router-view></router-view>
    </div>
let r = new VueRouter({
            routes: [
                {path:"/",redirect:"/user"},
                {path: "/user/:id",name:"user",component: user },
                {path: "/register", component: register }
            ]
        });

页面导航两种方式

1.声明式导航:点击链接实现导航 如:a,router-link标签

2.编程式导航: js形式API实现,如:location.href

this.$router.push("/")//导航
this.$router.go(n)//n>0前进

<template id="user">
        <div>
            <p>user----{{$route.params.id}}</p>      
            <button @click = "toRegister">register</button>
        </div>
</template>
const user = {
            template: "#user",
            methods:{
                toRegister:function(){
                    this.$router.push("/register");
                }
                }
        };

导航守卫

meta :元数据,描述数据的数据

给路由加meta->tltle

router.beforeEach((to,from,next)=>{

document.title = to.matched[0].meta,title;

next();

})

前置钩子,需要调用next()

后置钩子不需要

路由独享的守卫

routes:[{
path:'/home',
component: Home,
beforEach: (to,from,next)=>{

}
}]

组件守卫

router.vuejs.org/zh/guide/ad…

keep-alive

是Vur内置的组件,可以使被包含的组件保留状态,或避免重新被渲染。

页面切换时实际上组件是反复创建销毁的。

<keep-alive>
<router-view/>
<keep-alive/>

当组件在 内被切换,它的 activated (被 keep-alive 缓存的组件激活时调用。)和 deactivated (被 keep-alive 缓存的组件停用时调用。)这两个生命周期钩子函数将会被对应执行。

保存路径,

beforeRouteLeave

储存当时的路径,activated中压回去

keep-alive 两个属性

include

exclude

路径起别名

在build-webpack.base.conf.js中

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src'),
      'assets': resolve('src/assets')//别名
    }
  },

import里使用时直接使用

src中使用需要在前面加上~

路由练习:封装一个tabbar组件