背景
博主最近做一些页面迁移的工作,即将某些页面以子应用的方式嵌入到其他系统的基座应用中(基于micro-app这一微前端方案实现)。
在迁移过程中,和主管聊了聊,觉得这是一个将老项目从vue2升级成vue3的契机,于是便说干就干了。
框架升级最优先的工作,我认为是梳理 ,明确哪些功能或写法是以前过度设计 了,哪些是滥用了等等。
本文主要讲的是我在梳理完一些页面后,发现它们在状态管理方面存在滥用第三方库的现象,导致很多完全没必要依赖vuex的地方,使用了vuex。
(根本就没用上vuex提供的别的功能!!!🤯)
我的解决方案是使用reactive
维护store
,再将这个类似store
的状态变量provide
出去,从而替换掉原先vue2版本项目中的通过vuex引入store的写法。
看到这里可能有同学会问了:"那么什么时候推荐使用vuex或者pinia这些状态管理库呢?"
这个话题我们下回再讨论~😊
本篇博客主要想和大家分享,我在使用【依赖注入】时发现的几种方式与其特点(优、劣)
如果选择了错误的方式,则会让页面出现丢失响应式的情况,导致渲染异常。
信息对齐
什么是vue的响应式?
什么是丢失响应式?
建立在上一小节内容的基础上,本文中所讨论的"丢失响应式",就是指模板中使用的值发生变化后,Vue并不会检测这个变化,也不会相应地更新DOM,从而导致渲染异常的现象。
使用【依赖注入】的几种方式与其特点
- 当一个
reactive
对象被provide
出去之后,如果在子孙组件以下方的方式使用,则会丢失响应式
script setup:
js
const compareMessage = inject('compareMessage')
const compareMessageContent = compareMessage.content
// 👆等同于对一个reactive进行解构赋值的写法
// const { content } = compareMessage
template:
html
<p>
<!-- 会丢失响应式 -->
compareMessage to grand child: <em>{{ compareMessageContent}}</em>
</p>
- 当一个
reactive
对象被provide
出去之后,如果期望它还是响应式的数据,则可以有以下几种方式:
- 直接在
template
中使用xxx.yyyy
的方式,如:
html
<p>
compareMessage to grand child: <em>{{ compareMessage.content }}</em>
</p>
- 可以使用
computed
进行包裹,不过不太推荐🙅,因为计算属性主要用于描述依赖响应式状态的复杂逻辑
script setup:
js
const compareMessage = inject('compareMessage')
const compareMessageContent = computed(() => compareMessage.content)
template:
html
<p>
<!-- 不会丢失响应式 -->
compareMessage to grand child: <em>{{ compareMessageContent}}</em>
</p>
- 可以使用
toRefs
,将其改为响应式,这种解法就更不推荐了×,硬解,和使用computed
一样,toRefs
最适合用在从组合式函数中返回响应式对象时
js
const compareMessage = toRefs(reactive({ content: 'hello2'}))
//...
<input v-model="compareMessage.content.value">
html
<script setup>
const compareMessage = inject('compareMessage')
const {content} = compareMessage
</script>
<template>
<p>compareMessage to grand child: <em>{{ content}}</em></p>
</template>
【依赖注入】的推荐写法
- 👉 个人认为的最佳实践,在provide一个类似于vuex的store对象时,这样去写
js
const content = ref('hello')
provide('compareMessage', { content })
子孙组件:
html
<script setup>
const compareMessage = inject('compareMessage')
// 解构赋值
const {content} = compareMessage
// 或者
// const compareMessageContent = compareMessage.content
</script>
<template>
<!-- 不会丢失响应式 -->
<p>compareMessage to grand child: <em>{{ content}}</em></p>
</template>
结语
我用的最久的技术栈还是React
,因此,本文提到的一些使用vue相关特性的方式和给出的解法,都是基于自己目前对于vue的理解。
如果掘友们有更好的想法与解法,欢迎评论区留言~