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

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

相关推荐
敲键盘的小夜猫3 分钟前
RunnablePassthrough介绍和透传参数实战
java·服务器·前端
独立开阀者_FwtCoder12 分钟前
MySQL FULLTEXT索引解析:为什么它能大幅提升文本搜索性能?
前端·javascript·面试
EndingCoder24 分钟前
React从基础入门到高级实战:React 实战项目 - 项目一:在线待办事项应用
前端·javascript·react.js·前端框架
lyc23333325 分钟前
鸿蒙提醒管理:让通知「聪明又贴心」的3个技巧📢
前端
PasserbyX26 分钟前
cookie与广告追踪!
前端
lyc23333326 分钟前
鸿蒙断点适配:让应用「随屏而变」的终极指南📱💻
前端
JacksonGao27 分钟前
React Fiber的优先级系统你知道多少?
前端·react.js
PasserbyX29 分钟前
图说CSRF攻击
前端
lyc23333330 分钟前
鸿蒙文件分享:安全交换的「双车道」指南📤
前端
月下点灯1 小时前
使用Set集合新特性,快速实现一个商品SKU(单品)规格选择器
前端·javascript·vue.js