前端跨端复用实际(一)
咱们的页面次要由两局部组成: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'
针对问题二,我的项目文件目录构造为,我的项目启动后,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}
这样就能够做到最大水平上复用代码,并且放弃架构的清晰可保护