Vue3学习笔记

组合式的优势

属性不再全部附加在一整个data上,不至于弄成一大坨。

写代码也更倾向于函数式编程,减少了状态的随意传递,后续维护性会更好一些。

Vue2写法升级到Vue3

总的来说还是挺顺利的:

  • 改写mixin

  • 去掉所有this,包括属性和函数

  • 属性调用改为value形式,包括普通属性和计算属性

  • 通过defineProps改写props

  • created放到setup里面

  • watch改写

  • onMounted改写

  • 通过defineEmits改写emit

  • 通过defineExpose暴露API

如何将属性方法传递给dat.GUI?

用Pinia,这个才1K,大小能接受。

但是方法不好跨组件调用,从这个问题来看,我程序设计本身有问题,这些方法不应该放在.vue文件中,应该独立出去才对。

经过思考后,感觉是我程序设计有问题,正确的形式应该是下面那张图。

程序设计思路

程序设计

跨Hooks共享状态

状态管理 | Vue.js

如果你有一部分状态需要在多个组件实例间共享,你可以使用 reactive() 来创建一个响应式对象,并将它导入到多个组件中。

错误的操作

  • 给无需响应的属性设置了响应式(不会随着时间变化的都不应该设置为响应式,区分清楚配置和响应式属性;还有一些是只有在用户主动触发交互才会渲染的,比如lockView,这种也不应该设置为响应式;只有属性变化会自动触发渲染的才应该设置为响应式)

  • 逻辑没有抽离到hooks中,全部写到了Component.vue里面

3D项目的程序设计

以汽车产业链项目为例。

业务开发模式

用纯做业务开发的流水账模式来组织程序,类似这样:

业务开发模式

框架开发模式

业务开发模式

业务和组件的分层边界

从程序执行流程的角度来看业务方和组件方的边界:

业务开发模式

目标策略图项目在程序设计上的反思

状态管理其实就是替换掉focus

其他的都不用变,可以沿用。

切换视角调用的是focus(),focus里面调用了showAnnotation/hideAnnotation

哪些内容有State上的变化:

  • Camera:几个不同的视角

  • 模型:透明、隐藏、默认、高亮

  • 注解和连线:显示、隐藏

  • Tooltip:显示、隐藏

我自己基于当前的代码,融入State机制和插值,就可以了吧?

改进方案-用State消化掉用户的交互

  • 枚举所有物体的所有状态

  • focus改为setState,这是一个分发函数

  • 提供一个useState函数,获取页面上所有的元素,判断isDirty=true,执行状态插值的渲染操作

  • 提供状态识别函数,比如toNearestView(),将用户的交互转换为对应的状态

配置项的切换

怎么实现HDR的切换?

如何绘制edge线条和注解标签

如何绘制节点

还是用Trois,这是UI层

如何操控动画

Trois的必要性

似乎并不大,页面上的内容不多。

场景中通用的部分,完全可以实现配置化,比如灯光、Renderer;而且都是基于State的配置。

如何切换视角

GSAP根据Camera配置切换。

如何切换透明效果

如何与业务UI部分通信

通过Vue3的defineExpose对外提供API

如何接入业务方的Vue2、React框架?

controller类是否有必要?

目前每一个模型对应了一个controller,用于操控其动画

如果没有这个,也不好,无法细粒度控制模型了。

目前这里控制的功能包括:

  • 辉光(未实现)

  • 旋转:RotationController

  • 动画:GLTFController

  • 裁剪:Head,不确定;KnowledgeGraphStorageWrapper、SkinOfStorage

  • 环绕:QualityInspection,还加了个灯光、体积光手电筒、文本标签(已弃用)

  • 放大:Ring

  • Scene:不该放这里

注意:我们整个车搞成一个模型后,onBeforeRender需要放在整体模型上调用。

index.ts自动加载机制未实现

会不会导致传入的配置项太多?

类似海外图解财报项目那样,搞了很多无用功。

程序设计是否会让我们复杂化?

还是说基于hooks的组合式API模式更好?

这种肯定是不好的:

1
2
3
4
5
6
7
export function showModel(model: Group) {
model.traverse((child: Mesh) => {
if (child.material) {
(child.material as MeshBasicMaterial).visible = true;
}
});
}

合理的应该是model.show()

是否需要引入Pinia?

针对模型的状态管理?

针对配置项的管理?

有没有必要搞一个基于Three的更上层的封装?

其实就是Trois,声明式使用Three.js

TSX/JSX:以Vue框架开发基础组件

我们开发的组件往往都是UI组件,如果完全脱离Vue框架,其实效率上是有所降低的。但是如果以业务开发的模式,用template编写组件,又会遇到UI层难以复用的问题。

我们可能会用这种方式编写组件:

1、将vue组件对象传递到类内部,但是这样就耦合了

2、vue组件提供【事件api】,然后通过总控去调用这些api,实现状态切换的效果

但是这样不好无限递归渲染(比如Element.update()方法),写得很死,严重限制了组件的扩展性,缺少了动态性。

这时候引入TSX/JSX,就能解决这个问题了。

由于我们是Vue3+Vite,因此可以参考这个示例

如果是用的jsx,也可以参考这个示例

资料

Vue3视频教程:

https://www.bilibili.com/video/BV1dS4y1y7vd?p=65&vd_source=1ddc293a4439c7106ebd7878040f7c81

后台项目(集成了各种常用组件,很不错):

GitHub - pure-admin/vue-pure-admin: 🔥 ✨✨ ✨ Vue3+Vite4+Element-Plus+TypeScript编写的一款后台管理系统(兼容移动端)

上面这个后台的教程:

https://www.bilibili.com/video/BV1kg411v7QT/?spm_id_from=333.337.search-card.all.click&vd_source=1ddc293a4439c7106ebd7878040f7c81