伴随着青训营项目的推进,小编狂补react知识,接下来我就react路由以及组件展开讨论。文章内容如有不对,请各位看官多多指正,非常感谢。
文章目录
对SPA应用的理解
SPA(single page web application)单页web应用,它是一种网络应用程序或者网站的模型,通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验。
在单页应用中,所有必要的代码都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面。点击页面中的链接不会刷新页面,只会做页面的局部更新。
举个栗子,一个杯子,早上装水,中午装茶,晚上装牛奶,我们发现变的始终是杯子中盛放的东西,而杯子一直是那个杯子。
由此可见,我们能够将页面看作一个容器,我们需要修改的只是其中需要改动内容,比如某个组件等等。
具体结构如下
SPA与MPA的区别如下
单页面应用(SPA) 多页面应用(MPA) 组成 一个外壳页面和多个页面片段 多个完整页面构成 刷新方式 局部刷新 整页刷新 url模式 哈希hash模式 历史history模式 SEO搜索引擎优化 实现较为困难、不利于SEO检索,可利用服务器端渲染(SSR)优化 容易实现 数据传递 容易 依赖url传参,或者cookie、localStorage等 页面切换 速度快,用户体验良好 切换加载资源,速度慢,用户体验差 维护成本 相对容易 相对复杂
SPA应用优缺点
优点:
1. 具有桌面应用的即时性,网站的可移植性和可访问性
2. 用户体验好、快,内容的改变不需要重新加载整个页面
3. 良好的前后端分离,分工更加明确
缺点:
1. 不利于搜索引擎的抓取
2. 首次渲染速度相对较慢
对路由的理解
- 什么是路由
1. 一个路由就是一个映射关系(key: value)
key为路径,value可能是function或component
- 路由的分类
后端路由:
理解:value是function, 用来处理客户端提交的请求。
注册路由:router.get(path, function(req, res))
工作过程:当node接收到一个请求时,根据请求的路径找到匹配的路由,调用路由中的函数来处理请求,返回响应数据。
举个栗子(代码如下)const express = require("express") const axios = require("axios") const app = express() app.get("/search/users", function(req, res) { const {q} = req.query axios ({ url: 'https://api.github.com/search/users', params: {q} }).then(response => { res.json(response.data) }) })如果你请求的路径是"/search/users",就是如果你想搜索,搜索的是用户。那么则将本次请求交给function() {} 中去处理。function会拿到req对象,res对象,然后执行函数体中的那些操作。
对于后端路由来说,key == /search/users,value == function() {}
前端路由:
理解:浏览器端路由,value是component,用于展示页面内容。
注册路由:<Route path="/demo" component={Demo}
工作过程:当浏览器的path变为/demo时, 当前路由组件就会变为Demo组件。
- 前端路由的原理
前端路由的实现是依靠浏览器对象BOM里的历史记录—history。程序员不直接自己去操作BOM里的history,因为原生的API操作起来特麻烦,所以借助history.js库来操作。
引入history.js库<script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script>创建history对象
<script type="text/javascript"> let history = History.createBrowserHistory() </script>如何阻止a标签的跳转
点击a标签,调用push方法,得到false返回值在返回给a标签<a href="https://juejin.cn/" onclick="return push('/test1') ">push test1</a> <script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script> <script type="text/javascript"> let history = History.createHashHistory() function push (path) { history.push(path) return false } </script>学过数据结构小伙伴们应该都能够理解,浏览器的历史记录其实是一个栈的结构,保持后进先出的原则。所以每当执行push操作(追加历史记录)时,都是将path推入栈顶,浏览器也自动显示栈顶内容,当我们点击浏览器的后退按钮时,就把栈顶的内容对应的路径出栈。
每当执行replace操作(替换历史记录)时,则将目前栈顶的内容对应的路径替换,当点击回退按钮时,不会回退到刚刚被替换掉的内容(已经被替换掉了),而是回到被替换掉的内容的前一个历史记录。function replace(path) { history.replace(path) }实现回退操作(将栈顶内容出栈)
<button onClick="back()">回退</button> function back() { history.goBack() }实现前进操作(将栈外内容入栈)
<button onClick="forword()">前进</button> function forword() { history.goForward() }
补:
history有两种工作模式:history模式和hash模式
history模式:直接使用H5推出的history身上的APIlet history = History.createBrowserHistory()hash模式:使用hash值(类似锚点),使用该模式路径中会多一个#号
let history = History.createHashHistory()
总结
- 从react基本语法到生命周期,再到脚手架以及路由,我虽然只花了三四天时间,但是我知道这并不扎实,如不是项目时间紧迫,不愿拖团队后腿,我要重新再来一遍,学的更加牢固一些。
- 在我仅仅只学会前端三大件,没学过react这些框架之前,对前端的认识非常肤浅,知道接触了真正的大佬,才知道自己的无知。
- 承认自己的无知,乃是开启智慧的大门。