丰台怎样做网站,网络舆情处置方案,合肥做网站的企业,山东免费网站制作Vue Router路由
1 路由基础
1.1 什么是路由
用Vue.js创建的项目是单页面应用#xff0c;如果想要在项目中模拟出来类似于页面跳转的效果#xff0c;就要使用路由。其实#xff0c;我们不能只从字面的意思来理解路由#xff0c;从字面上来看#xff0c;很容易把路由联想…Vue Router路由
1 路由基础
1.1 什么是路由
用Vue.js创建的项目是单页面应用如果想要在项目中模拟出来类似于页面跳转的效果就要使用路由。其实我们不能只从字面的意思来理解路由从字面上来看很容易把路由联想成“路由器”。路由器的功能用一句话来概括就是连接两个或多个网络的硬件设备。我们所说的路由是指在一个应用程序中链接多个页面组件的一种配置在一个全栈项目中路由分为前端路由和后端路由。
后端路由
先来看一下后端路由例如项目的服务器地址是 http://192.168.1.10:8080 在这个站点中提供了3个界面分别是
页面1地址 http://192.168.1.10:8080/index.html
页面2地址 http://192.168.1.10:8080/about.html
页面3地址 http://192.168.1.10:8080/news.html当我们在浏览器中输入 http://192.168.1.10:8080/index.html 时web服务器接收到这个请求然后把 “/index.html” 解析出来再找到 index.html 文件并响应给浏览器这就是服务器端的路由分发。
前端路由
虽然前端路由和后端路由在实现技术上有些差别但是实现的原理都是一样的。在HTML5的 history API 发布之前前端路由功能都是通过 hash散列计算的因为 hash 算法可以兼容低版本的浏览器例如
http://192.168.1.10:8080/#/index.html
http://192.168.1.10:8080/#/about.html
http://192.168.1.10:8080/#/news.html由于web服务不会解析#后面的内容而JavaScript是可以拿到#后面的内容的那么就可以使用 window.location.hash 来读取通过这个方法来匹配到不同的功能上。使用hash的方式还有一个很大的优点当hash的值改变后不会导致浏览器的刷新。
1.2 在Vue中使用路由
用 Vue.js Vue Router 创建单页应用是非常简单的。要在Vue.js应用程序中使用路由需要先安装 vue-router 在当前项目下启动命令行工具命令如下
npm install vue-router如果在一个模块化工程中使用它必须要通过 Vue.use() 明确地安装路由功能
import Vue from vue
import VueRouter from vue-routerVue.use(VueRouter)如果是使用脚手架工具创建的项目路由的配置在 /src/router/index.js 文件中。 注意 如果使用全局的 script 标签就无需上面的操作了。 在脚手架工具创建的项目中使用路由需要在 /src/router/index.js 路由配置文件创建路由对象然后将路由配置文件引入到 main.js 入口文件并注册到Vue实例上。上面的流程操作完成后就可以在页面组件中使用路由的内置组件 router-link 和 router-view 进行页面跳转了。 /router/index.js 文件代码如下
import Vue from vue
import VueRouter from vue-routerVue.use(VueRouter)const routes [{path: /home,name: Home,component: () import(/views/Home.vue)}
]const router new VueRouter({mode: history,base: process.env.BASE_URL,routes
})export default router/main.js 文件代码如下
import Vue from vue
import App from ./App.vue
import router from ./routernew Vue({router,render: h h(App)
}).$mount(#app)/App.vue 文件代码如下
templatedivdiv!-- 用于跳转路由的链接to属性为跳转地址 --router-link to/homeHome页面/router-link/div!-- 路由匹配的组件会渲染到router-view --router-view//div
/template/views/Home.vue 文件代码如下
templatediv这是Home页面/div
/template在Google Chrome浏览器运行打开项目根目录会显示 router-link 的超链接效果如下图所示
点击超链接后跳转到 http://localhost:8080/home 路由下并渲染 Home.vue 视图效果如下图所示。
1.3 动态路由
在很多时候我们需要从一个页面跳转到另一个页面并且携带参数这种应用场景下就可以使用动态路由。动态路由可以将某种模式匹配到所有路由全部映射到同一个组件上。例如我们需要访问一个商品页面的组件 goods.vue 文件对于所有要访问这个页面组件的用户来说都要使用这个组件进行视图渲染。那么就可以在 vue-router 的路由路径中使用“动态路径参数”来达到这个效果。 一个“路径参数”使用冒号 : 标记。当匹配到一个路由时参数值会被设置到 this.$route.params可以在每个组件内使用。 /router/index.js 文件代码如下
import Vue from vue
import VueRouter from vue-routerVue.use(VueRouter)const routes [{path: /goods/:gid,name: Goods,component: () import(/views/Goods.vue)}
]const router new VueRouter({mode: history,base: process.env.BASE_URL,routes
})export default router/App.vue 文件代码如下
templatedivdiv!-- 用于跳转路由的链接to属性为跳转地址 --router-link to/goods/1001查看商品/router-link/div!-- 路由匹配的组件会渲染到router-view --router-view//div
/template/views/Goods.vue 文件代码如下
template
div
商品详情页面
p
商品ID{{$route.params.gid}}
/p/div
/template在Google Chrome浏览器中运行项目根目录下会显示“查看商品”的超链接效果如下图所示
当点击超链接页面跳转到 /goods 商品详情路由下并渲染 Goods.vue 视图在商品详情页面中会显示传递过来的商品id参数值效果如下图所示。
可以在一个路由中设置多段“路径参数”对应的值都会设置到 $route.params 中。参数设置参考如下表所示。
除了 $route.params 外$route 对象还提供了其它有用的信息例如$route.query (在 URL中设置查询参数)、$route.hash 等等。
1.4 嵌套路由
在实际生活中的应用界面通常由多层嵌套的组件组合而成在配置路由的过程中需要对URL进行分层管理使每一个路由都能按照嵌套的顺序进行编写。我们还以商城类应用为例在商品分类页面点击某一个类别要跳转到商品的列表页面那么该商品列表页面的路由就由商品分类商品列表组成。 /App.vue 文件代码如下
templatediv!-- 路由匹配的组件会渲染到router-view --router-view//div
/template在上面代码中的 是最顶层的出口渲染最高级路由匹配到的组件。同样地一个被渲染组件同样可以包含自己的嵌套 。例如在 Classify.vue 组件的模板添加一个 。 /views/Classify.vue 文件代码如下
template
div
div
router-link to/classify/list/1男装/router-link nbsp;nbsp;
router-link to/classify/list/2女装/router-link nbsp;nbsp;
router-link to/classify/list/3童装/router-link
/divrouter-view/router-view
/div
/template/views/GoodsList.vue 文件代码如下
template
div
商品列表页 -- 分类id{{$route.params.tid}}
/div
/template要在嵌套的出口中渲染组件需要在 VueRouter 的参数中使用 children 配置。 /router/index.js 文件代码如下
import Vue from vue
import VueRouter from vue-routerVue.use(VueRouter)const routes [{path: /classify,name: Classify,component: () import(/views/Classify.vue),children: [{path: /classify/list/:tid,name: GoodsList,component: () import(/views/GoodsList.vue)}]}
]const router new VueRouter({mode: history,base: process.env.BASE_URL,routes
})export default router在Google Chrome浏览器中运行访问 /classify 路由时打开商品分类页面效果如下图所示
当点击不同的商品类别时跳转到 /classify/list/:tid 路由渲染商品列表页面视图并动态的获取当前商品列表的id效果如下图所示。
1.5 编程式导航
除了使用 创建 a 标签来定义导航链接我们还可以借助 router 的实例方法通过编写代码来实现。
push函数
语法
router.push(location, onComplete?, onAbort?)想要导航到不同的 URL则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录所以当用户点击浏览器后退按钮时则回到之前的 URL。在 Vue 实例内部可以通过 $router 访问路由实例具体操作为 this.$router.push。 当你点击 router-link 时这个方法会在内部调用所以说点击 router-link :to... 等同于调用 router.push(...)。 声明式代码
router-link :to...编程式代码
router.push(...)该方法的参数可以是一个字符串路径或者一个描述地址的对象代码如下
// 字符串
router.push(home)// 对象
router.push({ path: home })// 命名的路由
router.push({ name: user, params: { userId: 123 }})// 带查询参数变成 /register?planprivate
router.push({ path: register, query: { plan: private }})如果提供了 pathparams 会被忽略上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法你需要提供路由的 name 或手写完整的带有参数的 path代码如下
const userId 123
router.push({ name: user, params: { userId }}) // - /user/123
router.push({ path: /user/${userId} }) // - /user/123
// 这里的 params 不生效
router.push({ path: /user, params: { userId }}) // - /user同样的规则也适用于 router-link 组件的 to 属性。
replace函数
语法
router.replace(location, onComplete?, onAbort?)router.replace 跟 router.push 很像唯一的不同就是它不会向 history 添加新记录而是跟它的方法名一样 替换掉当前的 history 记录。 声明式示例代码
router-link :to... replace编程式示例代码
router.replace(...)go函数
语法
router.go(n)这个方法的参数是一个整数意思是在 history 记录中向前或者后退多少步类似 window.history.go(n)。代码如下
// 在浏览器记录中前进一步等同于 history.forward()
router.go(1)// 后退一步记录等同于 history.back()
router.go(-1)// 前进 3 步记录
router.go(3)// 如果 history 记录不够用那就默默地失败呗
router.go(-100)
router.go(100)2 路由的相关配置
2.1 命名路由
在开发过程中使用路由跳转的过程中如果每次都用path会显得比较麻烦如果能通过一个名称来标识一个路由会显得更加方便。在vue-router中就有关于命名路由的配置项创建Router实例的时候在routes配置中可以给某个路由设置名称。代码如下
const router new VueRouter({routes: [{path: /user/:userId,name: user,component: User}]
})要链接到一个命名路由可以给 router-link 的 to 属性传一个对象代码如下
router-link :to{
name: user,
params: { userId: 123 }
}User/router-link这跟代码调用 router.push() 的效果是一样的。代码如下
router.push({ name: user, params: { userId: 123 }})
上面这两种方式都会把路由导航到 /user/123 路径。
2.2 命名视图
有时候想同时 (同级) 展示多个视图而不是嵌套展示例如创建一个布局有 sidebar (侧导航) 和 main (主内容) 两个视图这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图而不是只有一个单独的出口。如果 router-view 没有设置名字那么默认为 default。
router-view classview one/router-view
router-view classview two namea/router-view
router-view classview three nameb/router-view一个视图使用一个组件渲染因此对于同个路由多个视图就需要多个组件。确保正确使用 components 配置 (带上 s)代码如下
const router new VueRouter({routes: [{path: /,components: {default: Foo,a: Bar,b: Baz}}]
})2.3 重定向
在实际开发中当对一个页面的功能操作完成后需要自动完成跳转或者是访问某个路由链接时需要自动访问另外一个链接这就要用到路由的重定向配置。重定向可以通过routes配置来完成代码如下
const router new VueRouter({routes: [{ path: /a, redirect: /b }]
})重定向的目标也可以是一个命名的路由代码如下
const router new VueRouter({routes: [{ path: /a, redirect: { name: foo }}]
})还可以通过一个方法动态返回重定向目标代码如下
const router new VueRouter({routes: [{ path: /a, redirect: to {// 方法接收 目标路由 作为参数// return 重定向的 字符串路径/路径对象}}]
})3 路由的模式
在讲解vue-router的路由模式之前首先要先认识路由的组成每个路由都是由多个URL组成使用不同的URL可以相应的导航到不同的位置。对于服务器端访问来说HTTP请求是无状态的所以当请求服务器不同的地址来切换页面时都会重新进行请求。而在使用vue-router在前端做页面切换时并没有让浏览器刷新这是因为借助了浏览器的History API来实现的使得页面跳转而浏览器不做刷新操作页面的状态就被维持在浏览器中了。 vue-router中默认是hash模式URL地址的格式为 http://localhost:8080/#/ 在URL中带有#号。可以在 router 实例中修改路由的模式代码如下
const router new VueRouter({mode: history,base: process.env.BASE_URL,routes
})当路由的模式设置为 history 模式后URL地址中的#就会被去除了。
4 导航守卫
导航守卫又称为路由守卫用来实时监控路由跳转的过程在路由跳转的各个过程中执行相应的钩子函数这就类似于Vue的生命周期钩子在实际开发中经常被使用。例如当用户点击一个页面时如果当前用户为登录就自动跳转到登录页面如果是已经登录就让用户正常进入。 导航守卫分为全局守卫、路由独享守卫和组件内守卫这三种方式应用的场景不同都有自己的钩子函数具体内容如下。
4.1 全局守卫
全局守卫的钩子函数三个分别是
router.beforeEach全局前置守卫router.beforeResolve全局解析守卫router.afterEach全局后置守卫
router.beforeEach全局前置守卫
可以使用 router.beforeEach 注册一个全局前置守卫代码如下
const router new VueRouter({ ... })router.beforeEach((to, from, next) {// ...
})当一个导航触发时全局前置守卫按照创建顺序调用。守卫是异步解析执行此时导航在所有守卫 resolve 完之前一直处于 等待中。 每个守卫方法接收三个参数
to是一个Route对象表示即将要进入的目标路由对象。from是一个Route对象表示当前导航正要离开的路由。next是一个函数对象必须要调用该方法来完成这个钩子执行效果依赖 next 方法的调用参数。
router.beforeResolve(全局解析守卫)
和全局前置守卫类似区别是在跳转被确认之前同时在所有组件内守卫和异步路由组件都被解析之后解析守卫才调用。
router.afterEach(全局后置钩子)
可以注册全局后置钩子然而和守卫不同的是这些钩子只接受to和from不会接受 next 函数也不会改变导航本身。
4.2 路由独享守卫
独享守卫只有一种:beforeEnter。该守卫接收的参数与全局守卫是一样的但是该守卫只在其他路由跳转至配置有beforeEnter路由表信息时才生效。 router配置文件配置如下
const router new VueRouter({routes: [{path: /foo,component: Foo,beforeEnter: (to, from, next) {// ...}}]
})4.3 组件内守卫
组件内守卫是在组件内部直接定义的有以下三个钩子函数。
beforeRouteEnter进入该路由前执行。beforeRouteUpdate该路由的动态参数值发生改变时执行(2.2 新增)。beforeRouteLeave离开该路由时执行。
代码如下
const Foo {template: ...,beforeRouteEnter (to, from, next) {// 在渲染该组件的对应路由被 confirm 前调用// 不能获取组件实例 this// 因为当守卫执行前组件实例还没被创建},beforeRouteUpdate (to, from, next) {// 在当前路由改变但是该组件被复用时调用// 举例来说对于一个带有动态参数的路径 /foo/:id在 /foo/1 和 /foo/2 之间跳转的时候// 由于会渲染同样的 Foo 组件因此组件实例会被复用。而这个钩子就会在这个情况下被调用。// 可以访问组件实例 this},beforeRouteLeave (to, from, next) {// 导航离开该组件的对应路由时调用// 可以访问组件实例 this}
}beforeRouteEnter 守卫 不能 访问 this因为守卫在导航确认前被调用因此即将登场的新组件还没被创建。 不过你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) {next(vm {// 通过 vm 访问组件实例})
}注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说this 已经可用了所以不支持传递回调因为没有必要了。