From Vue to SwiftUI

SwiftUI是苹果公司推出的现代 UI 框架,可以更加快速地为 App 构建 UI。从前端开发者角度来看,SwiftUI跟前端 UI 框架Vue有很多相似的地方。以下将以开发一个“TODO-List”应用的方式,从「入口」、「构建 UI」、「更新 UI」、「动画」四个方面展示SwiftUIVue的异同,简单入门SwiftUI

入口

In Vue

0.1.png

Vue通过其提供的createAppAPI 来创建应用,App根组件组件(一般由defineComponent定义)是构成 Vue 应用的基本单位。 mount("#app")是将应用挂载到 dom 元素上(HTML 文件中相应的idapp的元素)

In SwiftUI

0.2.png

SwiftUI的入口@main修饰的 App,ContentView的一个View类型的结构体,View是构成 SwiftUI 应用的基本单位。

构建 UI

"TODO-List"包含一个输入框和一个“TODO”列表。 VueSwiftUI都采用“声明式“的方法来构建 UI

In Vue

1.1.png

Vue通过defineComponent来定义组件,图中定义了AppItem两个组件,App组件包含输入框和每条“TODO”的展示,Item组件是“TODO”具体视图,Vue 通过组合组件来构建应用。 Vue依赖 HTML 提供的基本视图元素(比如divbutton),并通过jsx这样一种DSL来编写视图,样式修改则是通过 CSS 来实现,跟视图的交互也是依赖 HTML 基本元素自身的交互(比如buttonclick事件)。

In SwiftUI

1.2.png

SwiftUI的组件是一个实现了View协议的结构体,通过 SwiftUI 提供的一系列基础组件(比如HStackText),可以很方便地编写 UI。修改组件则是通过一系列被称为modefier的方法来实现的,modefier比 CSS 更加强大,除了修改样式,还能配置组件,修改组件逻辑,类似 Vue 中的高阶组件。

更新 UI

通过输入框增加“TODO”,通过“X”按钮删除“TODO” VueSwiftUI都提供数据变更响应式更新 UI 的能力。

In Vue

2.1.png

Vue通过其提供的refAPI 来定义可响应式更新视图的状态,当状态变更时,视图会相应的变更,无需手动更新视图。其中input输入框和inputText状态的同步用到了 Vue 的双向绑定特性v-model

In SwiftUI

2.2.png

SwiftUI通过@State这样一种PropertyWrapper来修饰属性使其具有响应式更新 UI 的能力。其中TextField输入框和inputText状态的同步用到了 SwiftUI 的双向绑定特性Binding$inputText)。

关于父子组件通信、孙子组件通信、外部数据源这些数据管理方案,Vue 和 SwiftUI 都有一些相似的解决方案,就不再演示了。

动画和生命周期

视觉的变化一般需要有动画来过渡,在每条“TODO”出现时添加过渡动画。

In Vue

3.1.png

Vue基于 CSS 提供的动画能力,先使用transition配置过渡动画的各个参数,再通过状态的变化使 UI 元素的某些属性发生变化从而触发动画,这里使用onMount生命周期钩子,在组件挂载时,改变状态showed使元素的transform属性发生改变,触发位移的过渡动画。

In SwiftUI

3.2.png

SwiftUI的动画类似,使用animation配置过渡动画的各个参数,再通过状态的变化使 UI 元素的某些属性发生变化从而触发动画,onAppear则是在元素显示时触发。

SwiftUI的动画更加方便和强大,上文介绍的动画声明方式被称为“隐式动画”,除此之外还有“显示动画”。

3.3.png

将状态变化逻辑放在withAnimation里,则相应的 UI 动画会自动执行,并且 SwiftUI 还给元素属性的变化设置了默认的过渡动画。

最后的效果图:

Vue
SwiftUI

总结

VueSwiftUI在构建 UI、状态管理等方面有很多相似之处。 SwiftUI在语言本身、动画等方面具有更加优秀的表现,尤其在样式编写方面,modefier 比 CSS 丝滑和强大很多。 但是 Vue composition API / react hooks API 对 efftecs 的隔离复用、对逻辑的组合,暂时没有看到 SwiftUI 有相应良好的解决方案。