本人技术栈是Vue,最近调部门改成用React开发,从头开始踩坑,持续更新中~
1月18日内容汇总
记一次vue3.0技术分享会
Vue3.0 官方文档
备战2021:vite 工程化实践,建议收藏
1月14日内容汇总
如何实现一个react-router路由拦截(导航守卫)
React Router 4.0 实现路由守卫
https://segmentfault.com/a/11...
http://cache.baiducontent.com...
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
http://cache.baiducontent.com...
使用React.memo()来优化函数组件的性能
1月6日内容汇总
使用 npm install
拉取依赖的时候报错,可以试一下清空缓存,后面的参数 f
表示强制执行。
$ npm cache clean -f
1月1日内容汇总
Vue + Nuxt.js 项目推荐:
领课网络(RonCoo) / roncoo-education-web
React Redux 官方文档
React-Redux 文档 - Segmentfault
12月30日内容汇总
测试的同学提了一个老项目的缺陷,说是提交到后台的参数会把上一次操作的数据也给带上。我看了下代码,各种拼接字符串,而且他就是为了得到一个逗号分隔的字符串,还要手写 for
循环,直接调用数组的 join
或者 toString
不香吗?
修改方案:不管 nodesList
原来是不是空值,直接用一个新的值去替换;使用 map
方法生成一个节点ip的数组,调用 join
方法将数组转成字符串。
说明:Array.prototype.join()
或者Array.prototype.toString()
都默认返回以逗号分隔的字符串,这里为了语义更好给join
传了一个","
作为参数。如果不希望有分隔符可以使用Array.prototype.join("")
。
12月29日内容汇总
注释// TODO的作用
在注释中写 // TODO
,一些编辑器会进行代码高亮,例如 Android Studio,IDEA。在 vs code 中可以装一个插件 todo-tree
,支持高亮显示 TODO
,FIXME
,Tag
,DONE
等注释,还可以自定义样式。
vscode 插件推荐 todo-tree
记一次vue3.0技术分享会
第二集: 从零开始实现一套pc端vue的ui组件库(icon组件)
12月28日内容汇总
今天同事问了一个问题,在前端项目中,public 和 src/asstes 都可用于存放静态资源,这两个有什么区别呢?
查了一下其实很简单,在 public 目录下的文件不会被 webpack 打包,而是直接复制一份到构建出来的文件夹中;在 src/asserts 下的文件会被打包编译(前提是在JS中有引入),从而在实际项目中减少 HTTP 请求。
在实际项目中,public还是有它的作用的。如果你希望你的文件不被编译,比如jquery.min.js,或者压缩好的js插件等,你就可以把文件放在public文件夹中,这样可以减少文件构建时间,还可以减少构建出来的文件大小。
12月22日内容汇总
最近一个项目需要重构,但是那个项目不断还有新需求,给重构带来了一定难度。找了一些react后台模板,提升一下重构效率。
基于React+antd的后台管理模板(可预览)
react构建后台管理系统
React+AntD 后台管理系统解决方案 -- 终极版
使用React全家桶搭建一个后台管理系统
react中后台管理界面
12月2日内容汇总
JS 函数库
Vue 中主要使用 lodash ,React 中使用 Immutable.js
Immutable.js入门 - 知乎
为什么 react要使用immutable.js
Vue 和 React 项目多环境部署
开发环境:development
集成测试环境:staging
发布环境:production
三分钟教你搞定 React 项目多环境配置 - 知乎
react----cross-env配置多环境变量
react使用docker时多环境支持
React 添加环境变量
基于create-react-app 的 webpack 配置多环境
11月30日内容汇总
React 中动态加载组件
React.lazy()
允许你定义一个动态加载的组件。这有助于缩减 bundle 的体积,并延迟加载在初次渲染时未用到的组件。
const SomeComponent = React.lazy(() => import('./SomeComponent'));
使用 React.lazy
的动态引入特性需要 JS 环境支持 Promise。在 IE11 及以下版本的浏览器中需要通过引入 polyfill 来使用该特性。
Vue 这个被称为异步组件,也是利用 Promise 来实现的。
Vue.component(
'async-webpack-example',
// 这个动态导入会返回一个 `Promise` 对象。
() => import('./my-async-component')
)
当使用局部注册的时候,你也可以直接提供一个返回 Promise
的函数:
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
React 中的 style
React 中的 style
并不是 Vue 中的双大括号,最外面那个括号代表内部是 JS 表达式,里面的括号是 JS 对象。所以多个样式之间用 ,
分隔,原生的 HTML 行内样式用 ;
分隔,样式属性命名采用小驼峰法。
style
通常用来绑定动态样式,元素的主要样式应该使用外部引入的 CSS 样式表
function HelloWorldComponent() {
return <div style={{color: blue, fontSize: 14px}}>Hello World!</div>;
}
既然 style
其实是 JS 对象,那么就可以把对象抽出来,从而实现动态样式:
const divStyle = {
color: 'blue',
backgroundImage: 'url(' + imgUrl + ')',
};
function HelloWorldComponent() {
return <div style={divStyle}>Hello World!</div>;
}
在 Vue 中可以通过计算属性实现动态样式
React 会自动添加 ”px” 后缀到内联样式为数字的属性后。如需使用 ”px” 以外的单位,请将此值设为数字与所需单位组成的字符串。
// Result style: '10px'
<div style={{ height: 10 }}> Hello World! </div>
// Result style: '10%'
<div style={{ height: '10%' }}> Hello World! </div>
但并非所有样式属性都转换为像素字符串。有些样式属性是没有单位的(例如zoom
,order
,flex
)
className 和 htmlFor
由于 class
和 for
都是 JS 关键字,所以在 React 里面使用 className
和 htmlFor
代替。
dangerouslySetInnerHTML
React 中使用 dangerouslySetInnerHTML
渲染 HTML,尽量不要用,容易导致 XSS 攻击。
// 需要传一个 key 为 __html 的对象
function createMarkup() {
return {__html: 'First · Second'};
}
function MyComponent() {
return <div dangerouslySetInnerHTML={createMarkup()} />;
}
Vue 中使用 v-html
指令渲染 HTML
11月19日内容汇总
JSX 的一些注意事项
使用 JSX 必须在 React 作用域内,这样才能编译。在如下代码中,虽然 React
和 CustomButton
并没有被直接使用,但还是需要导入:
import React from 'react';
import CustomButton from './CustomButton';
function WarningButton() {
return <CustomButton color="red" />;
}
JSX 中可以使用点语法,例如:
<React.Fragment></React.Fragment>
<Form.Item></Form.Item>
自定义组件必须大写字母开头,才能被识别为 React 组件。
React 组件名不能是 JS 表达式,如果需要动态渲染组件,需要先将 组件名赋值给一个大写字母开头的变量:
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
与 Vue 类似,React 的 props
花括号里面接受 JS 表达式:
// React 用法
<MyComponent foo={isShow ? "1" : "0"} />
// Vue 用法
<my-component :foo="isShow ? '1' : '0'" />
if
语句以及 for
循环不是 JavaScript 表达式,所以不能在 JSX 中直接使用。但是,你可以用在 JSX 以外的代码中。
React 组件通过 props
传字符串有两种做法,第一种直接通过字符串字面量:
// React 用法
<MyComponent message="hello world" />
// Vue 用法
<my-component message="hello world" />
另一种是通过表达式:
// React 用法
<MyComponent message={'hello world'} />
// Vue 用法
<my-component :message="`hello world`" /> // Vue的属性前面加上v-bind,后面的""里面就是JS表达式
React 如果没有给 props
赋值,它会有一个默认值 true
。
这点我觉得还是 Vue 做得好,可以手动指定 props 的默认值和类型,类型传错了还会给你警告,维护起来相当方便
React 中的 props
对象可以进行属性展开,下面两个组件是等价的:
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
下面这个技巧非常有用,选择只保留当前组件需要接收的 props,并使用展开运算符将其他 props 传递下去:
const Button = props => {
const { kind, ...other } = props;
const className = kind === "primary" ? "PrimaryButton" : "SecondaryButton";
return <button className={className} {...other} />;
};
高阶组件
高阶组件在 React 官方文档的说法是用于替代 mixins
实现组件方法复用。
高阶组件是参数为组件,返回值为新组件的函数
也就是说在组件外面封装了一层,把可以复用的方法都抽出来。
我看了一下文档的示例代码,觉得高阶组件的场景和 mixins
其实还是有区别的,而且 mixins
是可以全局混入的。文档上的示例我觉得更接近于 Vue 中的动态组件。
function withSubscription(WrappedComponent, selectData) {
// ...并返回另一个组件...
return class extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {
data: selectData(DataSource, props)
};
}
componentDidMount() {
DataSource.addChangeListener(this.handleChange);
}
componentWillUnmount() {
DataSource.removeChangeListener(this.handleChange);
}
handleChange() {
this.setState({
data: selectData(DataSource, this.props)
});
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}
使用的时候把组件传递给 withSubscription()
:
const CommentListWithSubscription = withSubscription(
CommentList,
(DataSource) => DataSource.getComments()
);
const BlogPostWithSubscription = withSubscription(
BlogPost,
(DataSource, props) => DataSource.getBlogPost(props.id)
);
之前不理解React 路由为什么要这样写,现在明白了,这其实就是高阶组件:
const NavbarWithRouter = withRouter(Navbar);
Vue 动态组件的 is
属性也可以接收一个组件作为参数,同时也能传递 props
:
<component :is="currentTabComponent" :values="values"></component>
11月18日内容汇总
React 组件生命周期调用顺序
挂载
组件实例被创建并插入DOM
constructor()
static getDerivedStateFromProps()
render()
componentDidMount()
更新
当组件的 props 或 state 发生变化时会触发更新
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
卸载
当组件从 DOM 中移除时会进行调用
componentWillUnmount()
错误处理
当渲染过程,生命周期,或子组件的构造函数中抛出错误时会进行调用
static getDerivedStateFromError()
componentDidCatch()
更多内容参考:
常用生命周期方法
2.x
的生命周期函数与新版 Composition API
之间的映射关系:
- beforeCreate -> 使用 setup()
- created -> 使用 setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- errorCaptured -> onErrorCaptured
注意:beforeCreate
和 created
在 Vue3
中已经由 setup
替代。
参考资料
Vue 3.0 有很多借鉴了 React 的地方,看了 React 文档之后 可以对比着看下 Vue 3.0 。
Vue 3.0 修炼手册
抄笔记:尤雨溪在Vue3.0 Beta直播里聊到了这些…
API 手册 - Vue 组合式 API
Koa 快速入门系列
【从前端到全栈】- koa快速入门指南
【进阶篇】koa+Mysql的全栈之旅
【全栈之旅】NodeJs登录流程以及Token身份验证
11月17日内容汇总
React Hooks的用法
函数组件有重大限制,必须是纯函数,不能包含状态,也不支持生命周期方法。React Hooks 的设计目的,就是加强版函数组件,完全不使用"类",就能写出一个全功能的组件。
四个常用Hooks
useState()
useContext()
useReducer()
useEffect()
useState()
用于为函数组件引入状态(state)。纯函数不能有状态,所以把状态放在钩子里面。
import React, { useState } from "react";
export default function Button() {
const [buttonText, setButtonText] = useState("Click me, please");
function handleClick() {
return setButtonText("Thanks, been clicked!");
}
return <button onClick={handleClick}>{buttonText}</button>;
}
useEffect()
用来引入具有副作用的操作,最常见的就是向服务器请求数据。以前,放在componentDidMount
里面的代码,现在可以放在useEffect()
。
useEffect(() => {
// 这里调接口
}, [dependencies])
useEffect()
接受两个参数。第一个参数是一个函数,异步操作的代码放在里面。第二个参数是一个数组,用于给出 Effect 的依赖项,可以省略。组件第一次渲染时, useEffect()
就会执行。当依赖项的数组发生变化, useEffect()
也会执行。
Vue 3.0 的Composition API
借鉴了React Hooks
轻松学会 React 钩子:以 useEffect() 为例 - 阮一峰
React Hooks 入门教程 - 阮一峰
React中Fragment的用法
与 Vue 类似, React 组件要求 return
的内容必须由唯一根元素包裹,否则就会报错。
如果希望在不额外创建DOM元素的情况下 return
多个元素,就可以用到Fragment。
render() {
return (
<React.Fragment>
Some text.
<h2>A heading</h2>
</React.Fragment>
);
}
Vue 中的 template 也是虚拟元素,但还是有区别
在 template 中的元素必须要唯一根元素包裹
template 仅仅只是在条件渲染的时候可以不用引入新的DOM元素
Vue 3.0 中也提供了类似 React 的 Fragment
Fragment还有一种简写语法 <></>
。<React.Fragment>可以接受键值或者属性,例如在列表渲染的时候绑定 key
,但是 <></>
不行。
render() {
return (
<>
Some text.
<h2>A heading</h2>
</>
);
}
另外react 16开始, render支持返回数组,可以减少不必要的节点嵌套。
export default function () {
return [
<div>1</div>,
<div>2</div>,
<div>3</div>
];
}
Vue 3.0 的 render
函数同样也支持返回数组
组件继承的两种写法
以上面的Fragment为例,如果只引入 React
,那么使用就要像这样 <React.Fragment>
import React from "react";
function App() {
return (
<React.Fragment>
{/* Some text here */}
</React.Fragment>
)
}
如果像下面这样引入,就可以像这样使用 <Fragment>
import React, { Fragment } from "react";
function App() {
return (
<Fragment>
{/* Some text here */}
</Fragment>
)
}
严格模式
嵌套在 <StrictMode>
标签中的元素将开启严格模式,用来突出显示应用程序中潜在问题。与 Fragment
一样,StrictMode
不会渲染任何可见的 UI。它为其后代元素触发额外的检查和警告。
严格模式检查仅在开发模式下运行;它们不会影响生产构建。
import React from 'react';
function ExampleApplication() {
return (
<div>
<Header />
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
<Footer />
</div>
);
}
11月16日内容汇总
React事件类型
输入框:onChange,onKeyUp
按钮:onClick
React监听回车事件
<Input placeholder="www.chao99.top" onKeyUp={this.onKeyup} />
onKeyup(e) {
if(e.keyCode === 13) {
this.handleBtnClick()
}
}
报错信息
Cannot update during an existing state transition (such as within render
)
这个一般是事件处理函数的 this
没有绑定导致的 。
报错信息
Failed prop type: You provided avalue
prop to a form field without anonChange
handler. This will render a read-only field.
受控组件表单必须要绑定 onChange
事件,否则这个表单就是只读,无法修改。
不能修改的前提是 value
被赋了一个常量。如果将空值 null
赋给 value
,还是可以修改的。
受控组件:自身的value值由组件的state托管,这也是 React 官方推荐的。
<Input value={this.state.name} onChange={this.handleChange} />
上面的代码中, value
用来给表单赋值, onChange
事件用于触发事件处理函数修改 state
。在 Vue 中直接就是一个语法糖 v-model
。
Vue 中的<input v-model="searchText">
等价于<input :value="searchText" @input="searchText = $event.target.value">
非受控组件:value由第三方库或者DOM进行托管。
<Input type="file" ref={this.input}/>
文件上传是典型的非受控组件。
React修改antd原生样式
在 Vue 中直接修改是不生效的,需要通过样式穿透 >>>
或 ::v-deep
。
在 React 里面,调出控制台找到组件对应的类名,然后在样式文件中直接修改就行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。