最近入门 Vue3 并完结 3 个项目,遇到问题蛮多的,今日就花点时间整理一下,和咱们共享 15 个比较常见的问题,根本都贴出对应文档地址,还请多看文档~ 现已完结的 3 个项目根本都是运用 Vue3 (setup-script 形式)全家桶开发,因此首要分几个方面总结:
- Vue3
- Vite
- VueRouter
- Pinia
- ElementPlus
一、Vue3
1. Vue2.x 和 Vue3.x 生命周期办法的改变
文档地址:v3.cn.vuejs.org/guide/compo…
Vue2.x 和 Vue3.x 生命周期办法的改变蛮大的,先看看:
现在 Vue3.x 仍然支持 Vue2.x 的生命周期,但不建议混搭运用,前期能够先运用 2.x 的生命周期,后边尽量运用 3.x 的生命周期开发。
由于我运用都是script-srtup
形式,所以都是直接运用 Vue3.x 的生命周期函数:
// A.vue
<script setup lang="ts">
import { ref, onMounted } from "vue";
let count = ref<number>(0);
onMounted(() => {
count.value = 1;
})
</script>
每个钩子的履行时机点,也能够看看文档:v3.cn.vuejs.org/guide/insta…
2. script-setup 形式中父组件获取子组件的数据
文档地址:v3.cn.vuejs.org/api/sfc-scr…
这儿首要介绍父组件怎么去获取子组件内部定义的变量,关于父子组件通信,能够看文档介绍比较具体:v3.cn.vuejs.org/guide/compo…
咱们能够运用大局编译器宏的defineExpose
宏,将子组件中需求露出给父组件获取的参数,经过{key: vlaue}
办法作为参数即可,父组件经过模版 ref 办法获取子组件实例,就能获取到对应值:
// 子组件
<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>
注意:
- 大局编译器宏只能在 script-setup 形式下运用;
- script-setup 形式下,运用宏时无需
import
能够直接运用; - script-setup 形式一共供给了 4 个宏,包括:defineProps、defineEmits、defineExpose、withDefaults。
3. 为 props 供给默许值
definedProps 文档:v3.cn.vuejs.org/api/sfc-scr… 文档:v3.cn.vuejs.org/api/sfc-scr…
前面介绍 script-setup 形式供给的 4 个大局编译器宏,还没有具体介绍,这一节介绍defineProps
和withDefaults
。运用defineProps
宏能够用来定义组件的入参,运用如下:
<script setup lang="ts">
let props = defineProps<{
schema: AttrsValueObject;
modelValue: any;
}>();
</script>
这儿只定义props
特点中的schema
和modelValue
两个特点的类型,defineProps
的这种声明的不足之处在于,它没有供给设置 props 默许值的办法。
其实咱们能够经过 withDefaults 这个宏来完成:
<script setup lang="ts">
let props = withDefaults(
defineProps<{
schema: AttrsValueObject;
modelValue: any;
}>(),
{
schema: [],
modelValue: ''
}
);
</script>
withDefaults 辅助函数供给了对默许值的类型检查,并保证返回的 props 的类型删除了已声明默许值的特点的可选标志。
4. 装备大局自定义参数
文档地址: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
constapp=createApp({})
app.config.globalProperties.$api=axios;
app.config.globalProperties.$eventBus=eventBus;
运用时需求先经过 vue 供给的getCurrentInstance
办法获取实例目标:
5. v-model 改变
文档地址:v3.cn.vuejs.org/guide/migra…
当咱们在运用v-model
指令的时分,实际上v-bind
和v-on
组合的简写,Vue2.x 和 Vue3.x 又存在差异。
Vue2.x
在子组件中,假如要对某一个特点进行双向数据绑定,只要经过this.$emit('update:myPropName', newValue)
就能更新其v-model
绑定的值。
- Vue3.x
script-setup
形式下就不能运用this.$emit
去派发更新事情,毕竟没有this
,这时分需求运用前面有介绍到的 defineProps、defineEmits 两个宏来完成:
父组件运用的时分就很简略:
6. 开发环境报错不好排查
文档地址:v3.cn.vuejs.org/api/applica…
Vue3.x 关于一些开发过程中的反常,做了更友好的提示正告,比方下面这个提示:
这样能够更清楚的告知反常的出处,能够看出大概是<ElInput 0=......
这边的问题,但还不行清楚。这时分就能够增加 Vue3.x 供给的大局反常处理器,更明晰的输出过错内容和调用栈信息,代码如下:
这时分就能看到输出内容如下:
一会儿就清楚许多。当然,该装备项也能够用来集成过错追踪服务 Sentry 和 Bugsnag。引荐阅览:Vue3 怎么完成大局反常处理?
7. 调查 ref 的数据不直观,不方便
当咱们在控制台输出ref
声明的变量时。
会看到控制台输出了一个RefImpl
目标:
看起来很不直观。咱们都知道,要获取和修正ref
声明的变量的值,需求经过.value
来获取,所以你也能够:
这儿还有另一种办法,就是在控制台的设置面板中敞开 「Enable custom formatters」选项。
image.png
image.png
这时分你会发现,控制台输出的ref
的格式发生改变了:
这个办法是我在《Vue.js 设计与完成》中发现的,但在文档也没有找到相关介绍,假如有朋友发现了,欢迎告知~
二、Vite
1. Vite 动态导入的运用问题
文档地址:cn.vitejs.dev/guide/featu…
运用 webpack 的同学应该都知道,在 webpack 中能够经过require.context
动态导入文件:
在 Vite 中,咱们能够运用这两个办法来动态导入文件:
import.meta.glob
该办法匹配到的文件默许是懒加载,经过动态导入完成,构建时会分离独立的 chunk,是异步导入,返回的是 Promise,需求做异步操作,运用办法如下:
import.meta.globEager
该办法是直接导入一切模块,并且是同步导入,返回成果直接经过for...in
循环就能够操作,运用办法如下:
假如仅仅运用异步导入 Vue3 组件,也能够直接运用 Vue3 defineAsyncComponent API 来加载:
2. Vite 装备 alias 类型别名
文档地址:cn.vitejs.dev/config/#res…
当项目比较复杂的时分,常常需求装备 alias 途径别名来简化一些代码:
在 Vite 中装备也很简略,只需求在vite.config.ts
的resolve.alias
中装备即可:
假如运用的是 TypeScript 时,编辑器会提示途径不存在的正告⚠️,这时分能够在tsconfig.json
中增加compilerOptions.paths
的装备:
3. Vite 装备大局 scss
文档地址:cn.vitejs.dev/config/#css…
当咱们需求运用 scss 装备的主题变量(如$primary
)、mixin办法(如@mixin lines
)等时,如:
咱们能够将 scss 主题装备文件,装备在vite.config.ts
的css.preprocessorOptions.scss.additionalData
中:
假如不想运用 scss 装备文件,也能够直接写成 scss 代码:
三、VueRouter
1. script-setup 形式下获取路由参数
文档地址:router.vuejs.org/zh/guide/ad…
由于在script-setup
形式下,没有this
能够运用,就不能直接经过this.$router
或this.$route
来获取路由参数和跳转路由。当咱们需求获取路由参数时,就能够运用vue-router
供给的useRoute
办法来获取,运用如下:
假如要做路由跳转,就能够运用useRouter
办法的返回值去跳转:
四、Pinia
1. store 解构的变量修正后没有更新
文档地址:pinia.vuejs.org/core-concep…
当咱们解构出 store 的变量后,再修正 store 上该变量的值,视图没有更新:
这时分点击按钮触发changeName
事情后,视图上的name
并没有改变。这是由于 store 是个 reactive 目标,当进行解构后,会损坏它的响应性。所以咱们不能直接进行解构。这种状况就能够运用 Pinia 供给storeToRefs
工具办法,运用起来也很简略,只需求将需求解构的目标经过storeToRefs
办法包裹,其他逻辑不变:
这样再修正其值,变更马上更新视图了。
2. Pinia 修正数据状况的办法
依照官网给的方案,现在有三种办法修正:
- 经过
store.特点名
赋值修正单笔数据的状况;
这个办法就是前面一节运用的:
- 经过
$patch
办法修正多笔数据的状况;
文档地址:pinia.vuejs.org/api/interfa…
当咱们需求一起修正多笔数据的状况时,假如还是依照上面办法,可能要这么写:
上面这么写也没什么问题,但是 Pinia 官网现已说明,运用$patch
的效率会更高,功能更好,所以在修正多笔数据时,更引荐运用$patch
,运用办法也很简略:
- 经过
action
办法修正多笔数据的状况;
也能够在 store 中定义 actions 的一个办法来更新:
运用时:
这三种办法都能更新 Pinia 中 store 的数据状况。
五、Element Plus
1. element-plus 打包时 @charset 正告
项目新安装的 element-plus 在开发阶段都是正常,没有提示任何正告,但是在打包过程中,控制台输出下面正告内容:
在官方 issues 中查阅很久:github.com/element-plu…
测验在vite.config.ts
中装备charset: false
,成果也是无效:
最后在官方的 issues 中找到处理办法:
2. 中文语言包装备
文档地址:element-plus.gitee.io/zh-CN/guide…
咱们能够经过引入中文语言包,并增加到 ElementPlus 装备中来切换成中文:
这时分就能看到 ElementPlus 里面组件的文本变成中文了。
总结
以上是我最近从入门到实战 Vue3 全家桶的 3 个项目后总结避坑经历,其实许多都是文档中有介绍的,仅仅刚开始不熟悉。也期望大伙多看看文档咯~
Vue3 script-setup 形式的确越写越香。
本文内容假如有问题,欢迎咱们一起谈论讨论。