In diesem Artikel werden einige häufige Probleme bei der Entwicklung des Vue3-Familien-Buckets erläutert, damit Sie Fallstricke und Minenfelder vermeiden können.
Ich habe vor kurzem mit der Verwendung von Vue3 begonnen und bin auf viele Probleme gestoßen. Heute werde ich mir die 15 häufigsten Probleme mitteilen Gib mir mehr. Schau dir das Dokument an ~ Die drei abgeschlossenen Projekte werden grundsätzlich mit Vue3 (Setup-Skript-Modus) entwickelt und sind daher hauptsächlich in mehreren Aspekten zusammengefasst:
(Lernvideo-Sharing: vue-Video-Tutorial)
Die Lebenszyklusmethoden von Vue2.x und Vue3.x haben sich ziemlich verändert, werfen wir zuerst einen Blick darauf:
Vue3.x wird im aktuellen Vue2.x-Lebenszyklus noch unterstützt, es wird jedoch nicht empfohlen, den 2.x-Lebenszyklus in der frühen Phase zu verwenden und später zu versuchen, den 3.x-Lebenszyklus zu verwenden .
Da ich den script-srtup
-Modus verwende, verwende ich direkt die Lebenszyklusfunktion von Vue3.x:
// A.vue\ <script setup>\ import { ref, onMounted } from "vue";\ let count = ref<number>(0);\ \ onMounted(() => {\ count.value = 1;\ })\ </script>
Für den Ausführungszeitpunkt jedes Hooks können Sie sich auch die Dokumentation ansehen: a href="https://v3.cn.vuejs.org/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B % BE%E7%A4%BA" target="_blank" textvalue="v3.cn.vuejs.org/guide/insta…">v3.cn.vuejs.org/guide/insta…
script-srtup
模式,所以都是直接使用 Vue3.x 的生命周期函数:// 子组件\ <script setup>\ let name = ref("pingan8787")\ defineExpose({ name }); // 显式暴露的数据,父组件才可以获取\ </script>\ \ // 父组件\ <Chlid ref="child"></Chlid>\ <script setup>\ let child = ref(null)\ child.value.name //获取子组件中 name 的值为 pingan8787\ </script>
每个钩子的执行时机点,也可以看看文档:v3.cn.vuejs.org/guide/insta…
这里主要介绍父组件如何去获取子组件内部定义的变量,关于父子组件通信,可以看文档介绍比较详细:v3.cn.vuejs.org/guide/compo…
我们可以使用全局编译器宏的defineExpose
宏,将子组件中需要暴露给父组件获取的参数,通过 {key: vlaue}
方式作为参数即可,父组件通过模版 ref 方式获取子组件实例,就能获取到对应值:
<script setup>\ let props = defineProps<{\ schema: AttrsValueObject;\ modelValue: any;\ }>();\ </script>
注意:
import
可以直接使用;definedProps 文档:v3.cn.vuejs.org/api/sfc-scr… 文档:v3.cn.vuejs.org/api/sfc-scr…
前面介绍 script-setup 模式提供的 4 个全局编译器宏,还没有详细介绍,这一节介绍 defineProps
和 withDefaults
。使用 defineProps
宏可以用来定义组件的入参,使用如下:
<script setup>\ let props = withDefaults(\ defineProps<{\ schema: AttrsValueObject;\ modelValue: any;\ }>(),\ {\ schema: [],\ modelValue: ''\ }\ );\ </script>
这里只定义props
属性中的 schema
和 modelValue
两个属性的类型, defineProps
2. Im Skript-Setup-Modus erhält die übergeordnete Komponente die Daten der untergeordneten Komponente
Dokumentadresse: v3.cn.vuejs.org/api/sfc-scr…
globale Compiler-MakroHinweis🎜: 🎜🎜🎜🎜Globale Compiler-Makros können nur im Skript-Setup verwendet werden Modus; 🎜🎜🎜Skript-Setup-Modus, bei Verwendung von Makros ist kein
defineExpose
-Makro verwenden. Die Parameter in der untergeordneten Komponente, die der übergeordneten Komponente ausgesetzt werden müssen, können über den{key: vlaue} als Parameter verwendet werden
-Methode. Die übergeordnete Komponente erhält die untergeordnete Komponente über die Vorlagen-Ref-Methode. Beispiel: Sie können den entsprechenden Wert abrufen:// Vue2.x\ Vue.prototype.$api = axios;\ Vue.prototype.$eventBus = eventBus;\ \ // Vue3.x\ const app = createApp({})\ app.config.globalProperties.$api = axios;\ app.config.globalProperties.$eventBus = eventBus;Nach dem Login kopierenNach dem Login kopierenerforderlich
kann direkt verwendet werden; 🎜🎜Skript-Setup-Modus bietet insgesamt 4 Makros, darunter: defineProps, defineEmits, defineExpose, und withDefaults. 🎜🎜🎜3. Geben Sie Standardwerte für Requisiten an🎜🎜🎜🎜definierteProps-Dokumentation: v3.cn.vuejs.org /api /sfc-scr…🎜 Dokumentation: v3.cn.vuejs .org /api/sfc-scr…🎜🎜🎜🎜Die 4 🎜globalen Compiler-Makros🎜, die vom Skript-Setup-Modus bereitgestellt werden, wurden noch nicht im Detail vorgestellt und
withDefaults
. Das MakrodefineProps
kann verwendet werden, um die Eingabeparameter der Komponente zu definieren. Die Verwendung ist wie folgt: 🎜rrreee🎜Hier definieren wir nur dasschema
undim <code>props
-Attribut. >modelValueZwei Attributtypen,defineProps
Der Nachteil dieser Deklaration besteht darin, dass sie keine Möglichkeit bietet, den Standardwert von props festzulegen. 🎜🎜Tatsächlich können wir dies durch das withDefaults-Makro erreichen: 🎜rrreee🎜🎜withDefaults Die Hilfsfunktion bietet eine Typprüfung für Standardwerte und stellt sicher, dass der Typ der zurückgegebenen Requisiten das optionale Flag der Eigenschaft entfernt, die a deklariert hat Standardwert. 🎜🎜🎜🎜4. Konfigurieren Sie globale benutzerdefinierte Parameter 🎜🎜🎜🎜Dokumentadresse: 🎜v3.cn.vuejs.org/guide/migra…🎜🎜
在 Vue2.x 中我们可以通过 Vue.prototype
添加全局属性 property。但是在 Vue3.x 中需要将 Vue.prototype
替换为 config.globalProperties
配置:
// Vue2.x\ Vue.prototype.$api = axios;\ Vue.prototype.$eventBus = eventBus;\ \ // Vue3.x\ const app = createApp({})\ app.config.globalProperties.$api = axios;\ app.config.globalProperties.$eventBus = eventBus;
使用时需要先通过 vue 提供的 getCurrentInstance
方法获取实例对象:
当我们在使用 v-model
指令的时候,实际上 v-bind
和 v-on
组合的简写,Vue2.x 和 Vue3.x 又存在差异。
Vue2.x
在子组件中,如果要对某一个属性进行双向数据绑定,只要通过 this.$emit('update:myPropName', newValue)
就能更新其 v-model
绑定的值。
script-setup
模式下就不能使用 this.$emit
去派发更新事件,毕竟没有 this
,这时候需要使用前面有介绍到的 defineProps、defineEmits 两个宏来实现:
父组件使用的时候就很简单:
Vue3.x 对于一些开发过程中的异常,做了更友好的提示警告,比如下面这个提示:
这样能够更清楚的告知异常的出处,可以看出大概是 <elinput>这边的问题,但还不够清楚。这时候就可以添加 Vue3.x 提供的<strong>全局异常处理器</strong>,更清晰的<strong>输出错误内容和调用栈信息,代码如下</strong>:</elinput>
这时候就能看到输出内容如下:
一下子就清楚很多。当然,该配置项也可以用来集成错误追踪服务 Sentry 和 Bugsnag。推荐阅读:Vue3 如何实现全局异常处理?
当我们在控制台输出 ref
声明的变量时。
会看到控制台输出了一个 RefImpl
对象:
看起来很不直观。我们都知道,要获取和修改 ref
声明的变量的值,需要通过 .value
来获取,所以你也可以:
这里还有另一种方式,就是在控制台的设置面板中开启 「Enable custom formatters」选项。
image.png
image.png
这时候你会发现,控制台输出的 ref
的格式发生变化了:
更加清晰直观了。
Ich habe diese Methode in „Vue.js Design and Implementation“ entdeckt, konnte aber keine relevante Einführung im Dokument finden. Wenn Freunde sie finden, lassen Sie es mich bitte wissen~
Studenten, die Webpack verwenden, sollten wissen, dass Sie im Webpack
require.contextDynamische Importdatei:
require.context
动态导入文件:
在 Vite 中,我们可以使用这两个方法来动态导入文件:
import.meta.glob
该方法匹配到的文件默认是懒加载,通过动态导入实现,构建时会分离独立的 chunk,是异步导入,返回的是 Promise,需要做异步操作,使用方式如下:
import.meta.globEager
该方法是直接导入所有模块,并且是同步导入,返回结果直接通过 for...in
循环就可以操作,使用方式如下:
如果仅仅使用异步导入 Vue3 组件,也可以直接使用 Vue3 defineAsyncComponent API 来加载:
当项目比较复杂的时候,经常需要配置 alias 路径别名来简化一些代码:
在 Vite 中配置也很简单,只需要在 vite.config.ts
的 resolve.alias
中配置即可:
如果使用的是 TypeScript 时,编辑器会提示路径不存在的警告⚠️,这时候可以在 tsconfig.json
中添加 compilerOptions.paths
的配置:
当我们需要使用 scss 配置的主题变量(如 $primary
)、mixin方法(如 @mixin lines
)等时,如:
我们可以将 scss 主题配置文件,配置在 vite.config.ts
的 css.preprocessorOptions.scss.additionalData
中:
如果不想使用 scss 配置文件,也可以直接写成 scss 代码:
由于在 script-setup
模式下,没有 this
可以使用,就不能直接通过 this.$router
或 this.$route
来获取路由参数和跳转路由。当我们需要获取路由参数时,就可以使用 vue-router
提供的 useRoute
In Vite können wir diese beiden Methoden verwenden, um Dateien dynamisch zu importieren:
import.meta.glob
Diese Methode Die abgeglichene Datei ist standardmäßig auf „verzögertes Laden“ eingestellt, was durch „dynamischen Import“ implementiert wird. Beim Erstellen werden „unabhängige Blöcke“ getrennt, was einem „asynchronen Import“ entspricht . Die Verwendungsmethode ist wie folgt:
🎜import.meta.globEager
for.. .in
-Schleife geleitet, die ausgeführt werden kann, und die Verwendungsmethode ist wie folgt: 🎜🎜🎜🎜Wenn Sie nur den asynchronen Import von Vue3-Komponenten verwenden, können Sie auch direkt die Vue3-DefineAsyncComponent verwenden API zum Laden: 🎜🎜🎜vite.config eingeben. Konfigurieren Sie es einfach in <code>resolve.alias
von ts: 🎜🎜 🎜🎜Wenn ja Bei Verwendung von TypeScript gibt der Editor eine Warnung aus, dass der Pfad nicht existiert. Zu diesem Zeitpunkt können Sie tsconfig.json verwenden. Fügen Sie die Konfiguration von <code>compilerOptions.paths
im Code> hinzu: 🎜🎜🎜$primary
), Mixin-Methoden (wie @mixinlines
) usw., wie zum Beispiel: 🎜🎜🎜🎜Wir können die SCSS-Theme-Konfigurationsdatei in vite.config.ts
konfigurieren css.preprocessorOptions.scss.additionalData
: 🎜🎜🎜🎜Wenn Sie die SCSS-Konfigurationsdatei nicht verwenden möchten, können Sie den SCSS-Code auch direkt schreiben: 🎜🎜🎜this
kann verwendet werden, Sie können this.$router
oder this .$route
nicht direkt übergeben > um Routing-Parameter und Sprungrouten zu erhalten. Wenn wir Routing-Parameter abrufen müssen, können wir die von vue-router
bereitgestellte Methode useRoute
verwenden, um diese wie folgt abzurufen: 🎜🎜🎜🎜Wenn Sie zu einer Route springen möchten, können Sie zum Springen den Rückgabewert der Methode useRouter
verwenden: useRouter
方法的返回值去跳转:
当我们解构出 store 的变量后,再修改 store 上该变量的值,视图没有更新:
这时候点击按钮触发 changeName
事件后,视图上的 name
并没有变化。这是因为 store 是个 reactive 对象,当进行解构后,会破坏它的响应性。所以我们不能直接进行解构。这种情况就可以使用 Pinia 提供 storeToRefs
工具方法,使用起来也很简单,只需要将需要解构的对象通过 storeToRefs
方法包裹,其他逻辑不变:
这样再修改其值,变更马上更新视图了。
按照官网给的方案,目前有三种方式修改:
通过 store.属性名
赋值修改单笔数据的状态;
这个方法就是前面一节使用的:
通过 $patch
方法修改多笔数据的状态;
当我们需要同时修改多笔数据的状态时,如果还是按照上面方法,可能要这么写:
上面这么写也没什么问题,但是 Pinia 官网已经说明,使用 $patch
的效率会更高,性能更好,所以在修改多笔数据时,更推荐使用 $patch
,使用方式也很简单:
通过 action
方法修改多笔数据的状态;
也可以在 store 中定义 actions 的一个方法来更新:
使用时:
这三种方式都能更新 Pinia 中 store 的数据状态。
项目新安装的 element-plus 在开发阶段都是正常,没有提示任何警告,但是在打包过程中,控制台输出下面警告内容:
在官方 issues 中查阅很久:github.com/element-plu…
尝试在 vite.config.ts
中配置 charset: false
1. Destrukturierte Speichervariablen werden nach der Änderung nicht aktualisiert
Dokumentadresse: pinia.vuejs.org/core-concep…Gefällt mir noch einmal. Ändern Sie den Wert und die Ansicht wird sofort mit der Änderung aktualisiert.Zu diesem Zeitpunkt wird nach dem Klicken auf die Schaltfläche zum Auslösen des Ereignisses
changeName
dername
in der Ansicht angezeigt nicht geändert. Dies liegt daran, dass der Speicher ein reaktives Objekt ist und bei einer Zerstörung seine Reaktionsfähigkeit zerstört wird. Wir können also nicht direkt dekonstruieren. In diesem Fall können Sie die von Pinia bereitgestellte Tool-MethodestoreToRefs
verwenden. Sie ist ebenfalls sehr einfach zu verwenden. Sie müssen nur das zu dekonstruierende Objekt mitstoreToRefs umschließen. code>-Methode, und die andere Logik bleibt unverändert:
store.property name
; 🎜$patch
🎜$patch
effizienter ist und eine bessere Leistung erbringt. Wenn Sie also mehrere Daten ändern, wird eher die Verwendung von $ empfohlen Patch
. Die Verwendung ist auch sehr einfach: 🎜🎜🎜action
-Methode; 🎜Wir können auf Chinesisch umsteigen, indem wir das chinesische Sprachpaket einführen und zur ElementPlus-Konfiguration hinzufügen:
Zu diesem Zeitpunkt können Sie sehen, dass der Text der Komponenten in ElementPlus Chinesisch geworden ist.
Das Obige ist meine aktuelle Zusammenfassung der Erfahrungen mit der Vermeidung von Fallstricken nach drei Projekten von den Anfängen bis zum eigentlichen Vue3-Familien-Bucket. Tatsächlich werden viele davon im Dokument vorgestellt, aber ich war damit nicht vertraut sie zunächst. Ich hoffe auch, dass jeder die Dokumentation mehr liest ~
Der Skript-Setup-Modus von Vue3 wird im Laufe des Schreibens tatsächlich immer beliebter.
Wenn Sie Fragen zum Inhalt dieses Artikels haben, können Sie diese gerne kommentieren und diskutieren.
【Empfohlene verwandte Video-Tutorials: vuejs-Einführungs-Tutorial, Erste Schritte mit dem Web-Frontend】