一、 ts项目使用css规范 和引入文件
(1)模组化:每个jsx或者tsx文件都是被视为独立存在的原件,原件包含的所有内容也都是独立存在。 所以css引入最好改为引入对象独立加载css(这种方式就是css in js),以对象形式动态注入样式。实现按需加载样式,也会避免一定的样式冲突
css模块化规范命名文件,module.css结尾
import styles from "@/App.module.css";
import logo from "@/assests/images/logo.svg";
1. 内联样式都是驼峰,是为了和dom节点的属性保持一致
2. 浏览器兼容除了ms其他都是大写开始
3. 如果值为数字,react会自动拼接px,写:fontSize: 20有效。字符串不行
const divStyle = {
backgroundColor: 'red',
WebkitTransition: 'all'
msTransition: 'all'
fontSize: 20,
}
function App() {
return (
和es6中的class类进行区分,样式命名为className
<div className={styles.parentBox} style={{}}>
{robots.map((r) => (
<Robot id={r.id} name={r.name} email={r.email} />
))}
</div>
);
}
(2) 还要给css加上类型声明文件*.d.ts。 d.ts结尾的文件只包含类型声明,不会被编译不会被打包。实际上这个声明文件脚手架里已经有了,包含各种支持,module.scss module.sass svg png webp。我们只需要新建css文件以module.css结尾即可
// 导出css对象,以css结尾的文件
企业微信截图_16197632131830.png
二、 使用插件typescript-plugin-css-modules 解析css文件自动生成ts 所对应的引用类型(这样写引入后就会有样式名提示了)
(1) 在tsconfig.json启用插件
{
"compilerOptions": {
"plugins": [{ "name": "typescript-plugin-css-modules" }]
}
}
(2) 注意:使用这个必须要使用项目的ts版本,也就是切换到工作区版本,具体怎么切换为工作区版本,点我查看第一篇第五要点
(3)效果
企业微信截图_16197545613453.png
二、思考:设计思路上的区别造就了不一样的Vue和React
1. 从更新粒度上理解
Vue:更改数据,基于 Object.defineProperty 或 Proxy 的响应式依赖收集机制(在getter中实现了依赖收集)精准的触发视图更新,不会触发子组件重新渲染
React:遵从Immutable(不可变【函数式编程】)的设计思想,永远不在原对象上修改属性(原对象未变,无法定位修改部位)
由于没有响应式的收集依赖,React 只能递归的把所有子组件都重新 render一遍,然后再通过 diff算法 决定要更新哪部分的视图(shouldComponentUpdate优化)
//tips:Immutable好处
原理:持久化数据结构,不可变数据
1.final const 增强语义,提高代码可读性(快速定位问题),防止人为错误不小心修改
2. 良好的函数/方法通常不会更改参数对象的值,否则容易产生隐晦bug。
不可变数据在多个方法调用后防止出现连串问题,可以快速定位, 也方便链式调用(数据修改是bug的源头【函数式编程】)
3. 直接比较原对象和新对象的引用地址就可以知道是否发生变化,大大提高了比较的性能
(state,props 可以直接使用 === 来比较,确认是否发生了变化)
问题:
1. 需要创建更多对象,占内存。这和性能优化上的好处比较起来微不足道
2. 类似下面例子修改obj需要写更多代码,深拷贝也会有性能问题,可以使用库immer.js
(使用proxy实现,共享未修改部分的内存,只更改变化部分和节点的父级创建新的关联关系)
(1) 不可变意味着不修改源数据,修改的时候直接返回新的数据。
state = {
obj: {a: 1, b: 2},
}
// 修改obj.b
modifyObj = () => {
this.setState({
obj: {
...this.state.obj,
b: 3,
}
})
表现在代码上就是上面这样:
由于react与redux本身就是推崇函数式编程的,所以官方是不推荐直接修改对象或数组
// 直接修改obj.b = 3,然后setState({ obj }) 也是可以的
(2) 不推荐直接修改数据的第二点原因:
由于在pureComponent中shouldComponentUpdate是浅比较,
如果直接修改父组件对象或者数组的话会导致组件并不会发生更新
//pureComponent 就是一个自带shouldComponentUpdate比较的React.Component
//实现了只比较引用地址的变化来判断是否更新
2. 在逻辑复用方面
vue:vue2用mixins抽出公用逻辑(命名冲突,不易维护)vue3 有Composition API 在设计上更为清晰(拆分逻辑,引入再到setup中使用)
React :
renderProps 抽象出组件负责行为,然后将state作为参数传入外部返回组件的函数中.类似vue的slot
1. 公共逻辑在Mouse
<Mouse render={mouse => (
<ChildComponent {...this.props} mouse={mouse} />
)}/>
2. 在mouse中渲染ChildComponent
this.props.render(this.state)
3.渲染执行render的时候将state给到了ChildComponent ,ChildComponent 将这个数据合并到props就可以使用了
高阶组件HOC:组件作为参数传入函数,返回一个组件。比mixin更多可拓展性(之前工作遇到过一个负责人,写vue喜欢抽离很细的组件,应该就是受这个的影响)
hook :比HOC 或者renderProps 更好,钩子函数hook 是纯函数,使用简单清晰
tip :ts是未来,在ts的支持上 React 更好。vue3也支持
高阶组件
公用组件,获取组织数据。使其拥有orgTree的props,
function HOC(wrapperComponent) {
return class getOrgTree extends React.Component {
state = { orgTree: [] }
componentDidMount() {
fetch('xxxxxxx').then(orgTree => this.setState({ orgTree }))
}
render() {
return <wrapperComponent orgTree={this.state.orgTree} {...this.props} />
}
}
}
社区活跃度react是大于vue的,丰富的解决方案也是选择react的理由
为什么说vue适合小而精的项目,react则更适用于偏大的项目。
vue的组件由于一些复杂逻辑的复用方式和组件可应用模式的不足,以至于在大型项目中复用性与设计性是不如react。
虽然vue简单好用快速开发都是优点。用react做大项目更需要 好的设计,拥有更好维护的代码(高质量的代码可读性强很重要)。
但是选择react要求领头人足够优秀,因为社区东西确实多:状态管理,中间件,路由。瞎选型最后也是写成一坨难以维护的东西。
从vue3的设计来看,Composition API在设计上抽离单一功能提高代码可读性,也对写代码的人提出了一些要求,最近看github上的项目,逻辑全部都整在一个setup里也是难以维护的
网友评论