看了千万项目的 vue 代码,我陷入了沉思

前言

哈喽大家好,我是 SuperYing 。最近接了个成本千万级的业务系统运维工作,前端是用 Vue3 写的。看了代码之后,我大为震惊,让我不得不重新思考下使用 Vue3 的正确姿势。

本文设计 Vue3 computed watch 以及 ref 的相关说明及反面案例

正文

业务场景:

某业务单据管理模块,单据详情页面允许同时打开多个(单据 id 不同的情况下),需要根据不同的操作类型 (新增、查看、编辑等)对页面元素进行控制,如:查看操作不允许任何编辑操作,新增/编辑操作则允许编辑。操作类型 会在从上级页面跳转时添加到 URL 参数上,即使用 vue-router push 函数参数的 query 属性实现。

项目代码

清楚了业务,我们来看看原项目的小伙伴是如何实现的:

js 复制代码
const route = useRoute()

const isView = ref(route.query.opType === 'view')

watch(
   () => route,
   (newVal) => {
       if (newValue.query.opType === 'view') isView.value = true
   },
   {
       deep: true,
       immediate: true
   }
)

以上是精简过的代码,核心思路是通过 isView 来控制页面元素的编辑状态,isView 的值由操作类型 route.query.opType 确定,若其等于 view,则为 true,否则为 false

分析

上面代码看似是实现了业务功能,监听路由 route 变更,以更新 isView 的值,达到控制页面元素编辑状态的目的。

那么哪里让我陷入沉思了呢?主要有以下两点:

  1. isView 的值仅仅由路径参数 opType 决定,是否有必要手动赋值?
  2. 仅为了获取路由参数 opType 的值,是否有必要始终监听 route 对象?

针对以上两个问题,我的答案都是 。因为 isView 的值来源单一,仅仅是通过 opType 来决定,没有其他任何需要赋值的逻辑;而且对于 route 对象,很可能 queyr.opType 不会变更,而变更其他属性,如 namepath 等,或 query 的其他属性值,这种情况不需要为 isView 重新赋值,如果可以用缓存的值那就完美了。

鉴于以上思路,我认为针对此业务场景,使用 计算属性 computed 更为适合。

computed 和 watch 的区别

我们来简单回顾一下 computedwatch 的主要区别,两者都可以监听响应式依赖的变化。

  • computed 接收一个 getter 函数作为参数,返回一个计算属性 ref,有缓存,仅响应式依赖变更时才重新计算,否则使用缓存的值。
  • watcher 在响应式依赖发生变化时执行副作用函数,无缓存,返回值是一个停止 watch 的函数。

可见,computed 可用于定义 ref 变量,且可缓存,无需每次 route 对象变更时都重新计算。

ref 与 computed 定义变量的区别

由于 refcomputed 都可创建响应式数据,因此也拉来一起比一比😄

  • ref 比较直接,就是用来创建响应式数据的 API
  • computed 返回的计算属性也是响应式数据,不同之处在于,computed 不建议手动赋值,应始终保持其派生状态。即使可以通过 getter/setter 的定义方式实现该特性。

优化后代码

通过以上分析,可以发现,computed 不仅可以监听 route.query.opType 的变更,还可以创建响应式数据,且有缓存,顺便小小的提升了一波性能。

js 复制代码
const route = useRoute()

const isView = computed(() => route.query.opType === 'view')

搞定,不仅同样实现了业务功能,还减少了代码量,更提升了可读性和维护性,perfect!!!

结语

好啦,本文内容就到这里。实践出真知,只有真正动手实践,真正参与其中才能更深刻的体会到技术的魅力,才能总结出更合理的开发方式,爱动手的小伙伴们赶快行动起来吧😁。

若本文内容有错误或遗漏的地方,欢迎评论指出。感谢阅读,愿你我共同进步,谢谢!!!

相关推荐
用户51681661458419 分钟前
Vue Router 路由懒加载引发的生产页面白屏问题
vue.js·vue-router
libraG9 分钟前
Jenkins打包问题
前端·npm·jenkins
前端康师傅9 分钟前
JavaScript 作用域
前端·javascript
前端缘梦9 分钟前
Vue Keep-Alive 组件详解:优化性能与保留组件状态的终极指南
前端·vue.js·面试
我是天龙_绍18 分钟前
使用 TypeScript (TS) 结合 JSDoc
前端
云枫晖22 分钟前
JS核心知识-事件循环
前端·javascript
Simon_He22 分钟前
这次来点狠的:用 Vue 3 把 AI 的“碎片 Markdown”渲染得又快又稳(Monaco 实时更新 + Mermaid 渐进绘图)
前端·vue.js·markdown
eason_fan1 小时前
Git 大小写敏感性问题:一次组件重命名引发的CI构建失败
前端·javascript
无羡仙1 小时前
JavaScript 迭代器
前端
XiaoSong1 小时前
从未有过如此丝滑的React Native开发体验:EAS开发构建完全指南
前端·react.js