简述Vue的路由与视图
1、vue-router
- 安装方式
- npm/cnpm:(个人偏向于cnpm)
npm/cnpm install vue-router --save-dev
- bower:
bower install vue-router --save-dev
- 手动编译:省略
- npm/cnpm:(个人偏向于cnpm)
- 基本使用
- 概念:
后端路由:根据不同的url返回不同的内容(node) 前端路由:根据不同的hash返回不同的组件(Vue生成的项目叫做单页应用(SPA),单页面应用的特点就是可以在改变URL不重新请求页面的情况下更新页面视图。)
- 类型:
一、经常使用,无兼容性问题的方式hash 二、history方式
history.pushState(stateObj,'page2','2.html');----页面重新加载了吗?为什么url地址栏发生变化,显示为2.html,但并不会跳转到2.html页面上,也不会检查这个路径是否存在,它只是成为浏览历史中的最新记录,假定你访问了google.com,然后点击了倒退按钮,页面的url将显示为2.html,但是内容还是原来的1.html,再点击一次,url变为1.html,内容不变,总之,这个方法不会触发页面刷新,只会导致history对象发生变化,地址栏会有反应三、node下的默认实现方式abstract
import Vue from 'vue' 在router文件下的index.js文件中 import Router from 'vue-router' import { routes } from './router' 在router文件下的router.js文件中定义路由 Vue.use(Router)//注册 // 路由配置 const RouterConfig = { // mode: 'history', routes, }; - 路由的重定向:
redirect: { path: '/zh-CN/login' },
- 错误路由的匹配(如任意路径或者 404 Not Found)
{ path: '**', // 错误路由,使用通配符,并且此路由应该放到最后 redirect: { path: '/zh-CN/login' },//重定向 }
- 路由元信息:路由中的meta字段;
- 路由视图:
<router-view></router-view>相当于一个占位符,匹配到的组件展示到其中去
- 路由导航:
- 使用<router-link> 创建 a 标签来定义导航链接
<router-link to="/path" tag="">标签</router-link> 默认渲染为一个a标签,通过tag属性可以改变标签,仍然可以跳转
- 使用 router.push 方法(编程式导航)
一、跳转 1、this.$router.push('/list/' + type); 2、this.$router.push({path : '/list/' + type}) 3、this.$router.push({//常用 name: "list", params: { a: a, b: b, c: c }, query: {//查询参数 reason: 'reason', }, }); 跳转之后进行取值 this.$route.params.a /list/a/b/c this.$route.query.reson /list?reason = reason 二、替换 this.$router.replace(‘/home’) 前进后退按钮失效,清除路由跳转的历史记录 三、前进 this.$router.go(1) === window.history.forward() 四、后退 this.$router.go(-1) === window.history.back()
- 使用<router-link> 创建 a 标签来定义导航链接
- 在vue组件中的使用:
- 建立router文件夹,里面建立index.js与router.js,引入文件夹时会自动寻找index文件;
- router.js的文件代码是:
import title from '../config/title.config' const titleConfig = title['zh-CN'] const rootRouter = { path: '/', redirect: { path: '/zh-CN/login' }, meta: {}, } // 首页 const homeRoute = { path: '/:language(zh-CN|en-US)/home', name: 'home', component: () => import('../views/home.vue'), meta: { title: `${titleConfig.home}` }, } // 登录页 const loginRoute = { path: '/:language(zh-CN|en-US)/login', name: 'login', component: () => import('../views/login/login.vue'), meta: { title: `${titleConfig.login}` }, } // 个人中心首页 const userHomeRoute = { path: '/:language(zh-CN|en-US)/userHome', name: 'userHome', component: () => import('../views/user/userHome.vue'), meta: { title: `${titleConfig.home}` }, redirect: { path: '/zh-CN/userHome/userInfo' }, children: [{ path: 'userInfo', name: 'userInfo', component: () => import('../views/user/userInfo.vue'), meta: { title: `${titleConfig.userInfo}` } }, { path: 'myCollection', name: 'myCollection', component: () => import('../views/user/myCollection.vue'), meta: { title: `${titleConfig.myCollection}` } }, { path: 'message', name: 'message', component: () => import('../views/user/message.vue'), meta: { title: `${titleConfig.message}` } },] } // 商品详情页面 const goodsInfoRoute = { path: '/:language(zh-CN|en-US)/goodsInfo/:id/:booksPrice', name: 'goodsInfo', component: () => import('../views/goodsInfo/index.vue'), meta: { title: `${titleConfig.goodsInfo}` }, } // 所有路由 export const routes = [ rootRouter, homeRoute, loginRoute, userHomeRoute, goodsInfoRoute , ]
- index.js的文件代码是:
import Vue from 'vue' import Router from 'vue-router' import { routes } from './router' Vue.use(Router) // 路由配置 const RouterConfig = { // mode: 'history', routes, }; export const router = new Router(RouterConfig) router.beforeEach((to, from, next) => { if (to.meta.title) document.title = to.meta.title next() }) router.afterEach((to, from) => { })
- 概念:
- 导航守卫
- 官网https://router.vuejs.org/zh/guide/advanced
- 全局前置守卫
router.beforeEach((to, from, next) => { if (to.meta.title) document.title = to.meta.title next() }) 注解: to: 即将要进入的目标(当前导航即将要去的路由) from: 当前导航正要离开的路由 next: 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
- 全局后置钩子
router.afterEach((to, from) => { }) 注解: 不接受next函数也不改变导航本身
- 路由独享的守卫
可以在路由配置上直接定义-----在执行之前可以执行一个钩子函数,通过验证next,否则显示警告信息 routes: [ { path: '/foo', component: Foo, beforeEnter : (to,from,next)=>{//next才可以进来 进入之前进行的判断 if(sessionStorage.getItem("user")){ next(); }else{ alert("您还没有登录") } }) }
- 组件内的守卫
beforeRouteEnter (to,from,next) { next(vm => { // 通过 `vm` 访问组件实例 }) } 注解: 1、执行比beforeCreate早 2、在渲染该组件的对应路由被 confirm 前调用 3、不!能!获取组件实例 `this` 4、 因为当守卫执行前,组件实例还没被创建 beforeRouteUpdate (to,from,next) {//详情页面 }) 注解: 1、在当前路由改变,但是该组件被复用时调用 2、举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, 3、 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 4、可以访问组件实例 `this` beforeRouteLeave (to, from , next) { const answer = window.confirm('Do you really want to leave? you have unsaved changes!') if (answer) { next() } else { next(false) } }) 注解: 1、这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。 2、导航离开该组件的对应路由时调用 3、可以访问组件实例 `this`
- 路由懒加载
- 定义:懒加载也叫延迟加载,即在需要的时候进行加载,随用随载;
-
单页面开发:
优点:用户的体验性好,无需跳转; 缺点:像vue这种单页面应用,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,时间过长,会出现长时间的白屏,
而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载时间,简单来讲,就是进
入首页不用一次加载过多资源造成用时过长 (面试题:单页面开发有什么问题/用户项目打包完毕后出现短暂白屏,如何解决) - 用法:
1、 const homeRoute = { path: '/:language(zh-CN|en-US)/home', name: 'home', component: () => import('../views/home.vue'), meta: { title: `${titleConfig.home}` }, } 2、 const homeRoute = { path: '/:language(zh-CN|en-US)/home', name: 'home', component: resolve => require(['../views/home.vue'],resolve) meta: { title: `${titleConfig.home}` }, }
北栀女孩儿