vue3.0 使用踩坑
2020, Nov 28
最近一周正式使用vue3.0编写项目。
在文档尚不健全的情况下,编写中踩了一些小坑。
看法
- 优点
3.0出来的响应式API,让编写代码有种编写原生代码的感觉,写法较2.0可以写的更加简洁,在编写表单页面时,一套逻辑写下来自我感觉比2.0能少些很多非逻辑代码。通过编写自定义hook,可以有效地封装一些逻辑,而不需要使用mixin了。可能是最近写react比较多,所以对3.0的编写并不会觉得有什么陌生,所以所谓的面条代码的问题倒还好。 - 难点
ref与reactive,给这两个api写ts的类型定义有点难搞,因为一个数据往往有初始值,如果直接拿这两个api去定义一个值,就会遇到api返回的类型与目标模型不相同的问题(会在外层包裹一层UnwrapRef)。思考了一下后,决定定义一个state拿reactive初始化,当作原来的data字段,所有要存储的值都是state的一个属性,这样就避免了初始值的问题。这也是带来的所谓心智负担吧。更新:看了reactive的定义,当传入的类型变量不同,返回的类型定义也是不同的,现在不使用state,一个个初始化具体去定义也可以了。 - 对比react
写react,个人很喜欢写函数式组件,看起来非常简洁,API非常的少,掌握不超过十个api,写起就react就没什么问题了。而vue3.0编写的第一感受就是,编写逻辑的方式,真的和react有点相似,摒弃了插槽式的代码编写习惯,相似的逻辑放在一起,3.0通过更多的语义化的api,方便了开发,比如生命周期钩子,同比react,我可以更明确的掌握代码的一举一动。不过,写了vue3.0以后反而更能体会到的react的简洁,这能天下代码殊途同归?如果公司需要明确以后主要要用什么开发,这也许会成为一个问题。
记录
关于基础的新知识就不说了,主要说一下在开发中遇到的一些小问题。
- ref与reactive
之前也提了,这两个api是本次更新的重点,是关键的响应式api,ref主要用来定义值变量,reactive主要用来定义引用变量。有这样一个场景,如果你有个detail变量需要声明,等请求来具体值后再修改值,通常我会使用let detail:Detail|null = null,规避这个问题。interface Detail{ a:number, b:string } let detail:(Detail |null)= reactive(null) // error const getDetail =async ()=>{ // ...... res = await getData() detail = res.data }这样看起来是没错的,但是在初始化定义的时候就会报错,提示
Argument of type 'null' is not assignable to parameter of type 'object',reactive需要存储的数据初始化的数据类型是引用类型的,这就很尴尬,同理ref也有类似的问题,解决方法我想是在所有可变数据的最外面套一个state,让可变数据成为state的一个属性,可以规避掉一些问题。
但是我在编写template模式的代码时遇到问题,一个ref定义的变量a,在模板里必须用a.value,才能渲染出来,这和我在网上看到的,模板中无需添加value是不一样的。 - 自定义hook
原来的vue想要复用逻辑,用mixin,正如大家所说,出问题很难找,原来又没有ts,不熟悉代码的人,接手一段代码可能会产生疑惑,这个变量怎么在当前组件没有,怎么就可以用,也许是通过mixin混入进来的,现在可以自定义一个hook,和react一样,就很舒服,编写hook的时候要注意同样,最好所有需要监听变化的值用一个state给包裹,用reactive去定义,。 -
编写方式
当前我使用的是普通组件靠template去渲染,涉及到复杂逻辑、表单页面用tsx模式去编写。这种配合虽然有点奇奇怪怪,也意味着,我能在写出来的逻辑,在vue3.0里同样也能写出来,这减少了入手难度。 - 插件使用
vue-router,vuex两个官方插件已经基本稳定了,在本次编写中也使用到了,不得不说,文档地址有点难找,具体的用法就不说了,说一点,在vue-router的路由ts里,在router.beforeEach里,我想调用vuex的action,我本以为引用useStore,就可以引用到。得,最终还是和上个版本一样,引用store的定义文件,这让人有点疑惑,我已经先初始化了store,为什么不能用hook调用呢~~~~
结语
vue3.0的首次正式使用,让人有一种编写react的感觉,附加的hook函数,方便了开发者使用,上手难度相对于2.0肯定是提升了,而且提升不少,写过react的应该上手不难,等本次开发结束后,可能要等到3.0的库更完善了才会继续使用吧。