路由
通过互联网将一个信息从源地址传输到目的地址
什么是前端渲染,什么是后端渲染
后端渲染:jsp:java server page
后端路由:后端处理URL和页面之间的映射关系
前后端分离:后端只负责提供数据,不负责任何内容
前端渲染:浏览器中显示的网页中的大部分内容,都是由前端写的js代码在浏览器中执行,最终渲染出来的网页
改变路径页面不刷新:URL的hash
location.hash=‘aaa’
history.pushState({},’’,‘about’) 入栈
history.back 出栈
history.back 等价于 history.go(-1)
history.forward 等价于 history.go(1)
history.replaceState({},’’,‘about’) 替换,不能返回
vue-router
步骤一:安装vue-router
npm install vue-router --save
步骤二:在模块化工程中使用它(因为是一个插件,所以可以通过Vue.use()来安装路由功能
第一步:导入路由对象,并且调用Vue.use(VueRouter)
第二步:创建路由实例,并且传入路由映射配置
第三步:在Vue实例中挂载创建的路由实例
//在router文件下的index.js中配置路由相关信息
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
//1、通过Vue.use(插件),安装插件
Vue.use(VueRouter)
//2、创建VueRouter对象
const routes=[
]
const router=new VueRouter({
//配置路由和组件之间的映射关系
routes
})
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
//3、将router对象传入到vue实例中
export default router
//再在main.js中接受router
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
使用vue-router步骤
第一步:创建路由组件
第二步:配置路由映射,组件和路径映射关系
第三步:使用路由:通过(被渲染成a标签)和(占位)
的其他属性
1. tag:指定之后渲染成什么组件
2. replace:不会留下history记录指定replace的情况下,后退键不能返回到上一个页面中
3. active-class:当对应的路由匹配成功时,会给当前元素设置一个router-link-active的class,设置active-class可以修改默认的名称
<div id="app">
<router-link to="/login" tag="button" replace active-class="active">登录</router-link>
<router-view></router-view>
</div>
//当比较多时,可以在router下面的index.js中修改active-class
const router = new VueRouter({
linkActiveClass: "active",
});
//第一步:创建路由组件components下面创建login.vue
<template>
<div>
<h2>登录</h2>
<p>我是登录,嘻嘻嘻</p>
</div>
</template>
<script>
export default {
name: "login"
};
</script>
<style scoped></style>
//第二步:配置路由映射,组件和路径映射关系,router文件下的index.js中配置路由相关信息
import Login from "../components/login.vue";
const routes = [
{
path: "/login",
component: Login
}
];
//第三步:使用路由:在App.vue中通过<router-link>(被渲染成a标签)和<router-view>(占位)
<div id="app">
<router-link to="/login">登录</router-link>
</div>
13:3 warning Delete `··` prettier/prettier
14:1 warning Delete `··` prettier/prettier
15:5 warning Delete `····` prettier/prettier
16:1 warning Replace `········` with `····` prettier/prettier
17:3 warning Delete `··` prettier/prettier
18:2 warning Insert `;`
//执行可以修复eslint配置的一些问题
npm run lint --fix
//去掉路径上的#
const router = new VueRouter({
mode: "history",
});
通过代码跳转路由
<button @click="loginClick">登录</button>
methods: {
loginClick() {
//通过代码方式修改路径vue-router
//this.$router.push("/login");
//replace无法返回
this.$router.replace("/login");
}
}
动态路由的使用
在某些情况下,一个页面的path路径可能是不确定的,这种path和Component的匹配关系,被称为动态路由
1、先在components中创建user.vue
2、现在router下面的index.js中配置
import User from "../components/user.vue";
{
path: "/user/:userid",
component: User
}
3、在要使用的页面(如App.vue)
<!-- <router-link to="/user/zhangshan">用户</router-link> -->
<router-link :to="'/user/'+userid">用户</router-link>
data(){
return{
userid:"lisi"
}
}
4、如果user.vue需要使用这个动态的id
<p>{{userId}}</p>
<p>{{$route.params.userid}}</p>
computed: {
userId(){
//这个userid是前面配置的,前面配置是什么就是什么
return this.$route.params.userid
}
},
路由的懒加载,使用时再加载
为什么需要懒加载
路由中通常会定义多个页面,这些页面通常情况放在一个js中,如果一次性从服务器请求下来可能需要花费一定的时间,也很容易出现卡顿
路由懒加载做了什么
主要作用就是将路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候,才加载对应的组件
{
path: "/register",
//使用时再引入
component: ()=>import("../components/register.vue")
},
或者(较方便管理)
const Login=()=>import("../components/login.vue")
const Register=()=>import("../components/register.vue")
const User=()=>import("../components/user.vue")
const routes = [{
path: "/",
//redirect重定向
redirect: "/login"
},
{
path: "/login",
component: Login
},
{
path: "/register",
component: Register
},
{
path: "/user/:userid",
component: User
}
];
默认路径
const routes = [{
path: "/",
//redirect重定向
redirect: "/login"
},
{
path: "/login",
component: Login
}
}
路由的嵌套使用
创建对应子组件,并且在路由映射中配置对应的子路由
在组件内部使用标签
1、user.vue(父)同级创建一个userdetial.vue(子)
2、在router下的index.js配置一下
{
path: "/user",
component: User,
children: [{
path: "detial",
component: UserDetial
}]
},
3、在user.vue(父)中
<router-link to="user/detial">用户详情</router-link>
<router-view></router-view>
传递参数的方式
传递参数主要有两种形式:params和query
params的类型
配置路由格式:/router/:id
传递的方式:在path后面跟上对应的值
传递后形成的路径:/router/123,/router/abc
query的类型
配置路由格式:/router,也就是普通配置
传递的方式:对象中使用query的key作为传递方式
传递后形成的路径:/router?id=123,/router?id=abc
URL
协议类型:[//服务器地址[:端口号]][/资源层级UNIX文件路径]文件名[?查询][#片段ID]
简化版:协议://主机:端口/路径?查询
scheme://host:port/path?query#fragment
query的类型
在App.vue中
//query中的数据被拼接到地址栏
<router-link :to="{path:'/login',query:{name:'lisi',age:18}}">登录</router-link>
或
<button @click="loginClick">登录</button>
loginClick() {
this.$router.push({
path:'/login',
query:{
name:'zhangsan',
age:18
}
})
}
在login.vue中取出query里的数据
<p>{{$route.query}}</p>
<p>{{$route.query.name}}</p>
<p>{{$route.query.age}}</p>
r
o
u
t
e
r
和
router和
r o u t e r 和 route的由来
所有的组件都继承自Vue的原型
$router就是main.js里面的router
$route永远指向当前活跃对象
vue-router导航守卫
主要目的:监听跳转
利用导航守卫动态修改标题
在router的index.js中
{
path: "/register/:userid",
component: Register,
//meta元数据
meta: {
title: "注册"
}
},
router.beforeEach((to, from, next) => {
//从from跳to
document.title = to.matched[0].meta.title,
//next()不能没有
next()
});
这些是全局守卫
//前置守卫(guard)
//跳转前调用
router.beforeEach((to, from, next) => {
//从from跳to
document.title = to.matched[0].meta.title,
//必须有next
next()
});
//后置钩子(hook)
//跳转后调用
router.afterEach((to,form)=>{
//不需要next()
})
除了这些,还有
路由独享守卫
{
path: "detial",
component: UserDetial,
beforeEnter: (to, from, next) => {
// ...
}
组件内守卫
vue-router-keep-active及其他问题
keep-alive是Vue内置的一个组件,可以把使被包含的组件保留状态,或避免重新渲染
它有两个非常重要的组件
include-字符串或正则表达式,只有匹配的组件会被缓存
exclude-字符串或正则表达式,任何匹配的组件都不会被缓存
//exclude="name"
<keep-alive exclude="register,login">
<router-view></router-view>
</keep-alive>
router-view也是一个组件,如果直接被包在keep-alive里面,所有路径匹配到的视图组件都会被缓存
keep-alive->activated/deactivated
保持状态,避免频繁销毁
在App.vue
<keep-alive>
<router-view></router-view>
</keep-alive>
在要保持的页面
activated() {
this.$router.push(this.path)
},
deactivated() {
},
beforeRouteLeave (to, from, next) {
this.path=this.$route.path;
next()
}