import Vue from 'vue'; export default { setup(props, context) { console.log(Vue.version); return {}; } };
반응형 상태
를 변경할 때, Vue
업데이트 DOM
은 실시간으로 동기적으로 업데이트되지 않지만, 동기화 코드가 실행된 후 Dom 업데이트 작업이 수행됩니다. 렌더링
성능이 크게 최적화되었으며 Dom
업데이트 횟수가 줄었습니다. state
时,Vue
更新DOM
并不是同步实时更新的,而是将同步执行的所有state更新缓存起来,同步代码执行完后再去执行Dom更新操作,很大程度的优化了render
性能,减少了Dom
更新次数;
而这一特性带来的一个问题,我们无法在state
更改后获取到真实的Dom
,所以Vue提供了nextTick
来获取state
更新后的Dom
function nextTick(callback?: () => void): Promise<void>
使用案例
<template> <div class="test_demo"> <h3 class="text">{{ text }}</h3> <button @click="onBtnClick">更新</button> </div> </template> <script lang="ts" setup> import { ref, nextTick } from 'vue'; const text = ref('test_0'); const onBtnClick = () => { text.value = 'test_1'; nextTick(() => { const text = ( document.querySelector<HTMLElement>('.text') as HTMLElement ).innerText; console.log(text); }); text.value = 'test_2'; }; </script>
点击更新
按钮后,输出test_2。但是,如果注释掉text.value = 'test_1';
,输出结果大不一样,输出test_0。
为什么会有这个问题?
text.value
赋值操作是同步实时的,代码执行遇到响应式state
的更改时,会提交一个视图更新逻辑
到微任务队列,遇到nextTick,也会向微任务队列提交。 所以上述代码,视图更新逻辑
在nextTick
前边,视图更新逻辑
的执行是将text.value = 'test_1'
和text.value = 'test_2'
合并后再更新视图,所以输出test2;
注释掉text.value = 'test_1'
后,nextTick
在微任务队列的顺序就在视图更新逻辑
前边了,所以输出test_0。
如果你使用f84f58e8776554134faa77b8b91daf01
语法,就需要使用defineProps
让TS
推导出组件的Props
<script setup lang="ts"> // 启用了 TypeScript import { ref } from 'vue' const props = defineProps({ msg: String }) const count = ref(1) </script> <template> <!-- 启用了类型检查和自动补全 --> {{ count.toFixed(2) }} </template>
如果没有使用setup
语法,考虑使用defineComponent
进行包裹,从而实现类型推导
import { defineComponent } from 'vue' export default defineComponent({ // 启用了类型推导 props: { message: String }, setup(props) { props.message // 类型:string | undefined } })
如果项目用Webpack,需要注意下,defineComponent
可能导致组件无法被tree shaking
, 为了确保组件被安全的tree shaking
,需要我们开发时做一下处理
export default /*#__PURE__*/ defineComponent(/* ... */)
如果项目用Vite,不需要做任何处理,因为Vite
底层的Rollup
会智能的认为defineComponent
没有副作用。
开发过程中,有一些场景例如:弹框内的表单、其它Tab下的组件等在页面初始化时不需要加载,我们可以考虑使用defineAsyncComponent
来声明成异步组件,从而提高页面初始化的速度。
import { defineAsyncComponent } from 'vue'; const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { // ...从服务器获取组件 resolve(/* 获取到的组件 */); }); });
import { defineAsyncComponent } from 'vue'; const AsyncComp = defineAsyncComponent( () => import('./components/MyComponent.vue') );
const AsyncComp = defineAsyncComponent({ // 加载函数 loader: () => import('./Foo.vue'), // 加载异步组件时使用的组件 loadingComponent: LoadingComponent, // 展示加载组件前的延迟时间,默认为 200ms delay: 200, // 加载失败后展示的组件 errorComponent: ErrorComponent, // 如果提供了一个 timeout 时间限制,并超时了 // 也会显示这里配置的报错组件,默认值是:Infinity timeout: 3000 });
bb06e69d307cb52103d07d8f9dd385e5
是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态。
虽然defineAsyncComponent
具备loadingComponent
参数来配置加载异步组件时的Loading组件,但是在一些场景,是需要使用Suspense
来使用的。例如:A组件依赖了B、C、D,如果三个都是异步组件,加载的过程要显示3个Loading,而Suspense
可以配置所有子组件存在未加载时而现实的Loading。
关于Web Components
的介绍请参考文章 Web Components入门
Vue 提供了一个和定义一般 Vue 组件几乎完全一致的defineCustomElement
state
실제 Dom
은 변경 후에 획득되므로 Vue는 nextTick
을 제공하여 dom
이후에 업데이트된 Dom
을 획득합니다. code>state🎜 import { defineCustomElement } from 'vue'; const MyVueElement = defineCustomElement({ /* 组件选项 */ }); // 注册自定义元素 customElements.define('my-vue-element', MyVueElement);🎜사용 사례🎜rrreee🎜
Update
버튼을 클릭하면 test_2가 출력됩니다. 그러나 text.value = 'test_1';
을 주석 처리하면 출력 결과가 상당히 달라지며 test_0이 출력됩니다. 🎜🎜왜 이런 문제가 발생하나요? 🎜🎜text.value
할당 작업은 동기식이며 실시간입니다. 코드 실행 시 응답 상태
가 변경되면 뷰 업데이트 로직
이 변경됩니다. submit 마이크로태스크 큐로 이동하여 nextTick이 발견되면 마이크로태스크 큐에도 제출됩니다. 따라서 위 코드에서는 view update logic
이 nextTick
앞에 있고, view update logic
의 실행은 를 변경하는 것입니다. text.value = 'test_1' 및 <code>text.value = 'test_2'
는 뷰를 업데이트하기 전에 병합되므로 test2가 출력됩니다.🎜🎜text.value =를 주석 처리한 후 'test_1'
, nextTick
순서는 업데이트 로직 보기
직전이므로 test_0이 출력됩니다. 🎜🎜defineComponent(유형 추론을 위한 보조 함수, TypeScript가 구성 요소 옵션의 유형을 올바르게 추론할 수 있도록 함)🎜🎜 752f0c4521bd75dec1baff2d2a067fcf
구문을 사용하는 경우 다음이 필요합니다. defineProps
를 사용하면 TS
가 구성요소의 Props
🎜rrreee🎜를 파생할 수 있습니다. setup
구문을 사용하지 않는 경우 다음을 고려하세요. defineComponent
를 사용하면 유형 추론을 달성하기 위해 래핑됩니다🎜rrreee🎜프로젝트에서 Webpack을 사용하는 경우 defineComponent
로 인해 구성 요소가 트리 쉐이킹를 보장하려면 개발 중에 안전한 <code>트리 쉐이킹
을 처리해야 합니다🎜rrreee🎜프로젝트에서 Vite를 사용하는 경우 기본 가 있기 때문에 어떤 처리도 할 필요가 없습니다. <code>Vite
/code>의 code>롤업defineComponent에 부작용이 없다고 지능적으로 생각합니다. 🎜🎜defineAsyncComponent(비동기 구성 요소)🎜🎜개발 과정에서 팝업 상자의 양식, 다른 탭의 구성 요소 등과 같은 일부 시나리오가 페이지 초기화 중에 로드될 필요가 없습니다. defineAsyncComponent를 비동기 구성 요소로 선언하여 페이지 초기화 속도를 높입니다. 🎜🎜사용법 1(서버에서 구성 요소 가져오기)🎜rrreee🎜사용법 2(로컬 구성 요소를 비동기식으로 로드)🎜rrreee🎜defineAsyncComponent 기타 매개 변수 구성🎜rrreee🎜Suspense🎜🎜bb06e69d307cb52103d07d8f9dd385e5
는 내장된 구성 요소 트리에서 비동기 종속성 처리를 조정하는 데 사용됩니다. 이를 통해 아래에 중첩된 여러 비동기 종속성이 해결될 때까지 구성 요소 트리 위쪽에서 기다리고 기다리는 동안 로드 상태를 렌더링할 수 있습니다. 🎜🎜defineAsyncComponent
에는 비동기 구성 요소를 로드할 때 Loading 구성 요소를 구성하는 loadingComponent
매개 변수가 있지만 일부 시나리오에서는 Suspense
를 사용해야 합니다. 예: 구성 요소는 B, C, D에 종속됩니다. 세 가지 구성 요소가 모두 비동기식 구성 요소인 경우 로드 프로세스는 세 개의 로드를 표시하고 Suspense
는 모든 하위 구성 요소가 실행될 때 실제 로드를 갖도록 구성할 수 있습니다. 로드되지 않았습니다. 🎜🎜defineCustomElement(Vue 구성 요소를 사용하여 웹 구성 요소 개발)🎜🎜웹 구성 요소
에 대한 소개는 웹 구성 요소 시작하기 문서를 참조하세요.🎜🎜Vue는 거의 동일한 defineCustomElement를 제공합니다. 사용자 정의 요소 생성을 지원하는 일반 Vue 구성 요소를 정의합니다. 🎜아아아아
위 내용은 Vue3 일반 API 기능 사용 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!