也叫服务端渲染,是指当服务器获取到url后,通过一些后端代码在服务器中直接将对应的html页面渲染完毕后,再将页面返回给前端进行展示,这就叫做后端渲染。
优点:这种情况下渲染好的页面,不需要单独加载任何的js和css,可以交给浏览器展示,这样也有利于SEO的优化
缺点:后端人员编写维护任务太重,前端人员要编写页面还需要学习后端代码,而且这样做会HTML代码和数据以及对应的逻辑会混在一起,编写和维护都非常糟糕。
从上面可以知道,在后端,每一个url就对应了一个页面,而处理这种url与页面之间的映射关系的路由关系便是后端路由
当url发生改变时,浏览器便会向静态资源服务器请求html,css,js,然后再通过请求过来的js代码向API服务器请求数据
前后端分离就是把数据操作和显示分离出来。前端专注做数据显示,通过文字,图片或者图标等方式让数据形象直观的显示出来。后端专注做数据的操作。前端把数据发给后端,有后端对数据进行修改。
在浏览器中显示的大部分内容,都是由前端写的js代码在浏览器执行,最终渲染出来的页面。
单页面富应用页面,最主要的特点就是在前后端分离的基础上加了一层前端路由
网页会从一开始就下载所有资源,然后通过一些选项,通过改变url选择性的加载部分资源,而支持这种功能的技术,便是前端路由,前端路由也是管理url和页面的映射关系,而前端路由的核心便是改变url,而页面不会进行整体的刷新
可以在控制台通过 location.hash = ‘aaa’ 修改url的hash值
可以在控制台通过 history.pushState({} , ’ ’ , ‘aaa’ ) 修改url值,而且这个push其实是在做一个入栈和出栈的操作,在浏览器可以通过history.back()来回到上一个url,也可以通过前进后退来访问之前的url。
还有一个方法是 history.replaceState( { }, ‘ ‘, ‘aaaa’ ),同样能修改url而浏览器不刷新,但是用这种方法并不会有数据存储,而是直接替换之前的数据,所以这种方法修改的url不能前进后退
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u1p85S4t-1570600486821)(file:///C:\Users\轻狂书生\AppData\Local\Temp\msohtmlclip1\01\clip_image004.jpg)]
通过npm安装,也可以通过脚手架安装
通过npm安装时要注意,vue路由应该安装为运行时依赖,所以后面应该加 --save
在src/router下的index.js文件中配置,导入vue/vue-router,通过Vue.use(Router)进行插件的安装,接着new一个router实例,接着导出router实例,在main.js中进行导入,然后在vue实例中进行使用
导入要使用的组件,在router实例中配置routers属性,里面每一个路由都是一个对象,对象中有path:对应的url,component:对应的组件
在APP.vue中使用来设置路由选择项,渲染出来为一个标签,再通过设置组件显示出来的位置
具体代码如下:
Index.js:
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", //path用于设置url后面跟的东西
component:Home //component表示这个path对应的组件
},
{
path:"/about",
component:About
}
]
})
Main.js
import Vue from 'vue'
import App from './App'
import router from './router' //导入路由
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router, //使用路由
render: h => h(App)
})
App.js
<template>
<div id="app">
<router-link to="/home">首页</router-link>
<!-- 通过<router-link to="">设置对应的路由 -->
<router-link to="/about">关于</router-link>
<router-view></router-view>
<!-- 通过<router-view>设置组件显示的位置 -->
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
</style>
很简单,只需要在routes属性中再定义一个对象,对象中使用redirect重定向一下路径
{ //设置默认路径,当路径为空是,把路径重定向到另一个路径,这里是重定向到首页
path:"",
redirect:"/home" //redirect:重定向
}
这样当路径为空时,会自动转到home的路径
我们使用路由时,默认使用的是hash模式,这样的坏处是在url中会有一个#号,所以我们可以把模式设置为history,这样就没有#号了。
也很简单,只需要在router实例中设置一个mode属性为history即可
export default new Router({
routes,
mode:'history' //将路径模式设置为HTML5的history模式,这样就不会有#号了
})
记得加引号,没有就会报错
标签默认的话会被渲染成a标签,而tag这个属性的作用便是将渲染成其他标签
<template>
<div id="app">
<router-link to="/home" tag="button">首页</router-link>
<!-- 通过<router-link to="">设置对应的路由,渲染出来为一个a标签 -->
<router-link to="/about" tag="button">关于</router-link>
<router-view></router-view>
<!-- 通过<router-view>设置组件显示的位置 -->
</div>
</template>
可以看到,通过tag=”button”这个属性,属性被渲染成了一个button按钮。
当我们用mode=’history’属性将浏览器的url模式从hash变成history之后,每次更改url时,浏览器都是用pushState()方法来更改,这样的好处是有历史记录,用户可以通过前进后退来访问历史页面。但有些时候我们不想用户可以访问历史页面,这个时候就可以使用replace属性,用法很简单,直接在标签中添加一个replace属性就好了。
<router-link to="/home" tag="button" replace>首页</router-link>
这样用户在访问时就不能前进后退了
当我们的标签处于活跃状态时,浏览器会自动给它加上一个这个样式
<button class="router-link-exact-active router-link-active">关于button>
所以当需要在添加样式的时候,可以直接给router-link-active添加样式
如果我们想修改这个样式的名字,可以在router实例中有一个linkrouteractive属性,
可以通过这个属性修改名字
linkrouteractive:”active”
在上面我们说了设置路由之后可以通过的方式来修改路由
第二种修改路由的方法便是通过代码修改路由,在原来router-link的地方可以通过两个button来代替
router-link,然后给这两个按钮绑定一个点击事件,在事件中通过this.$router.push()来修改路由
<button @click="homeclick">主页button>
<button @click="aboutclick">主页button>
methods: {
homeclick(){
this.$router.push('/home') //通过代码的方式来修改router
},
aboutclick(){
this.$router.push('/about')
},
},
我们之前写的路由都是静态的已经写死的,而我们现在需要动态的来决定路由
同样的,我们需要先定义一个组件,然后将它导入,然后在routes里定义路由
{
path:"/User/:userid",
component:User
}
只不过这次我们在后面加上了 :userid ,这个变量便是我们要动态获取的值
接着我们在App.vue中使用router-link使用这个路由
<router-link :to="'/user/'+userid" tag="button">用户router-link>
可以看到,我们用v-bind指令绑定了to属性,然后在user后面加上了一个变量userid,
这个变量在下面的data中定义
export default {
name: 'App',
data() {
return {
userid:"zhangsan"
}
},
通过这种方式我们就能动态的获取到userid的值,从而实现动态的路由。
而要是想获取到url中的userid的值,我们需要通过$route.params.userid
<h2>{{ $route.params.userid }}h2>
要注意区别 r o u t e 和 route和 route和router
懒加载就是指用到时再加载
路由懒加载的写法:
const Home = () => import('../components/Home')
const About = () => import('../components/About')
const User = () => import('../components/User') //路由的懒加载方式写法
可以看到,先定义一个常量,然后后面用箭头函数的形式赋值给它一个import,import里跟上组件的路径,这样懒加载便写好了
首先,依旧是导入组件(记得使用懒加载的写法)
const HomeNews = () => import('../components/HomeNews')
const HomeMessage = () => import('../components/HomeMessage')
接着便是使用,而嵌套路由的使用是在需要嵌套的路由中,加入一个children属性,传入一个数组,在这个属性中使用我们的子路由,在我们的嵌套路由里一样可以使用默认值
{ //每一个路由都是一个对象
path:"/home", //path用于设置url后面跟的东西
component:Home, //component表示这个path对应的组件
children:[ //嵌套路由在要嵌套的路由里使用children属性,传入一个数组
{
path:'', //在子路由中,依旧可以设置默认值
component:HomeNews
},
{
path:'news', //在子路由里,前面不用写斜杠
component:HomeNews
},
{
path:'message',
component:HomeMessage
}
]
},
接着就是在我们嵌套的组件中使用被嵌套的组件了,注意to属性不要写错了
<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>
这样嵌套路由就写好了
首先在index.js中的routers中设置路由,在路径后面用冒号接收一个变量
{
path:"/User/:userid",
component:User
}
在APP.vue中的router-link中 通过v-bind绑定to属性,在后面加上变量用于传递
<router-link :to="'/user/'+userid" tag="button">用户router-link>
最后在User组件中通过$route.params.userid获取参数值
<template>
<div>
<h2>我是用户h2>
<p>我是内容,嘿嘿嘿p>
<h2>{{ $route.params.userid }}h2>
div>
template>
所谓query,就是url后面用?进行连接的数据
http://localhost:8081/profile?name=YoRHa&age=18&height=1.88
使用query时index.js中的routers配置正常写
{
path:"/profile",
component:Profile
}
但是App.vue中的router-link中依旧需要用v-bind绑定to,然后to的值改为一个对象,第一个path依旧为所前往的路径,第二个参数query也是一个对象便是我们要传的值
<router-link :to="{path:'/profile',query:{name:'YoRHa',age:'18',height:'1.88'}}" tag="button">档案router-link>
最后在Profile中我们便可以通过$route.query.name来使用传递的值了
r o u t e r : 为 V u e R o u t e r 实 例 , 想 要 导 航 到 不 同 u r l , 则 使 用 router:为VueRouter实例,想要导航到不同url,则使用 router:为VueRouter实例,想要导航到不同url,则使用router.push()方法
$route:为当前router跳转对象,里面可以获取name,path,query,params等
vue-router提供的导航守卫主要是用来监听路由的进入和离开的
①前置守卫 router.beforeEach((to,from,next)=>{next()}) //在跳转前回调
其中,to是指进入到哪个路由去,form指从哪个路由跳转过来,而next()是必须执行的函数,表示是否要展示你要看到的路由页面,调用该方法后,才能进入下一个钩子
所以当我们想在路由跳转的同时修改title时,我们可以这么做:
首先在每个router中定义title值
{
path:"/about",
component:About,
meta:{
title:"关于",
},
},
然后我们来设置导航守卫,这里是指当跳转发生时,将to页面的titlt值赋给document的title,next()是必须执行的,表示要展示我们要看到的页面
router.beforeEach((to,from,next)=>{
document.title = to.matched[0].meta.title
next()
})
Ps:注意,这里的router是我们自己定义的Router实例,通过脚手架安装默认好像是没有的
const router = new Router({
routes,
mode:'history' //将路径模式设置为HTML5的history模式,这样就不会有#号了
})
②后置钩子
router.afterEach((to,from)=>{}) //在跳转后回调,没有next()
以上的前置守卫和后置钩子,都是全局守卫
2.路由独享的守卫
beforeEnter((to,from,next)=>{}) 直接在路由中使用,参数使用和全局的一样
使用之后在进入之前进行调用
{
path:"/about",
component:About,
meta:{
title:“关于”,
},
beforeEnter: (to, from, next) => {
console.log(‘about beforeEnter’)
next()
}
},
3.组件内的守卫
①beforeRouteEnter((to,from,next)=>{})
②beforeRouteUpdata((to,from,next)=>{})
③befroeRouteLeave((to,from,next)=>{})
1.Keep-alive标签的作用是对组件进行一个缓存,使组件保持活着的状态,不会被销毁,正常的组件在路由跳转之后都会调用distroyed()生命周期钩子,在跳转回来之后再调用created()生命周期钩子。而使用keep-alive将Router-view包裹后,其中的组件在路由跳转后不会被销毁,会被缓存起来。
2.在使用keep-alive之后,可以使用两个函数,activated/deactivated,因为组件不会被销毁,所以相应的组件的状态变为了活跃和非活跃状态,当组件变为活跃时,会调用activated,变为不活跃时,会调用deactivated。这两个只有在使用了keep-alive时才有生效。
3.Keep-alive还有两个重要的属性:1.include 2.exclude
Include表示只有匹配的组件会被缓存
Exclude表示只有匹配的组件不会被缓存
这里的匹配可以是正则或者是组件中定义的name属性
4.关于在跳转后保持原来组件的点击路径:可以在befroeRouteLeave组件内守卫记录离开前的路径,然后通过activated修改路径
activated() {
this.$router.push(this.path) //当组件变为活跃状态时回调的函数,这里转变为离开前的路径
},
beforeRouteLeave (to, from, next) {
this.path = this.$route.path //组件内的守卫,记录了离开时的路径
next()
}
Keep-alive标签的作用是对组件进行一个缓存,使组件保持活着的状态,不会被销毁,正常的组件在路由跳转之后都会调用distroyed()生命周期钩子,在跳转回来之后再调用created()生命周期钩子。而使用keep-alive将Router-view包裹后,其中的组件在路由跳转后不会被销毁,会被缓存起来。
2.在使用keep-alive之后,可以使用两个函数,activated/deactivated,因为组件不会被销毁,所以相应的组件的状态变为了活跃和非活跃状态,当组件变为活跃时,会调用activated,变为不活跃时,会调用deactivated。这两个只有在使用了keep-alive时才有生效。
3.Keep-alive还有两个重要的属性:1.include 2.exclude
Include表示只有匹配的组件会被缓存
Exclude表示只有匹配的组件不会被缓存
这里的匹配可以是正则或者是组件中定义的name属性
4.关于在跳转后保持原来组件的点击路径:可以在befroeRouteLeave组件内守卫记录离开前的路径,然后通过activated修改路径
activated() {
this.$router.push(this.path) //当组件变为活跃状态时回调的函数,这里转变为离开前的路径
},
beforeRouteLeave (to, from, next) {
this.path = this.$route.path //组件内的守卫,记录了离开时的路径
next()
}