基础回顾
- 基本使用
- 创建路由组件
- vue.use()注册vue-router
- 注册router-view
- 创建链接 router-link
动态路由
$route.params.id
const routes = [{name: 'detail',// 路径中携带参数path: '/detail/:id',component: detail}]// detail 组件中接收路由参数$route.params.id
props:true ——推荐
const routes = [{name: 'detail',// 路径中携带参数path: '/detail/:id',component: detail,props: true}]// detail 组件中接收路由参数const detail = {props: ['id'],template: '<div>Detail ID: {{ id }}</div>'}
路由嵌套
index组件和details组件嵌套layout组件
{path: '/',component: layout,children: [{name: 'index',path: '/',component: index},{name: 'details',path: '/details/:id',component: details}]}
编程式导航
// 跳转到指定路径router.push('/login')// 命名的路由router.push({ name: 'user', params: { id: '5' }})router.replace()router.go()
Hash模式和History模式的区别
HTML5 HIstory模式的使用
- History需要服务器的支持
- 单应用中,服务端不存在http://www.testurl.com/login这样的地址会返回找不到该页面
- 在服务端应除了静态资源外都返回单页应用的 index.html
- Node.js环境
const history = require('connect-history-api-fall-back')app.use(history())
nginx中配置
- 从官网下载nginx的压缩包
- 把压缩包解压到c盘根目录,c:\nginx-1.18.0文件夹
修改 conf\nginx.conf文件
location / {root html;index index.html index.htm;#新添加内容#尝试读取$uri(当前请求的路径),如果读取不到读取$uri/这个文件夹下的首页#如果都获取不到返回根目录中的 index.htmltry_files $uri $uri/ /index.html;}
打开命令行,切换到目录c:\nginx-1.18.0
- nginx启动、重启和停止
# 启动start nginx# 重启nginx -s reload# 停止nginx -s stop
Vue Router模拟实现
前置知识:插件、solt插槽、混入、render函数、运行时和完整版的Vue实现思路
创建VueRouter插件,静态方法install
- 判断插件是否已经被加载
- 当Vue加载的时候把传入的router对象挂载到Vue实例上(注意:只执行一次)
创建VueRouter类
创建VueRouter插件
export default class VueRouter {static install (Vue) {// 如果插件已经安装直接返回if (VueRouter.install.installed && _Vue === Vue) returnVueRouter.install.installed = true_Vue = VueVue.mixin({beforeCreate () {// 判断 router 对象是否已经挂载了 Vue 实例上if (this.$options.router) {// 把 router 对象注入到 Vue 实例上_Vue.prototype.$router = this.$options.router}}})}}
实现VueRouter类-构造函数
constructor (options) {this.options = options// 记录路径和对应的组件this.routeMap = {}this.app = new _Vue({data: {// 当前的默认路径current: '/'}})}
实现VueRouter类-initRouteMap()
initRouteMap () {// routes => [{ name: '', path: '', component: }]// 遍历所有的路由信息,记录路径和组件的映射this.options.routes.forEach(route => {// 记录路径和组件的映射关系this.routeMap[route.path] = route.component})}
实现VueRouter类-注册事件
initEvents () {// 当路径变化之后,重新获取当前路径并记录到 currentwindow.addEventListener('hashchange', this.onHashChange.bind(this))window.addEventListener('load', this.onHashChange.bind(this))}onHashChange () {this.app.current = window.location.hash.substr(1) || '/'}
实现VueRouter类-router-link和router-view组件
initComponents () {_Vue.component('RouterLink', {props: {to: String},// 需要带编译器版本的 Vue.js// template: "<a :href='\"#\" + to'><slot></slot></a>"// 使用运行时版本的 Vue.jsrender (h) {return h('a', {attrs: {href: '#' + this.to}}, [this.$slots.default])}})const self = this_Vue.component('RouterView', {render (h) {// 根据当前路径找到对应的组件,注意 this 的问题const component = self.routeMap[self.app.current]return h(component)}})}
注意:
- vue-cli创建的项目默认使用的是运行版本的Vue.js
- 如果想切换成带编译器版本的Vue.js,需要修改vue-cli配置
- 项目根目录创建vue.config.js文件,添加runtimeCompiler
modele.exports = {runtimeCompile:true}
- 项目根目录创建vue.config.js文件,添加runtimeCompiler
实现VueRouter类-init()
init () {this.initRouteMap()this.initEvents()this.initComponents()}// 插件的 install() 方法中调用 init() 初始化if (this.$options.router) {_Vue.prototype.$router = this.$options.router// 初始化插件的时候,调用 initthis.$options.router.init()}
