我们的页面主要由两部分组成:1.逻辑 2. 视图
如果想要跨端复用的话,那么可以从上面这两方面入手
一般跨端的页面有几种情况
- 需求一样,对应页面中的逻辑也就完全一样,视图层只是使用的UI组件名字不一样(h5中写div,小程序中写View),需要完全复用逻辑层
- 需求部分一样,对应起来就是逻辑和UI组件也是只有部分的差异,需要复用公共部分
- 需求完全不一样,不同端各自写自己的,不需要复用
对应的有2种复用方案
复用逻辑,多端各自注入UI组件
将逻辑抽离到一个公共的common模块中,然后在各端的项目中,引入对应逻辑实现,将逻辑注入到UI组件中
具体代码见:
// model.tsx
export const model = (props: any) => {
const [name, setName] = useState(props.name)
const [age, setAge] = useState(props.age);
return {
name,
setName,
age,
setAge,
...props
}
}
// mini view.tsx
import { model } from './common/model'
const miniView = (props: any) => {
const { name, setName, age, setAge } = model(props)
return <View onClick={setName}>
<Text>{name}</Text>
<Input value={age} onChange={setAge} />
</View>
}
//h5 view.tsx
import { model } from './common/model'
const h5View = (props: any) => {
const { name, setName, age, setAge } = model(props)
return <div onClick={setName}>
<p>{name}</p>
<Input value={age} onChange={setAge} />
</div>
}
这样做的好处
- 逻辑复用,提高效率
- 在model层和UI层都可以更改逻辑和视图,针对跨端的页面需求部分一样的情形,比较友好,可以灵活调整。公共逻辑写在model中,差异逻辑写在View层
复用逻辑+视图
方案一的方式是将逻辑和UI分离,那么如果我们将这两者一起复用,那么提效会更明显,但是又会遇到以下问题
- 各端底层UI组件不一致
每端会存在各自的一些特定的调整
针对问题一,底层UI组件不一致的问题,可以通过引入一个胶水层,打平各端api来实现,然后再修改引用路径// h5 rn mini引入View的方式都相同 import { View } from 'XXComponents' //在编译时修改引用路径 // h5 index.ts import { View } from 'XXComponents/h5' // rn index.ts import { View } from 'XXComponents/rn' //xxComponents/h5中 const View = div export View //xxComponents/rn import { View } from 'react-native' export View = View
针对问题二,项目文件目录结构为,项目启动后,common文件夹以软链接的形式,copy到h5 | mini | rn中
├── package.json ├── projects │ ├── common │ ├── h5 ├── common ├── package.json │ ├── mini ├── common ├── package.json │ └── rn ├── common ├── package.json
比如我们有个PageA(三端都有),A中有组件B(三端都有),B组件中又有个组件C(h5,rn中有,小程序中没有),类似下图
// pageA
import B from './Components/B' // 引用common文件夹中的B组件
import C from '../../Components/C' // 引用各端自己定义的C组件
<PageA>
<B>
<C></C>
</B>
</PageA>
那么处理方式就是:
ComponentC的逻辑层写在Common文件夹中,ComponentC的View层写在各端文件夹中,h5 | rn 同时将ComponentC的逻辑引入,mini不引入逻辑代码。代码如下
// h5 componentC
import Model from '../common/modelC'
const ViewC = () => {
const state = Model()
return <div>
{state.name}
</div>
}
// rn ComponentC
import Model from '../common/modelC'
const ViewC = () => {
const state = Model()
return <View>
{state.name}
</View>
}
// mini ComponentC
const ViewC = () => {
return null
}
这样就可以做到最大程度上复用代码,并且保持架构的清晰可维护
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。