第十二单元(react路由-使用react-router-dom-认识相关的组件以及组件属性)
#课程目标
- 理解路由的原理及应运
- 理解react-router-dom以及内置的一些组件
- 合理应用内置组件及其属性搭建项目路由
#知识点
- 路由的由来
-
路由就是指随着浏览器地址栏的变化,展示给用户的页面也不相同。这是从路由的用途上来解释路由是什么的,还有一种说法是:路由就是URL到函数的映射。
1-1. hash => 路由的实现就是基于location.hash来实现的。其实现原理也很简单,location.hash的值就是URL中#后面的内容
<a href="#/">主页</a> <a href="#/home">home</a> <a href="#/index">index</a> <div id='content'></div> <script> /* URL中hash值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash部分不会被发送。hash值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash的切换。我们可以使用hashchange事件来监听hash的变化。 */ class Router{ constructor({routes}) { this.routes = routes; this.everyPath = {}; this.init(); this.routes.forEach(item => { this.everyPath[item.path] = function() { document.getElementById('content').innerHTML = item.component; } }) } init() { window.addEventListener('load', this.updateLocation.bind(this)) window.addEventListener('hashchange', this.updateLocation.bind(this)) } updateLocation() { let pathRes = window.location.hash.slice(1); console.log(this.everyPath, '----', pathRes) this.everyPath[pathRes](); } } new Router({ routes: [ { path: '/', component: '主页' }, { path: '/home', component: 'home' }, { path: '/index', component: 'index' } ] }) </script>
1-2. history => 前面的hash虽然也很不错,但使用时都需要加上#,并不是很美观。因此到了HTML5,又提供了History API来实现URL的变化。其中做最主要的API有以下两个:history.pushState()和history.repalceState()。这两个API可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录。
<a href="javascript:;" data-to='/'>去首页</a> <a href="javascript:;" data-to='/home'>去home页</a> <a href="javascript:;" data-to='/index'>去index页</a> <div id="content"></div> <script> class Router{ constructor({routes}) { this.router = routes; this.init() this.bindClick(); } init() { window.addEventListener('popstate', this.updateView.bind(this)); } updateView() { let content = document.getElementById('content'); let clickRes = window.location.pathname content.innerHTML = this.router.filter(val => val.path === clickRes)[0].component; } bindClick() { let pushA = document.querySelectorAll('a'); [].forEach.call(pushA, item => { item.addEventListener('click', () => { let clickRes = item.getAttribute('data-to'); window.history.pushState({}, null, clickRes) this.updateView() }) }) } } new Router({ routes: [ { path: '/', component: '主页' }, { path: '/home', component: 'home' }, { path: '/index', component: