阅读 188

Vue Router

四. Vue-Router

路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动. --- 维基百科

1.1. 后端路由和前端路由

  • 后端渲染/后端路由
  • 前后端分离
  • SPA/前端路由

后端渲染: 服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示。比如:jsp页面

前端渲染: 浏览器中显示的网页中的大部分内容,都是由前端写的 js 代码在浏览器中执行,最终渲染出来的网页。(后端返回JSON数据,前端利用预先写的html模板,循环读取JSON数据,拼接字符串,并插入页面。)

后端路由: 浏览器在地址栏中切换不同的 url 时,每次都向后台服务器发出请求,服务器响应请求,服务器渲染好整个页面, 并且将页面返回给客户端。

前端路由: 核心-改变URL,但是页面不进行整体的刷新。

1.2. SPA页面

SPA:单页面富应用,整个网页只有一个html页面。

SPA最主要的特点就是在前后端分离的基础上加了一层前端路由.

前端路由的核心是改变URL,但是页面不进行整体的刷新。

1.3. URL的hash

URL的hash也就是锚点(#), 本质上是改变window.location的href属性.

我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新.

location.href
"http://192.168.1.101:80/"
location.hash = '/foo'
"http://192.168.1.101:80/#/foo"
复制代码

1.4. HTML5的history模式

  • pushState
  • back
  • forward
  • replaceState
  • go
history.pushState({},'','/foo')
location.href
"http://192.168.1.101:80/foo"

history.replaceState({},'','/foo')
location.href
"http://192.168.1.101:80/foo"

"http://192.168.1.101:80/foo"
history.go(-1)
location.href
"http://192.168.1.101:80/"
history.go(1)
"http://192.168.1.101:80/foo"
复制代码

1.5. Vue Router

vue-router是基于路由和组件的

  • 路由用于设定访问路径, 将路径和组件映射起来.
  • 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换.

1.6. 安装和使用路由

第一步:导入路由对象,并且调用 Vue.use(VueRouter)
第二步:创建路由实例,并且传入路由映射配置
第三步:在Vue实例中挂载创建的路由实例

import Vue from 'vue' 
import VueRouter from 'vue-router' 

路由懒加载
const Home = () => import('../components/Home.vue')
const About = () => import('../components/About.vue')
const Message = () => import('../components/Message.vue')
const news = () => import('../components/news.vue')



Vue.use(VueRouter)

使用vue-router的步骤:
第一步: 创建路由组件
第二步: 配置路由映射: 组件和路径映射关系
第三步: 使用路由: 通过<router-link>和<router-view>

// 定义路由
const routers = [
	{
		path: '/',
		redirect: '/home'
	},
	{
		path: '/home',
		component: Home,
		
		// 嵌套路由
		children: [
		  {
		    path: 'message',
		    component: Message,
		  },
		  {
		    path: 'news',
		    component: News,
		  },
		  {
		    path: '',
			redirect: 'message'
		  }
		]
	},
	{
		path: '/about',
		component: About
	}
]

// 创建router实例
const router = new VueRouter({
  routers,
  
    // 使用HTML5的history模式
	mode: 'history'  
	
	// 修改active-class属性的默认类名(router-link-active)
	LinkActiveClass: 'active'  
})

// 导出router实例
export default router

// 挂载到vue实例
new Vue({
	el: '#app',
	router,
	render: h => h(APP)
})

<router-link>: 该标签是一个vue-router中已经内置的组件, 它会被渲染成一个<a>标签.
<router-view>: 该标签会根据当前的路径, 动态渲染出不同的组件.
网页的其他内容, 比如顶部的标题/导航, 或者底部的一些版权信息等会和<router-view>处于同一个等级.
在路由切换时, 切换的是<router-view>挂载的组件, 其他内容不会发生改变.
复制代码

1.7. router-link 其他属性

1.8. 页面路由跳转

<button @click="linkToHome">首页</button>

<script>
	export default {
        name: 'App',
        methods: {
          linkToHome() {
              this.$router.push('/home')
          }
        }
    }
    
</script>
复制代码

1.9. 动态路由

1.91. params的类型
  • 配置路由格式: /router/:id
  • 传递的方式: 在path后面跟上对应的值
  • 传递后形成的路径: /router/123, /router/abc
//拿到用户名(userId是自己router中定义的路径)
{
  path: '/user/:userId',
  component: User
}

<router-link to="/user/123">用户</router-link>

<div>
  <h3>{{$route.params.userId}}</h3>
</div>

{{this.$route.params.userId}}
复制代码
1.92. query的类型
  • 配置路由格式: /router, 也就是普通配置
  • 传递的方式: 对象中使用query的key作为传递方式
  • 传递后形成的路径: /router?id=123, /router?id=abc
获取参数
{{$route.params}}

{{$route.query}}
复制代码
1.93. 两种传递参数的方式

传递参数方式一:

图片4.png


传递参数方式二: JavaScript代码

图片3.png

1.94. routeroute和router是有区别的
  • routerVueRouter实例,想要导航到不同URL,则使用router为VueRouter实例,想要导航到不同URL,则使用router.push方法

  • $route为当前router跳转对象里面可以获取name、path、query、params等

image.png

2.0. 路由的懒加载

作用:将路由对应的组件打包成一个个的js代码块,只有在这个路由被访问到的时候,才加载对应的组件。

方式一: 结合Vue的异步组件和Webpack的代码分析.
const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};

方式二: AMD写法
const About = resolve => require(['../components/About.vue'], resolve);

方式三: 在ES6中, 我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割.
const Home = () => import('../components/Home.vue')
复制代码

2.1. 嵌套路由

2.2. 导航守卫

官网

  • vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.
  • vue-router提供了beforeEach和afterEach的钩子函数, 它们会在路由即将改变前和改变后触发.
首先, 我们可以在钩子当中定义一些标题, 可以利用meta来定义
其次, 利用导航守卫,修改我们的标题.

const routers = [
	{
		path: '/',
		redirect: '/home'
	},
	{
		path: '/home',
		component: Home,
		meta: {
		title: '首页'
		}
	},
	{
		path: '/about',
		component: About,
		title: '关于'
	}
]

const router = new VueRouter({
  routers,
})

router.beforeEach((to, from, next) => {
  window.document.title = to.meta.title;
  next()
})

export default router

导航钩子的三个参数解析:
to: 即将要进入的目标的路由对象.
from: 当前导航即将要离开的路由对象.
next: 调用该方法后, 才能进入下一个钩子.


复制代码

2.3. keep-alive

keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

  • 两个属性:
    1. include - 字符串或正则表达,只有匹配的组件会被缓存
    2. exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存

router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存。

通过create声明周期函数来验证。

2.4. TabBar案例

  1. 如果在下方有一个单独的TabBar组件,你如何封装

    • 自定义TabBar组件,在APP中使用
    • 让TabBar出于底部,并且设置相关的样式
  2. TabBar中显示的内容由外界决定

    • 定义插槽
    • flex布局平分TabBar
  3. 自定义TabBarItem,可以传入 图片和文字

    • 定义TabBarItem,并且定义两个插槽:图片、文字。
    • 给两个插槽外层包装div,用于设置样式。
    • 填充插槽,实现底部TabBar的效果
  4. 传入 高亮图片

    • 定义另外一个插槽,插入active-icon的数据
    • 定义一个变量isActive,通过v-show来决定是否显示对应的icon
  5. TabBarItem绑定路由数据

    • 安装路由:npm install vue-router —save
    • 完成router/index.js的内容,以及创建对应的组件
    • main.js中注册router
    • APP中加入组件
  6. 点击item跳转到对应路由,并且动态决定isActive

    • 监听item的点击,通过this.$router.replace()替换路由路径
    • 通过this.$route.path.indexOf(this.link) !== -1来判断是否是active
  7. 动态计算active样式

    • 封装新的计算属性:this.isActive ? {'color': 'red'} : {}

代码实现

image.png

文章分类
前端
文章标签