vue2升级vue3踩坑——【依赖注入】可能成功了,但【依赖注入】成功了不太可能

背景

博主最近做一些页面迁移的工作,即将某些页面以子应用的方式嵌入到其他系统的基座应用中(基于micro-app这一微前端方案实现)。

在迁移过程中,和主管聊了聊,觉得这是一个将老项目从vue2升级成vue3的契机,于是便说干就干了。

框架升级最优先的工作,我认为是梳理 ,明确哪些功能或写法是以前过度设计 了,哪些是滥用了等等。

本文主要讲的是我在梳理完一些页面后,发现它们在状态管理方面存在滥用第三方库的现象,导致很多完全没必要依赖vuex的地方,使用了vuex。

(根本就没用上vuex提供的别的功能!!!🤯)

我的解决方案是使用reactive维护store,再将这个类似store的状态变量provide出去,从而替换掉原先vue2版本项目中的通过vuex引入store的写法。

看到这里可能有同学会问了:"那么什么时候推荐使用vuex或者pinia这些状态管理库呢?"
这个话题我们下回再讨论~😊

本篇博客主要想和大家分享,我在使用【依赖注入】时发现的几种方式与其特点(优、劣)

如果选择了错误的方式,则会让页面出现丢失响应式的情况,导致渲染异常

信息对齐

什么是vue的响应式?

什么是丢失响应式?

建立在上一小节内容的基础上,本文中所讨论的"丢失响应式",就是指模板中使用的值发生变化后,Vue并不会检测这个变化,也不会相应地更新DOM,从而导致渲染异常的现象。

使用【依赖注入】的几种方式与其特点

  1. 当一个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>
  1. 当一个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的理解。

如果掘友们有更好的想法与解法,欢迎评论区留言~

相关推荐
@PHARAOH8 分钟前
WHAT - cursor cli 开发范式
前端·ai·ai编程
子兮曰1 小时前
深入 HTML-in-Canvas:当 Canvas 学会了渲染 DOM,前端图形生态要变天了
前端·javascript·canvas
ws_qy1 小时前
从大模型原理到前端 AI Coding 工程化实践
前端·ai编程
倾颜1 小时前
React 19 源码主线拆解 04:Fiber 到底是什么,React 为什么需要 Fiber?
前端·react.js·源码阅读
AI攻城狮2 小时前
国产大模型能力大比拼,社区有话说
前端
IT_陈寒2 小时前
Vite的public文件夹放静态资源?这坑我替你踩了
前端·人工智能·后端
涵涵(互关)2 小时前
GoView各项目文件中的相关语法2
前端·javascript·vue.js
子兮曰3 小时前
别让爬虫白嫖你的导航站了:纯免费,手把手实现加密字体防爬
前端·javascript·后端
小村儿3 小时前
连载06 - Hooks 源码深度解析:Claude Code 的确定性自动化体系
前端·后端·ai编程
心中无石马3 小时前
uniapp引入tailwindcss4.x
前端·css·uni-app