이 기사에서는 Vue3 제품군 버킷 개발 시 몇 가지 일반적인 문제를 공유하여 함정과 지뢰밭을 피할 수 있기를 바랍니다.
저는 최근 Vue3를 사용하기 시작했고 3개의 프로젝트를 완료했습니다. 오늘은 이를 정리하고 15가지 일반적인 문제를 공유하겠습니다. 기본적으로 해당 문서 주소가 게시되어 있습니다. 더 주세요 문서 보세요~ 완성된 3개의 프로젝트는 기본적으로 Vue3(설정 스크립트 모드)를 사용하여 개발되었으므로 주로 여러 측면으로 요약됩니다.
문서 주소: https:// v3.cn .vuejs.org/guide/composition-api-lifecycle-hooks.html
script-srtup
모드를 사용하기 때문에 Vue3.x의 생명주기 기능을 직접 사용합니다: // A.vue\ <script setup>\ import { ref, onMounted } from "vue";\ let count = ref<number>(0);\ \ onMounted(() => {\ count.value = 1;\ })\ </script>로그인 후 복사각 Hook의 실행 타이밍은 문서에서도 확인할 수 있습니다: < 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…
2. 스크립트 설정 모드에서 상위 구성 요소는 하위 구성 요소
문서 주소: v3.cn.vuejs.org/api/sfc-scr…
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
여기서는 상위 구성 요소가 하위 구성 요소 내에 정의된 변수를 얻는 방법을 주로 소개합니다. 상위 구성 요소와 하위 구성 요소 간의 통신에 대한 자세한 내용은 v3.cn.vuejs.org/guide/compo…
전역 컴파일러 매크로< code>defineExpose 매크로를 사용할 수 있으며, 상위 구성 요소에 노출되어야 하는 하위 구성 요소의 매개 변수는
{key: vlaue}를 통해 매개 변수로 사용할 수 있습니다.
메서드는 템플릿 ref 메서드를 통해 하위 구성 요소를 가져옵니다. 예를 들어 해당 값을 얻을 수 있습니다.// 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;로그인 후 복사로그인 후 복사
전역 컴파일러 매크로는 스크립트 설정에서만 사용할 수 있습니다. 모드;
스크립트 설정 모드, 매크로를 사용할 때가 필요하지 않음
을 직접 사용할 수 있습니다. 🎜🎜스크립트 설정 모드는 다음을 포함하여 총 4개의 매크로를 제공합니다. 그리고 기본값이 있습니다. 🎜🎜🎜3. props에 대한 기본값을 제공하세요. 🎜🎜🎜🎜 DefineProps 문서: v3.cn.vuejs.org /api /sfc-scr…🎜 문서: v3.cn.vuejs .org /api/sfc-scr…🎜🎜🎜🎜스크립트 설정 모드에서 제공하는 4개의 🎜전역 컴파일러 매크로🎜는 앞서 소개되었지만 아직은
defineProps
에 대해 자세히 소개하지 않았습니다. 및withDefaults
.defineProps
매크로는 구성요소의 입력 매개변수를 정의하는 데 사용할 수 있습니다. 사용법은 다음과 같습니다. 🎜rrreee🎜여기에서는schema
및만 정의합니다. <code>props
속성. >modelValue두 가지 속성 유형,defineProps
이 선언의 단점은 props의 기본값을 설정하는 방법을 제공하지 않는다는 것입니다. 🎜🎜실제로 withDefaults 매크로를 통해 이를 달성할 수 있습니다: 🎜rrreee🎜🎜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\ 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
的格式发生变化了:
更加清晰直观了。
이 방법을 "Vue.js 디자인 및 구현"에서 발견했는데, 문서에서 관련 소개를 찾을 수 없습니다. 친구가 발견하면 알려주세요~
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
Vite에서는 다음 두 가지 방법을 사용하여 파일을 동적으로 가져올 수 있습니다:
import.meta.glob
이 방법 일치하는 파일은 기본적으로 동적 가져오기
를 통해 구현되는 🎜지연 로딩🎜입니다. 빌드 시 🎜독립적인 청크를 분리🎜하여 🎜비동기 가져오기🎜로 반환됩니다. . 사용 방법은 다음과 같습니다. 🎜🎜 🎜import.meta.globEager
for...in
루프를 통해 직접 전달되어 연산이 가능하며, 사용 방법은 다음과 같습니다. 🎜🎜🎜🎜Vue3 구성 요소의 비동기 가져오기만 사용하는 경우 Vue3 정의AsyncComponent를 직접 사용할 수도 있습니다. 로드할 API: 🎜🎜🎜vite.config만 입력하면 됩니다. ts
의 resolve.alias
에서 구성하면 됩니다. 🎜🎜 🎜🎜만약 당신이 TypeScript를 사용하면 편집기에 경로가 존재하지 않는다는 경고 메시지가 표시됩니다⚠️ 이때 tsconfig.json을 사용할 수 있습니다. 코드에 <code>compilerOptions.paths
구성을 추가하세요. 🎜🎜🎜$primary
), mixin 메서드(예: @mixin 라인
) 등: 🎜🎜🎜🎜 vite.config.ts
에서 scss 테마 구성 파일을 구성할 수 있습니다. css.preprocessorOptions.scss.additionalData
: 🎜🎜🎜🎜 scss 구성 파일을 사용하지 않으려면 scss 코드를 직접 작성할 수도 있습니다: 🎜🎜🎜this
가 없으므로 this.$router
또는 this .$route를 사용하여 라우팅 매개변수와 점프 경로를 얻습니다. 라우팅 매개변수를 얻어야 할 경우 다음과 같이 <code>vue-router
에서 제공하는 useRoute
메소드를 사용하여 이를 얻을 수 있습니다. 🎜🎜🎜🎜경로로 이동하려면 useRouter
메서드의 반환 값을 사용하여 이동할 수 있습니다. 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. Store 분해된 변수는 수정 후 업데이트되지 않습니다
문서 주소: pinia.vuejs.org/core-concep…
이때 changeName
이벤트를 트리거하는 버튼을 클릭한 후 뷰의name
이 변경되지 않았습니다. 이는 저장소가 반응형 객체이기 때문에 구조가 해체되면 반응성이 파괴되기 때문입니다. 그래서 우리는 직접적으로 해체할 수 없습니다. 이 경우 Pinia에서 제공하는storeToRefs
도구 메서드를 사용할 수 있으며, 사용 방법도 매우 간단합니다.storeToRefs를 통해 해체해야 하는 개체만 래핑하면 됩니다. code> 메소드를 사용하고 다른 로직은 변경되지 않습니다:
store.property 이름
할당을 통해 단일 데이터의 상태를 수정합니다. 🎜$patch
메소드를 통해 여러 데이터의 상태를 수정합니다. 🎜$patch
를 사용하는 것이 더 효율적이고 성능도 더 좋다고 명시하고 있으므로 여러 데이터를 수정할 때에는 $를 사용하는 것이 더 좋습니다. 패치
사용법도 매우 간단합니다. 🎜🎜🎜action
메소드를 통해 여러 데이터의 상태를 수정합니다. 🎜중국어 언어 팩을 도입하고 ElementPlus 구성에 추가하면 중국어로 전환할 수 있습니다.
이때 ElementPlus의 구성 요소 텍스트가 중국어로 된 것을 볼 수 있습니다.
위는 제가 최근 3개의 프로젝트를 시작한 후 실제 Vue3 제품군 버킷까지 겪은 함정 회피 경험을 요약한 것입니다. 사실 그 중 많은 부분이 문서에 소개되어 있지만 익숙하지 않았습니다. 처음에는. 또한 모두가 문서를 더 많이 읽어보시길 바랍니다~
Vue3 스크립트 설정 모드는 실제로 쓰여질수록 점점 더 인기를 얻고 있습니다.
이 글의 내용에 대해 궁금한 점이 있으시면 언제든지 댓글로 토론해 주세요.
【추천 관련 동영상 튜토리얼: vuejs 입문 튜토리얼, 웹 프론트엔드 시작하기】