在08年以前谷歌还没推出chrome和node.js的时候,还有微软没有推出XHR概念的时候。web开发还是服务器渲染的TABLE布局显示。
在08后之后谷歌发布了chrome和node.js还有安卓手机系统之后。客户端的设备就越来越多了。如果还是采取第一种的方式,系统的复用性就大大减半。这个时候就有人提出了result api的方案解决数据复用性。也就有了如今的开发模式。
大多数的阅读者都在反应,能不能给dome。我分享的文章多数是思路问题,实现的过程有很多方式...程序员应该具备的能力是思路,而不是所谓的“精通原理”。懂原理虽然是好,但是你看源码的实际意义也不只不过是为了看作者的思路。我见过很多背原理很精通的,但缺没有想到把这些思路用在什么业务场景进行设计的人实在太多。这一类定义为码农还是搬运工好呢?
这是在js还没成为流行的趋势的时候形成的一种模式。但是如今已经是2020年了,几乎一个端JS都能做完的事情。为了统一,国内的方案的都是基于一门自己的核心语言做完基础栈,然后通过这个语言进行编译成对应的开发平台进行代码复用。以React Native,Taro为例子。
现在的解决方案都是这样。那么到了使用者是如何去做的呢?
由于前端是一个奇葩的世界,我不知道这些UI框架还能坚持几年。从历史来看Jquery在06年发布,08发行了angularjs,10年React,11年Angular2。这时间线来看,jQuery的霸主地位也维持了4年左右吧。而且随着Web Components不断完善,你很难确保未来工程化,未来再打包上做优化,可能会有一批新的非编译Web Components的兴起,比如polymer,svelte框架。又比如为前端的即将到来一般的企业应该如何快速迁移呢?如果按照上图的模块,和重构是没有什么区别了。
这个时候我就在想一个问题,能不能再抽象一层,提出这个概念的人是字节跳动的ArcoDesign,但是在我半个月的阅读源码思路的时候,发现并没有实现handle的抽象。我来说说我的思路吧,这模式只是适合中小产业做迁移。比如React迁移Vue。因为一般的企业更不没有资金去做类似Flutter,Taro等编译型框架!!!
动手就干。
先看看模块路径
React 先用回调实现简单的思路
//App.tsx
function App() {
const [data, setData] = useState(0);
const clickButton = useCallback(() => {
getTest(data, (res) => {
setData(res)
})
}, [data])
return (
<>
<button className="bg-red-400 border-red-400 rounded-md p-2 text-white shadow-md m-8"
onClick={clickButton}
>
Get Test {data}
</button>
</>
);
}
export default App;
// handle.js
import { TestModel } from "../entity";
import { TestService } from "../service";
export function getTest(data: any, setData: Function) {
TestService<TestModel>().then(test => {
console.log(test.version)
setData(data + 1)
})
}
// server.js
import { TestMock } from "../mock"
export function TestService<T>(): Promise<T> {
return new Promise((resolve, reject) => {
const mock = TestMock;
resolve(mock)
})
}
VUE实现
我们再看看 VUE能不能这么实现,vue已经4年没怎么用了,我直接用Vue3的hooks版本吧。(其实我更想使用NG来实现...不过还好Vue的ts,去掉babel和ng类似。)
//代码有点长。。。
<template>
<div class="hello">
<button
className="bg-red-400 border-red-400 rounded-md p-2 text-white shadow-md m-8"
@click="clickButton"
>
Get Test {{ data }}
</button>
</div>
</template>
<script lang="ts">
import { Options, Vue } from "vue-class-component";
import { getTest } from "../handles/index";
@Options({
props: {
msg: String,
},
data() {
return {
data: 0,
};
},
methods: {
clickButton() {
getTest(this.data, (res: number) => {
this.data = res;
});
},
},
})
export default class HelloWorld extends Vue {
msg!: string;
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
为了更好的扩展,当然不能使用回调进行操作啦!。
一般的前端会使用Promise进行操作。当然不是使用Promise,如果你是一个追求高可用的程序员,这个时候会考虑的肯定是Redux,Mobx来进行管理。但是这些都需要有一个store进行操作。入口注入sotre。我就不太喜欢了。
我这里使用rxjs和单列进行管理,我不太喜欢约束开发。
修个后React
function App() {
const [data, setData] = useState(0);
useEffect(() => {
TestSubjectFactory.getInstace().$name.asObservable().subscribe(res => {
setData(res)
})
}, [])
const clickButton = useCallback(() => {
getTest(data)
}, [data])
return (
<>
<button className="bg-red-400 border-red-400 rounded-md p-2 text-white shadow-md m-8"
onClick={clickButton}
>
Get Test {data}
</button>
</>
);
}
export default App;
修改后的 VUE
<template>
<div class="hello">
<button
className="bg-red-400 border-red-400 rounded-md p-2 text-white shadow-md m-8"
@click="clickButton"
>
Get Test {{ data }}
</button>
</div>
</template>
<script lang="ts">
import { Options, Vue } from "vue-class-component";
import { getTest } from "../handles/index";
import { TestSubjectFactory } from "../service/index";
@Options({
props: {
msg: String,
},
data() {
return {
data: 0,
};
},
methods: {
clickButton() {
getTest(this.data);
},
},
created() {
TestSubjectFactory.getInstace()
.$name.asObservable()
.subscribe((res) => {
this.data = res;
});
},
})
export default class HelloWorld extends Vue {
msg!: string;
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
当然这只是设计上的参考,但是基于这个思路你又会想到做什么事情呢?关注我让你学会更多的维护性思路。
至于代码基础那些资源,你们还是看其他文章喷我的那些博主吧,他们分享的内容居多是教学上的基础资源。