图片显示不出来见相应的补充中
路由
路由:通过互联网把信息从原地址传输到目的地址的活动 — 维基百科
前端渲染、后端渲染
早期 整个HTML页面是由服务器来渲染的
jsp: java server page
图见:路由 补充图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8aD7RHmr-1606716128749)(C:\Users\ZR\AppData\Roaming\Typora\typora-user-images\image-20201123141139554.png)]
前端返回url ,返回给服务器,服务器中保存html +css+ java java代码作用是从数据库中读取数据并将它动态的放在页面中,然后返回给前端
后端路由,后端处理URL和页面之间的映射关系
优点:
前端请求不同路径,交于服务器进行处理,服务器渲染好整个页面,并且将页面返回前端
不需要单独加载任何的js 和css 可以直接交给浏览器展示,有利于SEO的优化
后端路由缺点:
整个页面由后端人员来编写维护的
不利于前端人员编码
通常情况下HTML代码和数据以及队形的逻辑混在一起,编写和维护非常糟糕
前后端分离阶段AJAX
后端只负责API提供数据,不负责提供任何阶段的内容
前端通过AJAX获取数据,并且可以通过通过JS将数据渲染到页面中
前后端责任清晰
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6TPyJKQR-1606716128752)(C:\Users\ZR\AppData\Roaming\Typora\typora-user-images\image-20201123142743216.png)]
单页面富应用阶段
SPA:单页面富应用
整个网页只有一个HTML页面
在前后端分离的基础上添加了一层前端路由
改变URL页面不进行整体刷新
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zRNRnksX-1606716128754)(C:\Users\ZR\AppData\Roaming\Typora\typora-user-images\image-20201123143642954.png)]
前端路由中url 和组件的关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D7UJEWKs-1606716128755)(C:\Users\ZR\AppData\Roaming\Typora\typora-user-images\image-20201123143712400.png)]
改变页面url但是不刷新
通过location.hash = ‘ ’
通过history.pushiState({},’’,‘home’) 可以通过history.back()返回 ,相当于进栈和出栈的操作
history.replaceState({}, ’ ', ‘home’) 不可以进行前进和回退
history.go(-1) = history.back()
history.forword() = history.go(1)
vue-router的步骤
1、创建路由组件
2、配置路由映射:组件和路径映射关系
3、使用路由:通过 和
默认使用的是hash的模式 ,可以进行更改
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>//最终会解释为a标签
<router-view></router-view>//会根据当前路径展示
import Vue from 'vue'
import Router from 'vue-router'
import Home from '../components/Home'
import About from '../components/About'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '',
redirect: Home //路由的重定向,更改默认模式
}
],
mode: 'history' //更改默认模式,从hash 改为 history.pushState()
})
router-link属性
默认为a标签
可以重定义 通过 tag 设置渲染结果
通过replace ,设置不可以 前进后退 只能点击
<router-link to="/home" tag="button" replace>首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-view></router-view>
设置点击效果
默认的 router-link-active
通过设置active-class 修改默认名称,其他没添加的属性按照 router-link-active设置
还可在在路由中设置点击效果
<template>
<div id="app">
<router-link to="/home" tag="button" replace active-class="active">首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
.router-link-active{
color: blue;
}
.active{
color: red;
}
</style>
import Vue from 'vue'
import Router from 'vue-router'
import Home from '../components/Home'
import About from '../components/About'
Vue.use(Router)
export default new Router({
routes: [
{
path: '',
redirect: Home
}
],
mode: 'history',
linkActiveClass: 'active' //在路由中设置
})
通过代码实现路由跳转
$router 是创建的路由整体对象
<template>
<div id="app">
<!--<router-link to="/home" tag="button" replace active-class="active">首页</router-link>-->
<!--<router-link to="/about" tag="button" replace>关于</router-link>-->
<!--<router-view></router-view>-->
<button @click="homeclick">home</button>
<button @click="aboutclick">about</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
homeclick(){
// this.$router.push('/home')
this.$router.replace('/home')
},
aboutclick(){
// this.$router.push('/about')
this.$router.replace('/about')
}
}
}
</script>
<style>
.router-link-active{
color: blue;
}
.active{
color: red;
}
</style>
动态路由
动态路由
通过v-bind 动态加载
{
path: '/user/:userId',
component: User
}
<router-link to="/home" tag="button" replace active-class="active">首页</router-link>
<router-link to="/about" tag="button" replace>关于</router-link>
<router-link :to="'/user/'+userId" tag="button" replace>用户</router-link>
<router-view></router-view>
获取动态路由的动态值
$route 是获取当前活跃的路由
<template>
<div>
<h2>我是用户界面</h2>
<P>我是用户界面内容,哈哈</P>
<h2> {{userId}}</h2>
<h2> {{$route.params.userId}}</h2>
</div>
</template>
<script>
export default {
name: "User",
computed:{
userId(){
return this.$route.params.userId;
}
}
}
</script>
<style scoped>
</style>
路由的懒加载
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FA6sZWU8-1606716128757)(C:\Users\ZR\Desktop\VUE\image-20201123162951672.png)]
懒加载:用到时候在加载
当打包创建应用时候,js包会变得非常大,影响页面加载
如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,更加高效
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WCEbOHs2-1606716128758)(C:\Users\ZR\Desktop\VUE\image-20201123163225496.png)]
路由懒加载的方法
1、结合Vue的异步组件和webpack的代码分析
const Home = resolve => {
require.ensure(['../components/Home.vue'],()=>{
resolve(require('../components/Home.vue'))
})
}
2、AMD写法
const About = resolve => require(['../components/About.vue'],resolve);
3、ES6
const Home = ()=>import('../components/Home');
嵌套路由
在子路由中不要添加 “/” 在第一层路由中必须加 “/"
import Vue from 'vue'
import Router from 'vue-router'
// import Home from '../components/Home'
// import About from '../components/About'
// import User from '../components/User'
const Home = ()=>import('../components/Home');
const About = ()=>import('../components/About');
const User = ()=>import('../components/User');
const news = ()=>import('../components/HomeNews');
const message = ()=>import('../components/VueMessage');
Vue.use(Router)
export default new Router({
routes: [
{
path: '',
redirect: 'home'
},
{
path: '/home',
name: 'Home',
component: Home,
children: [
{
path: '',
redirect: 'news'
},
{
path: 'news',
component: news
},
{
path: 'message',
component: message
}
]
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/user/:userId',
component: User
}
],
mode: 'history',
linkActiveClass: 'active'
})
传递参数的方法
1、params 的方法
和动态路由相同
2、query 方法
URL: 协议://主机:端口/路径?查询
<router-link :to="{path: '/profile', query:{name:'zr',age:'12'}}" tag="button" replace>档案</router-link>
组件
<template>
<div>
<h2>
我是档案
{{$route.query.name}}
{{$route.query.age}}
</h2>
</div>
</template>
路由
{
path:'/profile',
component: profile
}
JS代码实现
profile(){
this.$router.push({
path: '/profile',
query: {
name: 'ze',
age: '123'
}
}
)
}
所有的组件继承VUE原型
所以在全部组件中可以使用全局组件router、route
Vue的原型属性$router 始终指向,设置的对象路由router
Vue的原型属性$route 始终指向当前活跃的路由
导航守卫
进行路由监听,并可以进行操作
动态修改标题
前置守卫(guard)
通过beforeach((to,from, next)=>{} )方法
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。只有调用该方法后,才能进入下一钩子。
import Vue from 'vue'
import Router from 'vue-router'
// import Home from '../components/Home'
// import About from '../components/About'
// import User from '../components/User'
const Home = ()=>import('../components/Home');
const About = ()=>import('../components/About');
const User = ()=>import('../components/User');
const news = ()=>import('../components/HomeNews');
const message = ()=>import('../components/VueMessage');
const profile = ()=>import('../components/Profile');
Vue.use(Router)
const router = new Router({
routes: [
{
path: '',
redirect: 'home'
},
{
path: '/home',
name: 'Home',
component: Home,
children: [
{
path: '',
redirect: 'news'
},
{
path: 'news',
name: 'news',
component: news
},
{
path: 'message',
name: 'message',
component: message
}
]
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/user/:userId',
name: 'user',
component: User
},
{
path:'/profile',
name: 'profile',
component: profile
}
],
mode: 'history',
linkActiveClass: 'active',
}
)
router.beforeEach((to,from,next)=>{
document.title = to.matched[0].name;
console.log(to);
next();
})
export default router;
后置钩子(hook)
router.afterEach((to,from) => {
console.log("------")
})
路由独享守卫
{
path: '/about',
name: 'About',
component: About,
beforeEnter: (to,from,next) =>{
console.log('beforeAbout')
next()
}
},
{
path: '/user/:userId',
name: 'user',
component: User,
beforeEnter: (to,from,next) =>{
console.log('befor')
next()
}
},
组件内守卫
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dzc8UvVN-1606716128759)(C:\Users\ZR\Desktop\VUE\image-20201123213652909.png)]
keep-alive 遇见vue-router
router-view 也是一个组件,包在keep-alive中,所有路径匹配到的视图组件将被缓存
keep-alive 是vue的内置组件,可以被包含组件的保留状态,避免重新渲染
保留上一次离开的状态,在home组件中,有新闻和消息,为了保存离开后的选择,需要记住离开时候的状态
只有使用 才能使用 activated() /deactivated()
<template>
<div>
<h2>我是首页</h2>
<P>我是首页内容,哈哈</P>
<router-link to="/home/news">新闻</router-link>
<router-link to="/home/message">消息</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "Home",
path: "home/news",
created(){
console.log("Homecreat");
},
destroyed(){
console.log("HomeDES");
},
activated(){
this.$router.push(this.path);
},
//组件路由守卫,记录上一次离开的状态
beforeRouteLeave(to,from,next){
console.log(this.$route.path);
this.path = this.$route.path;
next()
}
}
</script>
<style scoped>
</style>
keep-alive属性
exclude 排除在外 include 包含在内
exclude 等使用的是组件里面的name属性
<keep-alive exclude="Profile,User">
<router-view></router-view>
</keep-alive>
</template>
<script>
export default {
name: "Home",
path: "home/news",
created(){
console.log("Homecreat");
},
destroyed(){
console.log("HomeDES");
},
activated(){
this.$router.push(this.path);
},
//组件路由守卫,记录上一次离开的状态
beforeRouteLeave(to,from,next){
console.log(this.$route.path);
this.path = this.$route.path;
next()
}
}
</script>
<style scoped>
</style>
keep-alive属性
exclude 排除在外 include 包含在内
exclude 等使用的是组件里面的name属性
<keep-alive exclude="Profile,User">
<router-view></router-view>
</keep-alive>