1.axios的请求地址用模板字符串(可以传多个属性),普通字符串拼接(传单个参数)
2.try自带条件的if(这个条件一般是错误的),catch自动新建了一个名为err的变量存储错误文本。
使用try还有一个好处,如果try代码块里发生了错误,不会终止脚本的执行。
github搜索案例相关知识点
-
设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办
-
ES6小知识点:结构赋值+重命名
let obj = {a:{b:1}}
const {a}=obj //传统的解构赋值
const {a:{b}}= obj //连续解构赋值
const {a:{b:value}} = obj //连续解构赋值+重命名
-
消息订阅与发布机制
- 先订阅,在发布(理解:有一种隔空对话的感觉)
- 适用于任意组件之间的通信
- 要在组件的componentWillUnmount 中取消订阅
-
fetch发送请求(关注分离的设计思想)
try{ const response = await fetch(`/api1/search/users?q=${value}`) const data= await response.json(); PubSub.publish('atguigu',{isLoading:false,users:data.items}) } catch(error) { console.log("请求出错了",error); PubSub.publish('atguigu',{error:error.message}) }
小结:
token的使用:在进行敏感操作之前,每一个请求需要携带token,但是token有有效期,token失效后需要换取新的token并继续请求
alt属性是一个用于网页语言HTML和XHTML,当元素本身的物件无法被渲染时,就显示alt(替换)文字作为一种补救措施。
ref的作用:获取到页面上添加了 ref 的input输入框的值,对于子组件来说,我们可以直接获取到子组件data 选项中的数据,或是直接调用子组件的方法。
a标签中的rel( rel='noreferrer'): rel=noreferrer 可以禁用HTTP头部的Referer属性 而我要跳转进去的页面设置了防盗链
HTTP头部的Referer属性(作用):1.防盗链,比如只允许某台服务器访问我自己的图片服务器资源,则可校验Http请求包中的Referer。判断是不是特定服务器的域名,若不是,则拒接响应。2.防止恶意请求:对于某些风险较高的文件类型,可使用Referer使得该类型文件只能来自我所指定的网站
ES7 async函数
简介:async是ES7才有的与异步操作有关的关键字,和Promise,Generator有很大关联的
语法:
async function name([param[, param[, ... param]]]) { statements }
- name: 函数名称。
- param: 要传递给函数的参数的名称。
- statements: 函数体语句。
返回值:
async函数返回一个Promise对象,可以使用then方法添加回调函数。
async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。
await 关键字仅在 async function 中有效。如果在 async function 函数体外使用 await ,你只会得到一个语法错误。
Await关键字
await操作符用于等待一个Promise对象,只能在异步函数async function的内部使用
语法:
[return_value] = await expression;
- expression: 一个 Promise 对象或者任何要等待的值。
返回值
返回Promise对象的处理结果,如果等待的不是Promise对象,则返回该值本身,
如果一个Promise被传递给一个await操作符,await将等待Promise正常处理完成并返回其处理结果
正常情况下,await命令后面是一个Promise对象,它也可以是其他值,如:字符串,布尔值,数值以及普通的函数。
await针对所跟不同表达式的处理方式:
Promise对象:await会暂停指向,等待Promise对象resolve,然后回复async函数的执行并返回解析值
非Promise对象:直接返回对应的值。
发布订阅模式:
发布订阅模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个注意对象,用再:父子传值,兄弟传值没有办法满足需求,需要在这个页面操作,要改变另一个不相关的页面里面的数据。
用法:
pubsub-js
publish:发布
subscribe:订阅
1、下载,要依赖于pubsub-js模块
cnpm install pubsub-js --save
2、import pubSub from "pubsub-js"
使用:发布
pubSub.publish("消息名称",“消息的内容”);
订阅者:订阅
pubSub.subscribe("消息名称",function(name,context){})
例子:
one组件中
<input type="button" value={"发布订阅者模式"} onClick={this.sendMsg}/>
sendMsg(){
pubSub.publish("haha","我是发布消息的内容","hkhj")
pubSub.publish("two","我是第二个发布者")
}
componentDidMount(){
pubSub.subscribe("two",(name,context)=>{
console.log("asfa",context)
})
pubSub.unsubscribe("two");//取消订阅者接收two的消息
}
two组件中
componentWillMount(){
//发布-订阅者的模式是一对多的模式,一个发布者,多个订阅者可以接收,一个订阅者,接收一个发布者
//订阅者,pubSub.subscribe第一个参数是消息名称要和发布消息名称一致才可以接受,第二个是接受参数时候收到的回调函数,接受数据时候回触发
//函数的第一个参数是消息名称,第二个是消息内容,没有第三个参数,第三参数是undefined,相传多个参数用对象在第二个参数传
pubSub.subscribe("haha",(name,context,aaa)=>{
console.log("订阅者",name,context,aaa);
})
}
fetch
fetch是基于promise,fetch是一种HTTP数据请求的方式,是XMLHttpRequest的一种替代方案。fetch不是ajax的进一步封装,而是原生的js
特点 1、第一个参数是URL: 2、第二个是可选参数,可以控制不同配置的 init 对象 3、使用了 JavaScript Promises 来处理结果/回调:
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
获取一个JSON文件,并打印到控制台,指明资源路径。然后返回一个Response对象,使用json()方法获取JSON内容。
promise
返回值:
若执行函数有return 则值为return返回的值
若执行函数没有return 则值返回一个undefined
两种情况 该函数的状态都为resolved
那什么情况为rejected呢?
若出现错误 或者该函数设定为rejected 状态才会是rejected 其他情况都不是rejected
SPA的理解
- 单页web应用
- 整个应用只有一个完整的页面
- 点击页面中的链接不会刷新页面,只会做页面的局部更新
- 数据都需要通过Ajax请求获取,并在前端异步展现
路由的理解
- 什么是路由
- 一个路由就是一个映射关系(key:value)
- key为路径,value可能是function或component
- 路由分类
- 后端路由
- 理解:value是function用来处理客户端提交的请求
- 注册路由:router.get(path,function(req,res))
- 工作过程:当node接受到一个请求时,根据请求路径找到匹配的路由,调用路由中的函数来处理请求,返回响应数据。
- 前端路由:
- 浏览器路由:value是component,用于展示页面内容
- 注册路由:
- 工作过程:当浏览器的path变成/test时,当前路由组件就会变为Test组件
- 后端路由
路由器分为两种:
BrowserRouter
HashRouter (/#/about #后面就是hash值,锚点值)
这个应用只能用一个浏览器管理
路由的基本使用:
-
明确好界面中的导航区,展示区
-
导航区的a标签改为Link标签
<Link to="/xxxx">Demo</Link>
- 展示区写Route标签进行路径的匹配
<Route path='/xxxx' component={Demo}/>
- App组件中的最外侧包裹一个BrowserRouter或HashRouter的标签
路由组件与一般组件
-
写法不同
- 一般组件:Demo/
- 路由组件:Route path="/demo" component={Demo}/
-
存放的位置不同:
- 一般组件:components
- 路由组件:pages
-
接收到的props不同:
- 一般组件:写组件标签时传递什么就会收到什么
- 路由组件:接收到三个固定的属性
-
history:
-
- go: ƒ go(n)
- goBack: ƒ goBack()
- goForward: ƒ goForward()
- push: ƒ push(path, state)
- replace: ƒ replace(path, state)
-
location:
-
- hash: ""
- pathname: "/about"
- search: ""
- state: undefined
-
match:
-
- params: {}
- path: "/about"
- url: "/about"
标签体内容就是一个特殊的标签内容
NavLink与封装NavLink
- NavLink可以实现路由连接的 高亮,通过activeClassName指定样式名
- 标签体内容是一个特殊的标签属性
- 通过this.props.children可以获取标签体内容
Switch的使用
- 通常情况下,path和component是一一对应的关系
- Switch可以提高路由匹配效率(单一匹配,之后一样的路由,就不会再次进行匹配)
解决多级路径刷新页面样式丢失的问题
- public/index.html中引入样式时不写./写/(常用)
- public/index.html中引入样式时不写./写%PUBLIC_URL%(常用)
- 使用HashRouter
路由的严格匹配与模糊匹配
1. 默认使用的是模糊匹配(简单记:【输入路径】必须包含【要匹配的路径】,且顺序要一致)
1. 开启严格模式:<Route exact path='/about' component={About/}>
1. 严格匹配不要随便开启,需要再开,有一些时候开启会导致无法继续匹配二级路由
Redirect的使用
-
一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
-
具体编码:
<Switch> <Route path="/about" component={About}/> <Route path="/home" component={Home}/> <Redirect to="/about"/> </Switch>
嵌套路由
- 注册子路由是要写上父路由的path值
- 路由的匹配是按照注册路由的顺序进行的
Ajax中的query、params、body
query可以用name和path来传递,但是params只能用name来传递,query是直接在url中,页面刷新后url传递的参数依旧在,params在刷新跳转页面的时候就没有了。body是请求体。
Ajax中的params参数:将实参列表中的跟可变参数数组类型一致的元素都当做数组的原素去处理。params参数,在作为参数时智能出行爱你在参数的最后一位之,一个方法只能使用一个params参数。调用方法体时,params参数传值 数据类型需要一致。
向路由组件传递参数
- params参数
路由链接(携带参数):详情
注册路由(声明接收):
接收参数:const {id,title} =this.props.match.params
- search参数
let obj ={name:'tome',age:20} //name=tom&age 形式如:key=value&key 就是urlencoded
console.log(qs.stringify(obj)); //stringify就是将对象转换成为urlencoded的形式
let str='carName=奔驰&price=19'; //字符串形式
console.log(qs.parse(str)) //parse转换成为对象的形式
路由链接(携带参数):<Link to="/demo/test/?name=tom&age=18"}详情
注册路由(无需声明,正常注册即可):
接收参数:const {search} =this.props.location
备注:获取到search是urlencoded编码字符串,需要借助querystring解析
- state参数
路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情
注册路由(无需声明,正常注册即可):
接收参数:const {search} =this.props.location
备注:刷新也是可以保留参数
路由跳转的两种模式
push模式:会有后退的记录
replace模式:直接进行替换,不会有后退的历史记录
withRouter
让一般的组件也使用上路由组建的属性
BrowerRouter与HashRouter的区别
- 底层原理不一样:BrowerRouter使用的是H5的history API,不兼容IE9及以下版本;HashRouter使用的是URL的哈希值
- url表现形式不一样:BrowerRouter的路径中没有#,HashRouter的路径中有#
- 刷新后对路由state参数的影响:BrowerRouter没有任何影响,因为state保存在history对象中;HashRouter刷新后会导致路由state参数的丢失
- 备注:HashRouter可以用于解决一些路径错误相关的问题。(样式的丢失,css的文件找寻)
element、vant、ant-design官网UI
按需进行引入css样式
纯函数:
- 一类特别的函数:只要是同样的输入(实参),必定得到同样的输出(返回)
- 必须遵守以下一些约束
- 不得改写参数数据
- 不会产生任何副作用,例如:网络请求,输入和输出设备
- 不能调用Date.now()或者Math.random()等不纯的方法
- redux得reducer函数必须是一个纯函数
组件间的关系
父子组件
兄弟组件(非嵌套组件)
祖孙组件(跨级组件)
几种通信方式:
- props:
- children props
- render props
- 消息订阅-发布
- pubs-sub、event等等
- 集中式管理
- redux、dav等等
- conText: 生产者-消费者模式
比较好的搭配方式:
父子组件:props
兄弟组件:取消订阅-发布、集中式管理
祖孙组件(跨越组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)
重定向就是:当前方法不运行,运行重定向指定的其他方法