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的理解。

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

相关推荐
半点寒12W1 小时前
微信小程序实现路由拦截的方法
前端
某公司摸鱼前端2 小时前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
要加油哦~2 小时前
vue | 插件 | 移动文件的插件 —— move-file-cli 插件 的安装与使用
前端·javascript·vue.js
小林学习编程2 小时前
Springboot + vue + uni-app小程序web端全套家具商场
前端·vue.js·spring boot
柳鲲鹏2 小时前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
weixin-a153003083163 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
ai小鬼头4 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
一只叫煤球的猫4 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈
vvilkim5 小时前
Electron 自动更新机制详解:实现无缝应用升级
前端·javascript·electron
vvilkim5 小时前
Electron 应用中的内容安全策略 (CSP) 全面指南
前端·javascript·electron