1. 各司其职
让HTML、CSS和JavaScript职能分离(并不是说代码不能写在一起)
- HTML/CSS/JS各司其职
- 应当避免不必要的由JS直接操作样式
- 可以用class来表示状态
- 纯展示类交互寻求零JS方案
2. 组件封装
好的UI组件具备正确性、扩展性、复用性
2.1. 基本方法
- 结构设计
- 展现效果
- 行为设计
- API(功能)
- Event(控制流,使用自定义事件解耦)
轮播图示例:
2.2. 改进:插件化
- 将控制元素抽取成插件
- 插件与组件之间通过依赖注入方式建立联系
class Slider{
constructor(id, ...args){
// ...
}
// ...
registerPlugins(...plugins){
plugins.forEach(plugin => plugin(this))
}
}
const slider = new Slider('xxx');
// 定义好功能,需要时以插件形式注入
slider.registerPlugins(pluginController, pluginNext, pluginPrevious);
2.3. 改进:模板化
- 将HTML模板化,更易于扩展,做到数据驱动
2.4. 改进:抽象化(组件框架)
// 通过继承实现
class Slider extends Component{
constructor(...args){
// ...
}
registerPlugins(...plugins){
// ...
}
render(data){
// ...
}
}
2.5. 更多改进
- 考虑嵌套的情况,比如子组件作为父组件的插件
- CSS的模板化(可考虑css in js方案)
3. 过程抽象
用来处理局部细节控制的一些方法
应用函数式编程思想
过程抽象:为了能够让“只执行一次”的需求覆盖不同的事件处理,将这个需求剥离出来的过程
// 高阶函数
function once(fn){
return function (...args){
if(fn){
const result = fn.apply(this, args);
fn = null;
return result;
}
}
}
const test = once(() => {
console.log('bar');
})
test(); // bar(只输出一次)
test();
test();
声明式与命令式
// 一.、命令式
if(xxx){
fn1()
} else if(yyy){
fn2()
} else if(zzz){
fn3()
} else {
// ...
}
// 二、声明式(扩展性比上面的命令式更好)
function toggle(...action){
return function(...args){
// 相当于循环执行actions中的函数
let action = action.shift();
actions.push(action);
return action.apply(this, args);
}
}
toggle(
fn1,
fn2,
fn3,
...
)