老外做生意的思路和中国人不太一样,中国人喜欢便宜货,比如说买相机,期望什么都给你配好,还附送一大堆东西。而老外发给你的货干干净净,所谓贵的要命名牌也只不过是廉价的环保纸盒(摔不坏即可)。一分钱也不少赚你,同理一分钟钱也不多赚你。
在贸易战的大背景下,你可能不大认同这点。但就程序开发这点来说体会特别特别深。作为中国人写的框架比如vue,thinkjs等。用起来特别傻瓜式。而那些由“不存在的公司”Google,facebook开发的react,angular之流。写起来是真的高冷。而无可否认乃至包括尤雨溪也承认,vue参考了react的诸多东西。
现有需求如左:登录判断。
前后端的撕逼似乎还没完,jwt方案扯了如同没说。现在说,在每个需要鉴权的页面做登录态请求。通过了,才能做访问。
看到这个需求,我真的羞于做这样的事情。好好的一个SPA应用。硬生生做成web1.0时代的感觉,真是日了热比娅了!这TM后端做的东西我来搞!
但面向百度遍了一波程序,发现这种需求在中国人中间还贼tm多。心情也渐渐平复。其实无论是token验证还是这种恶心的验证方式。都是用高阶组件来实现的。
先简单介绍下高阶组件。
react有一个著名的公式:
UI或页面page=f(state)
而对对于HOC:
const EnhancedComponent = highOrderComponent(WrappedComponent);
组件是把 props 转化成 UI,而高阶组件是把一个组件转化成另外一个组件。
由此可得,高阶组件不是什么react的功能,它只是一个函数,接收一个组件,然后返回一个新的组件。
既然是函数,那就可以有参数,有返回值。从上面可以看出,这个函数接收一个组件 WrappedComponent
作为参数 ,返回加工过的新组件 EnhancedComponent
。其实高阶组件就是设计模式里的装饰者模式。
高阶组件你可以理解为一台相机裸机。 你得给他装个牛逼镜头,配个滤镜。装个挂带。然后才能带着出去装逼。 (冠希哥设计对白:我要开始装逼了)
下面是一个简单的高阶组件:
import React, { Component } from 'react';
export default (WrappedComponent) => {
return class EnhancedComponent extends Component {
// do something
render() {
return <WrappedComponent />;
}
}
}
从上面的代码可以看出,我们可以对传入的原始组件 WrappedComponent
做一些你想要的操作(比如操作 props,提取 state,给原始组件包裹其他元素等),从而加工出你想要的组件 EnhancedComponent
。把通用的逻辑放在高阶组件中,对组件实现一致的处理,从而实现代码的复用。
vue的思路是:你告诉我想拍什么效果,我帮你实现哟。 react的思路是:给你一台裸机,去创造世界吧。造的怎么样看你的水平。
https://reacttraining.com/react-router/web/example/auth-workflow
react的路由守卫在4.0之前是有一个类似 beforeEach
的前置钩子。但4.0之后删了。作者的理由是:删了更自由。
现在就采用高阶组件的形式来体现了:
const PrivateRoute = ({ component: Component, ...rest }) => (
class Guard extends Component {
constructor(props) {
super(props)
this.state = {
auth: false, // 表示是否认证通过
hasAuthed: false, // 表示是否向服务器发送过认证请求
role:null //教师或学生
};
}
componentDidMount() {
//向服务器发送认证请求,result表示认证是否成功
Http.get(Api.isLogin, (msg) => {
console.log('msg',msg.errno)
if (msg.errno == 0) {
if (msg.data.result.role) {
//老师
this.setState({
auth:true,
hasAuthed:true,
role:'teacher'
})
} else {
//学生
this.setState({
auth:true,
hasAuthed:true,
role:'student'
})
}
} else {
// alert(msg.errmsg)
this.setState({
hasAuthed:true,
})
}
})
}
render() {
// 初始渲染时,尚未向服务器发送认证请求,因此不渲染元素
console.log(this.state.auth)
if (!this.state.hasAuthed) {
return null;
}else{
return <Route {...rest} render={props => (
this.state.auth ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)
)} />
}
}
}
)
注意:if(!this.state.hasAuthed)
肯定会造成白屏。可见这个体验也还真的不怎么样~~。
以上。