vue2-路由&&模块化规范

路由

概念:路由是一个比较广义和抽象的概念,路由的本质就是对应关系

  • 后端路由
    • 概念:根据不同的用户url请求,返回不同的内容
    • 本质:url请求地址域服务器资源之间的对应关系
    • 根据不同的url地址分发不同的资源
  • SPA
    • 后端渲染(存在渲染问题)
    • Ajax前端渲染(前端渲染提高性能,但是不支持浏览器的前进后退操作)
    • 单页面程序spa:整个网站只有一个页面,内容的变化通过ajax局部更新实现、同时支持浏览器地址栏的前进和后退操作
    • 实现原理之一:实现原理之一:基于url的hash(hash的变化会导致浏览器记录访问历史的变化、但是hash的变化不会触发新的url请求)
    • 在实现spa过程中,最关键的技术就是前端路由
  • 前端路由
    • 概念:根据不同的用户事件,显示不同的页面内容
    • 本质:用户事件域事件处理函数之间的对应关系
    • 负责事件监听,触发事件后,通过事件函数渲染不同内容

前端路由的基本概念和原理

基于URL中的hash实现(点击菜单的时候改变URL的hash,根据hash的变化控制组件的切换)

1
2
3
4
//监听window的onhashchange事件,根据获取到的最新的hash值,切换要显示的组建的名称
window.onhashchange = function() {
//通过location.hash获取到最新的hash值
}

Vue Router

包括的功能:

  • 支持HTML5历史模式或hash模式
  • 支持嵌套路由
  • 支持路由参数
  • 支持编程式路由
  • 支持命名路由

使用基本步骤

  • 引入相关的库文件
  • 添加路由连接
  • 添加路由填充位
  • 定义路由组件
  • 配置路由规则并创建路由实例(!!!)
  • 把路由挂载到根实例中

路由传参

动态路由参数

通过动态路由参数的模式进行路由匹配。动态路由参数,在写路由匹配规则的时候,在路由最后的参数由:开头。而对应匹配的路由组件,可以通过$route.params.id获取路由参数:

props

$route与对应路由形成高度耦合,不够灵活,所以可以使用props将组件和路由解耦

  • props的值为布尔值。
    • 如果props被设置为true,route.params将会被设置为组件属性。需要在子组件中定义props:['id']来使用props接收路由参数。
  • props的值为对象类型时
    • 如果props是一个对象,它会被按原样设置为组件属性props:{ uname:'lisi',age:12 }
    • 在子组件中:props:['uname','age']
    • 就相当于传参传递多个参数,但是不能访问通过$route.params.id获取到的值
  • peops使得值为 函数类型
    • 如果props是一个函数,则这个函数接收route对象为自己的形参props: route => ({unam:'zs',age:20,id:route.params.id })
    • 子组件访问的时候props:['id','uname','age']
    • 该方法相当于是上述两种方法的结合

命名路由

为了更方便的表示路由的路径,可以给路由规则起一个别名,即命名路由。即在定义路由匹配规则中添加一个name属性即可。
即我们跳转路由的时候,可以在router-link中添加一个:to的对象为该命名路由。改成命名路由方式跳转

编程式导航

  • 声明式导航:通过点击连接实现导航的方式,叫做声明式导航。
    • 普通网页中的<a></a>连接
    • Vue中的<router-link></router-link>
  • 编程式导航:通过js形式的API实现导航的方式,叫做编程式导航
    • location.href

Vue中的编程式导航常用的API:

  • this.$router.push(‘hash地址’)//用来进行跳转
  • this.$router.go(n)//经常用来前进后退

router.push方法参数规则

1
2
3
4
5
6
7
8
//字符串
router.push('/home')
//对象
router.push({path:'/home'})
//命名的路由(传参)
router.push({name:'/user',params:{userId:123}})
//带查询参数,变成/register?unam=lisi
router.push({name:'/user',query:{uname:'lisi'}})

前端工程化

模块化

  • 传统开发模式的主要问题:命名冲突、文件依赖
  • 模块化就是把单独的一个功能封装到一个模块(文件)中,模块之间相互隔离,但是可以通过特定的接口公开内部成员也可以依赖别的模块
  • 方便代码重用,易于代码维护

模块化规范

  • 浏览器模块化规范
    • AMD
      • require.js
    • CMD
      • Sea.js
  • 服务器模块化规范
    • CommonJS规范
      • 模块分为单文件模块与包
      • 模块成员导出:module.exports和exports
      • 模块成员导入:require(‘模块标识符’)
  • 大一统的ES6模块化规范
    • 以上提出的AMD、CMD、CommonJS存在一定的差异性和局限性,并不是浏览器与服务器通用的模块化标准
    • AMD和CMD只适用与浏览器端的js模块化
    • CommonJS适用于服务器端的js模块化
    • 是浏览器端与服务器端通用的模块化开发规范
  • ES6中模块定义
    • 每个js文件都是一个独立的模块
    • 导入模块成员使用import关键字
    • 暴露模块成员使用export关键字

ES6模块化

Babel配置

  • npm i –save-dev @babel/core @babel/cli @babel/preset-env @babel/node
  • npm i –save @babel/polyfill
  • 项目根目录创建文件babel.config.js
  • babel.config.js文件内容添加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const presets = [
    ["@babel/env",{
    targets: {
    edge: "17",
    firefox: "60",
    chrome: "67",
    safari: "11.1"
    }
    }]
    ];
    module.exports = {presets};
  • 通过npx babe-node index.js执行代码

基本语法

  • 默认导出 export default{}(只能用一次)
  • 默认导入import 接受名称 from ‘模块标识符’
  • 按需导出:export let sl = 10
  • 按需导入:import { sl } from ‘模块标识符’
  • 有时候,我们只想单纯执行某个模块中的代码,并不需要得到模块向外暴露的成员,此时可以直接导入并执行模块代码 import ‘./m2.js’
-------------本文结束感谢您的阅读-------------