API
와 유사하게 provide()
는 에 있어야 합니다. 구성 요소의 setup()
단계는 동기적으로 호출됩니다. [관련 권장사항: vuejs 비디오 튜토리얼, 웹 프론트엔드 개발】
Vue3의 종속성 주입 및 구성 요소 정의에 대해 이야기해 보겠습니다.
이번에는 Vue3의 종속성 주입 및 구성 요소 정의와 관련된 여러 API와 공통 라이브러리 ElementUI Plus 및 Vueuse에서의 사용법을 주로 공유하고 예제를 사용하여 사용 시나리오를 이해합니다.
Vue 3
의 종속성 주입 및 구성 요소 정의에 대해 이야기해 보겠습니다. Vue 3
中依赖注入与组件定义相关的那点事儿。
provide() & inject()
provide()
提供一个值,可以被后代组件注入。
function provide<T>(key: InjectionKey<T> | string, value: T): void
接收两个参数:
- 要注入的
key
,字符串或者Symbol
;
export interface InjectionKey<T> extends Symbol {}
- 对应注入的值
与注册生命周期钩子的 API
类似,provide()
必须在组件的 setup()
阶段同步调用。【相关推荐:vuejs视频教程、web前端开发】
inject()
注入一个由祖先组件或整个应用 (通过 app.provide()
) 提供的值。
// 没有默认值 function inject<T>(key: InjectionKey<T> | string): T | undefined // 带有默认值 function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T // 使用工厂函数 function inject<T>( key: InjectionKey<T> | string, defaultValue: () => T, treatDefaultAsFactory: true ): T
第一个参数是注入的
key
。Vue
会遍历父组件链,通过匹配key
来确定所提供的值。如果父组件链上多个组件对同一个key
提供了值,那么离得更近的组件将会“覆盖”链上更远的组件所提供的值。如果没有能通过key
匹配到值,inject()
将返回undefined
,除非提供了一个默认值。第二个参数是可选的,即在没有匹配到
key
时使用的默认值。它也可以是一个工厂函数,用来返回某些创建起来比较复杂的值。如果默认值本身就是一个函数,那么你必须将false
作为第三个参数传入,表明这个函数就是默认值,而不是一个工厂函数。
provide() & inject() - 官方示例
// provide <script setup> import {(ref, provide)} from 'vue' import {fooSymbol} from './injectionSymbols' // 提供静态值 provide('foo', 'bar') // 提供响应式的值 const count = ref(0) provide('count', count) // 提供时将 Symbol 作为 key provide(fooSymbol, count) </script>
// inject <script setup> import { inject } from 'vue' import { fooSymbol } from './injectionSymbols' // 注入值的默认方式 const foo = inject('foo') // 注入响应式的值 const count = inject('count') // 通过 Symbol 类型的 key 注入 const foo2 = inject(fooSymbol) // 注入一个值,若为空则使用提供的默认值 const bar = inject('foo', 'default value') // 注入一个值,若为空则使用提供的工厂函数 const baz = inject('foo', () => new Map()) // 注入时为了表明提供的默认值是个函数,需要传入第三个参数 const fn = inject('function', () => {}, false) </script>
provide() & inject() - ElementUI Plus 示例 Breadcrumb 组件
<script setup> import { onMounted, provide, ref } from 'vue' import { useNamespace } from '@element-plus/hooks' import { breadcrumbKey } from './constants' import { breadcrumbProps } from './breadcrumb' defineOptions({ name: 'ElBreadcrumb', }) const props = defineProps(breadcrumbProps) const ns = useNamespace('breadcrumb') const breadcrumb = ref<HTMLDivElement>() // 提供值 provide(breadcrumbKey, props) onMounted(() => { ...... }) </script>
<script setup> import { getCurrentInstance, inject, ref, toRefs } from 'vue' import ElIcon from '@element-plus/components/icon' import { useNamespace } from '@element-plus/hooks' import { breadcrumbKey } from './constants' import { breadcrumbItemProps } from './breadcrumb-item' import type { Router } from 'vue-router' defineOptions({ name: 'ElBreadcrumbItem', }) const props = defineProps(breadcrumbItemProps) const instance = getCurrentInstance()! // 注入值 const breadcrumbContext = inject(breadcrumbKey, undefined)! const ns = useNamespace('breadcrumb') ...... </script>
provide() & inject() - VueUse 示例
createInjectionState 源码 / createInjectionState 使用
package/core/computedInject 源码
import { type InjectionKey, inject, provide } from 'vue-demi' /** * 创建可以注入到组件中的全局状态 */ export function createInjectionState<Arguments extends Array<any>, Return>( composable: (...args: Arguments) => Return ): readonly [ useProvidingState: (...args: Arguments) => Return, useInjectedState: () => Return | undefined ] { const key: string | InjectionKey<Return> = Symbol('InjectionState') const useProvidingState = (...args: Arguments) => { const state = composable(...args) provide(key, state) return state } const useInjectedState = () => inject(key) return [useProvidingState, useInjectedState] }
nextTick()
等待下一次 DOM 更新刷新的工具方法。
function nextTick(callback?: () => void): Promise<void>
说明:当你在 Vue
中更改响应式状态时,最终的 DOM
更新并不是同步生效的,而是由 Vue
将它们缓存在一个队列中,直到下一个“tick”
才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。
nextTick()
可以在状态改变后立即使用,以等待 DOM
provide() & inject()
provide()할 수 있는 값을 제공하세요. 하위 구성 요소에 의해 주입됩니다. <script setup>
import { ref, nextTick } from 'vue'
const count = ref(0)
async function increment() {
count.value++
// DOM 还未更新
console.log(document.getElementById('counter').textContent) // 0
await nextTick()
// DOM 此时已经更新
console.log(document.getElementById('counter').textContent) // 1
}
</script>
<template>
<button id="counter" @click="increment">{{ count }}</button>
</template>
로그인 후 복사두 개의 매개변수를 받습니다: 삽입할
key
, 문자열 또는 Symbol
export default defineComponent({
......
const syncMenuState = (
newCheckedNodes: CascaderNode[],
reserveExpandingState = true
) => {
......
checkedNodes.value = newNodes
nextTick(scrollToExpandingNode)
}
const scrollToExpandingNode = () => {
if (!isClient) return
menuList.value.forEach((menu) => {
const menuElement = menu?.$el
if (menuElement) {
const container = menuElement.querySelector(`.${ns.namespace.value}-scrollbar__wrap`)
const activeNode = menuElement.querySelector(`.${ns.b('node')}.${ns.is('active')}`) ||
menuElement.querySelector(`.${ns.b('node')}.in-active-path`)
scrollIntoView(container, activeNode)
}
})
}
......
})
로그인 후 복사< li>해당 주입된 값
라이프 사이클 후크를 등록하는 API
와 유사하게 provide()
는 에 있어야 합니다. 구성 요소의 setup()
단계는 동기적으로 호출됩니다. [관련 권장사항: vuejs 비디오 튜토리얼, 웹 프론트엔드 개발】
injection 상위 구성 요소 또는 전체 앱에서 제공하는 값입니다( <script setup> import { ref, nextTick } from 'vue' const count = ref(0) async function increment() { count.value++ // DOM 还未更新 console.log(document.getElementById('counter').textContent) // 0 await nextTick() // DOM 此时已经更新 console.log(document.getElementById('counter').textContent) // 1 } </script> <template> <button id="counter" @click="increment">{{ count }}</button> </template>
key
, 문자열 또는 Symbol
export default defineComponent({ ...... const syncMenuState = ( newCheckedNodes: CascaderNode[], reserveExpandingState = true ) => { ...... checkedNodes.value = newNodes nextTick(scrollToExpandingNode) } const scrollToExpandingNode = () => { if (!isClient) return menuList.value.forEach((menu) => { const menuElement = menu?.$el if (menuElement) { const container = menuElement.querySelector(`.${ns.namespace.value}-scrollbar__wrap`) const activeNode = menuElement.querySelector(`.${ns.b('node')}.${ns.is('active')}`) || menuElement.querySelector(`.${ns.b('node')}.in-active-path`) scrollIntoView(container, activeNode) } }) } ...... })
API
와 유사하게 provide()
는 에 있어야 합니다. 구성 요소의 setup()
단계는 동기적으로 호출됩니다. [관련 권장사항: vuejs 비디오 튜토리얼, 웹 프론트엔드 개발】app.provide()
를 통해). export function useInfiniteScroll(
element: MaybeComputedRef<HTMLElement | SVGElement | Window | Document | null | undefined>
......
) {
const state = reactive(......)
watch(
() => state.arrivedState[direction],
async (v) => {
if (v) {
const elem = resolveUnref(element) as Element
......
if (options.preserveScrollPosition && elem) {
nextTick(() => {
elem.scrollTo({
top: elem.scrollHeight - previous.height,
left: elem.scrollWidth - previous.width,
})
})
}
}
}
)
}
로그인 후 복사로그인 후 복사- 첫 번째 매개변수는 삽입된
key
입니다. Vue
는 상위 구성 요소 체인을 순회하고 키
를 일치시켜 제공된 값을 결정합니다. 상위 구성 요소 체인의 여러 구성 요소가 동일한 키
에 대한 값을 제공하는 경우 더 가까운 구성 요소가 체인 위쪽에 있는 구성 요소에서 제공한 값을 "덮어씁니다". key
와 일치하는 값이 없는 경우 기본값이 제공되지 않으면 inject()
는 undefine
을 반환합니다.
두 번째 매개변수는 선택사항이며, export function useInfiniteScroll( element: MaybeComputedRef<HTMLElement | SVGElement | Window | Document | null | undefined> ...... ) { const state = reactive(......) watch( () => state.arrivedState[direction], async (v) => { if (v) { const elem = resolveUnref(element) as Element ...... if (options.preserveScrollPosition && elem) { nextTick(() => { elem.scrollTo({ top: elem.scrollHeight - previous.height, left: elem.scrollWidth - previous.width, }) }) } } } ) }
key
입니다. Vue
는 상위 구성 요소 체인을 순회하고 키
를 일치시켜 제공된 값을 결정합니다. 상위 구성 요소 체인의 여러 구성 요소가 동일한 키
에 대한 값을 제공하는 경우 더 가까운 구성 요소가 체인 위쪽에 있는 구성 요소에서 제공한 값을 "덮어씁니다". key
와 일치하는 값이 없는 경우 기본값이 제공되지 않으면 inject()
는 undefine
을 반환합니다. 키
가 일치하지 않을 때 사용되는 기본값입니다. 또한 생성하기 더 복잡한 일부 값을 반환하는 팩토리 함수일 수도 있습니다. 기본값 자체가 함수인 경우 세 번째 매개변수로 false
를 전달하여 해당 함수가 팩토리 함수가 아니라 기본값임을 나타내야 합니다. provide() & inject() - 공식 예 function defineComponent(
component: ComponentOptions | ComponentOptions['setup']
): ComponentConstructor
로그인 후 복사로그인 후 복사rrree🎜provide( ) & inject() - ElementUI 플러스 예 🎜🎜Breadcrumb 구성 요소🎜🎜🎜const Foo = defineComponent(/* ... */)
// 提取出一个组件的实例类型 (与其选项中的 this 的类型等价)
type FooInstance = InstanceType<typeof Foo>
로그인 후 복사로그인 후 복사import { defineComponent, renderSlot, watch } from 'vue'
import { provideGlobalConfig } from './hooks/use-global-config'
import { configProviderProps } from './config-provider-props'
......
const ConfigProvider = defineComponent({
name: 'ElConfigProvider',
props: configProviderProps,
setup(props, { slots }) {
......
},
})
export type ConfigProviderInstance = InstanceType<typeof ConfigProvider>
export default ConfigProvider
로그인 후 복사로그인 후 복사 🎜 제공() & 주입() - Vue 사용 예 🎜🎜🎜createInjectionState 소스 코드 🎜 / createInjectionState 사용 🎜🎜🎜package/core/computedInject 소스 코드🎜🎜 export default /*#__PURE__*/ defineComponent(/* ... */)
로그인 후 복사로그인 후 복사🎜nextTick()🎜
🎜다음 DOM 업데이트 새로 고침을 기다리는 도구 메서드입니다. 🎜import { defineComponent, h, ref } from 'vue-demi'
import { onClickOutside } from '@vueuse/core'
import type { RenderableComponent } from '../types'
import type { OnClickOutsideOptions } from '.'
export interface OnClickOutsideProps extends RenderableComponent {
options?: OnClickOutsideOptions
}
export const OnClickOutside = /* #__PURE__ */ defineComponent<OnClickOutsideProps>({
name: 'OnClickOutside',
props: ['as', 'options'] as unknown as undefined,
emits: ['trigger'],
setup(props, { slots, emit }) {
... ...
return () => {
if (slots.default)
return h(props.as || 'div', { ref: target }, slots.default())
}
},
})
로그인 후 복사로그인 후 복사🎜참고: Vue
에서 반응 상태를 변경하면 최종 DOM
업데이트가 동기적으로 적용되지 않고 Vue
에 의해 수행됩니다. > 다음 "tick"
이 함께 실행될 때까지 대기열에 캐시합니다. 이는 상태 변경 횟수에 관계없이 각 구성 요소가 하나의 업데이트만 수행하도록 하기 위한 것입니다. 🎜🎜nextTick()
은 상태 변경 직후 DOM
업데이트가 완료될 때까지 기다리는 데 사용할 수 있습니다. 🎜콜백 함수🎜를 매개변수로 전달하거나 🎜await가 반환한 Promise🎜를 전달할 수 있습니다. 🎜🎜🎜nextTick() 공식 웹사이트 예시🎜🎜function defineAsyncComponent(
source: AsyncComponentLoader | AsyncComponentOptions
): Component
type AsyncComponentLoader = () => Promise<Component>
interface AsyncComponentOptions {
loader: AsyncComponentLoader
loadingComponent?: Component
errorComponent?: Component
delay?: number
timeout?: number
suspensible?: boolean
onError?: (
error: Error,
retry: () => void,
fail: () => void,
attempts: number
) => any
}
로그인 후 복사로그인 후 복사🎜🎜nextTick() - ElementUI Plus 예시🎜🎜🎜🎜ElCascaderPanel 소스 코드🎜🎜<script setup>
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
resolve(/* 从服务器获取到的组件 */)
})
})
const AdminPage = defineAsyncComponent(() =>
import('./components/AdminPageComponent.vue')
)
</script>
<template>
<AsyncComp />
<AdminPage />
</template>
로그인 후 복사로그인 후 복사🎜🎜nextTick() - VueUse 예시🎜🎜🎜 🎜InfiniteScroll 소스 코드 사용🎜🎜export function useInfiniteScroll(
element: MaybeComputedRef<HTMLElement | SVGElement | Window | Document | null | undefined>
......
) {
const state = reactive(......)
watch(
() => state.arrivedState[direction],
async (v) => {
if (v) {
const elem = resolveUnref(element) as Element
......
if (options.preserveScrollPosition && elem) {
nextTick(() => {
elem.scrollTo({
top: elem.scrollHeight - previous.height,
left: elem.scrollWidth - previous.width,
})
})
}
}
}
)
}
로그인 후 복사로그인 후 복사使用场景:
当你需要在修改了某些数据后立即对 DOM
进行操作时,可以使用 nextTick
来确保 DOM
已经更新完毕。例如,在使用 $ref
获取元素时,需要确保元素已经被渲染才能够正确获取。
在一些复杂页面中,有些组件可能会因为条件渲染或动态数据而频繁地变化。使用 nextTick
可以避免频繁地进行 DOM
操作,从而提高应用程序的性能。
当需要在模板中访问某些计算属性或者监听器中的值时,也可以使用 nextTick
来确保这些值已经更新完毕。这样可以避免在视图中访问到旧值。
总之,nextTick
是一个非常有用的 API,可以确保在正确的时机对 DOM
进行操作,避免出现一些不必要的问题,并且可以提高应用程序的性能。
defineComponent()
在定义 Vue
组件时提供类型推导的辅助函数。
function defineComponent(
component: ComponentOptions | ComponentOptions['setup']
): ComponentConstructor
로그인 후 복사로그인 후 복사第一个参数是一个组件选项对象。返回值将是该选项对象本身,因为该函数实际上在运行时没有任何操作,仅用于提供类型推导。
注意返回值的类型有一点特别:它会是一个构造函数类型,它的实例类型是根据选项推断出的组件实例类型。这是为了能让该返回值在 TSX
中用作标签时提供类型推导支持。
const Foo = defineComponent(/* ... */)
// 提取出一个组件的实例类型 (与其选项中的 this 的类型等价)
type FooInstance = InstanceType<typeof Foo>
로그인 후 복사로그인 후 복사参考:Vue3 - defineComponent 解决了什么?
defineComponent() - ElementUI Plus 示例
import { defineComponent, renderSlot, watch } from 'vue'
import { provideGlobalConfig } from './hooks/use-global-config'
import { configProviderProps } from './config-provider-props'
......
const ConfigProvider = defineComponent({
name: 'ElConfigProvider',
props: configProviderProps,
setup(props, { slots }) {
......
},
})
export type ConfigProviderInstance = InstanceType<typeof ConfigProvider>
export default ConfigProvider
로그인 후 복사로그인 후 복사defineComponent() - Treeshaking
因为 defineComponent()
是一个函数调用,所以它可能被某些构建工具认为会产生副作用,如 webpack
。即使一个组件从未被使用,也有可能不被 tree-shake
。
为了告诉 webpack
这个函数调用可以被安全地 tree-shake
,我们可以在函数调用之前添加一个 /_#**PURE**_/
形式的注释:
export default /*#__PURE__*/ defineComponent(/* ... */)
로그인 후 복사로그인 후 복사请注意,如果你的项目中使用的是 Vite
,就不需要这么做,因为 Rollup
(Vite
底层使用的生产环境打包工具) 可以智能地确定 defineComponent()
实际上并没有副作用,所以无需手动注释。
defineComponent() - VueUse 示例
import { defineComponent, h, ref } from 'vue-demi'
import { onClickOutside } from '@vueuse/core'
import type { RenderableComponent } from '../types'
import type { OnClickOutsideOptions } from '.'
export interface OnClickOutsideProps extends RenderableComponent {
options?: OnClickOutsideOptions
}
export const OnClickOutside = /* #__PURE__ */ defineComponent<OnClickOutsideProps>({
name: 'OnClickOutside',
props: ['as', 'options'] as unknown as undefined,
emits: ['trigger'],
setup(props, { slots, emit }) {
... ...
return () => {
if (slots.default)
return h(props.as || 'div', { ref: target }, slots.default())
}
},
})
로그인 후 복사로그인 후 복사defineAsyncComponent()
定义一个异步组件,它在运行时是懒加载的。参数可以是一个异步加载函数,或是对加载行为进行更具体定制的一个选项对象。
function defineAsyncComponent(
source: AsyncComponentLoader | AsyncComponentOptions
): Component
type AsyncComponentLoader = () => Promise<Component>
interface AsyncComponentOptions {
loader: AsyncComponentLoader
loadingComponent?: Component
errorComponent?: Component
delay?: number
timeout?: number
suspensible?: boolean
onError?: (
error: Error,
retry: () => void,
fail: () => void,
attempts: number
) => any
}
로그인 후 복사로그인 후 복사defineAsyncComponent() - 官网示例
<script setup>
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
resolve(/* 从服务器获取到的组件 */)
})
})
const AdminPage = defineAsyncComponent(() =>
import('./components/AdminPageComponent.vue')
)
</script>
<template>
<AsyncComp />
<AdminPage />
</template>
로그인 후 복사로그인 후 복사ES
模块动态导入也会返回一个 Promise
,所以多数情况下我们会将它和 defineAsyncComponent
搭配使用。类似 Vite
和 Webpack
这样的构建工具也支持此语法 (并且会将它们作为打包时的代码分割点),因此我们也可以用它来导入 Vue
单文件组件。
defineAsyncComponent() - VitePress 示例
<script setup>
import { defineAsyncComponent } from 'vue'
import type { DefaultTheme } from 'vitepress/theme'
defineProps<{ carbonAds: DefaultTheme.CarbonAdsOptions }>()
const VPCarbonAds = __CARBON__
? defineAsyncComponent(() => import('./VPCarbonAds.vue'))
: () => null
</script>
<template>
<div>
<VPCarbonAds :carbon-ads="carbonAds" />
</div>
</template>
로그인 후 복사defineAsyncComponent()
使用场景:
当你需要异步加载某些组件时,可以使用 defineAsyncComponent
来进行组件懒加载,这样可以提高应用程序的性能。
在一些复杂页面中,有些组件可能只有在用户执行特定操作或进入特定页面时才会被使用到。使用 defineAsyncComponent
可以降低初始页面加载时的资源开销。
当你需要动态地加载某些组件时,也可以使用 defineAsyncComponent
。例如,在路由中根据不同的路径加载不同的组件。
除 Vue3
之外,许多基于 Vue 3
的库和框架也开始使用 defineAsyncComponent
来实现组件的异步加载。例如:
- VitePress:
Vite
的官方文档工具,使用 defineAsyncComponent
来实现文档页面的异步加载。 - Nuxt.js: 基于 Vue.js 的静态网站生成器,从版本 2.15 开始支持
defineAsyncComponent
。 - Quasar Framework: 基于
Vue.js
的 UI 框架,从版本 2.0 开始支持 defineAsyncComponent
。 - Element UI Plus: 基于
Vue 3
的 UI 库,使用 defineAsyncComponent
来实现组件的异步加载。
总之,随着 Vue 3 的普及,越来越多的库和框架都开始使用 defineAsyncComponent
来提高应用程序的性能。
defineCustomElement()
这个方法和 defineComponent
接受的参数相同,不同的是会返回一个原生自定义元素类的构造器。
function defineCustomElement(
component:
| (ComponentOptions & { styles?: string[] })
| ComponentOptions['setup']
): {
new (props?: object): HTMLElement
}
로그인 후 복사除了常规的组件选项,defineCustomElement()
还支持一个特别的选项 styles
,它应该是一个内联 CSS
字符串的数组,所提供的 CSS
会被注入到该元素的 shadow root
上。
返回值是一个可以通过 customElements.define()
注册的自定义元素构造器。
import { defineCustomElement } from 'vue'
const MyVueElement = defineCustomElement({
/* 组件选项 */
})
// 注册自定义元素
customElements.define('my-vue-element', MyVueElement)
로그인 후 복사使用 Vue 构建自定义元素
import { defineCustomElement } from 'vue'
const MyVueElement = defineCustomElement({
// 这里是同平常一样的 Vue 组件选项
props: {},
emits: {},
template: `...`,
// defineCustomElement 特有的:注入进 shadow root 的 CSS
styles: [`/* inlined css */`],
})
// 注册自定义元素
// 注册之后,所有此页面中的 `<my-vue-element>` 标签
// 都会被升级
customElements.define('my-vue-element', MyVueElement)
// 你也可以编程式地实例化元素:
// (必须在注册之后)
document.body.appendChild(
new MyVueElement({
// 初始化 props(可选)
})
)
// 组件使用
<my-vue-element></my-vue-element>
로그인 후 복사除了 Vue 3
之外,一些基于 Vue 3
的库和框架也开始使用 defineCustomElement
来将 Vue
组件打包成自定义元素供其他框架或纯 HTML 页面使用。例如:
-
Ionic Framework: 基于
Web Components
的移动端 UI 框架,从版本 6 开始支持使用 defineCustomElement
将 Ionic
组件打包成自定义元素。
-
LitElement: Google 推出的
Web Components
库,提供类似 Vue
的模板语法,并支持使用 defineCustomElement
将 LitElement
组件打包成自定义元素。
-
Stencil: 由
Ionic Team
开发的 Web Components
工具链,可以将任何框架的组件转换为自定义元素,并支持使用 defineCustomElement
直接将 Vue
组件打包成自定义元素。
总之,随着 Web Components
的不断流行和发展,越来越多的库和框架都开始使用 defineCustomElement
来实现跨框架、跨平台的组件共享。
小结
本次我们围绕着 Vue3
中的依赖注入与组件定义相关的几个 API,学习其基本使用方法,并且结合着目前流行的库和框架分析了使用场景,以此来加深我们对它们的认识。
内容收录于github 仓库
위 내용은 Vue3의 종속성 주입 및 구성 요소 정의에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!
function defineComponent( component: ComponentOptions | ComponentOptions['setup'] ): ComponentConstructor
const Foo = defineComponent(/* ... */) // 提取出一个组件的实例类型 (与其选项中的 this 的类型等价) type FooInstance = InstanceType<typeof Foo>
import { defineComponent, renderSlot, watch } from 'vue' import { provideGlobalConfig } from './hooks/use-global-config' import { configProviderProps } from './config-provider-props' ...... const ConfigProvider = defineComponent({ name: 'ElConfigProvider', props: configProviderProps, setup(props, { slots }) { ...... }, }) export type ConfigProviderInstance = InstanceType<typeof ConfigProvider> export default ConfigProvider
🎜 제공() & 주입() - Vue 사용 예 🎜🎜🎜createInjectionState 소스 코드 🎜 / createInjectionState 사용 🎜🎜🎜package/core/computedInject 소스 코드🎜🎜 export default /*#__PURE__*/ defineComponent(/* ... */)
로그인 후 복사로그인 후 복사🎜nextTick()🎜
🎜다음 DOM 업데이트 새로 고침을 기다리는 도구 메서드입니다. 🎜import { defineComponent, h, ref } from 'vue-demi'
import { onClickOutside } from '@vueuse/core'
import type { RenderableComponent } from '../types'
import type { OnClickOutsideOptions } from '.'
export interface OnClickOutsideProps extends RenderableComponent {
options?: OnClickOutsideOptions
}
export const OnClickOutside = /* #__PURE__ */ defineComponent<OnClickOutsideProps>({
name: 'OnClickOutside',
props: ['as', 'options'] as unknown as undefined,
emits: ['trigger'],
setup(props, { slots, emit }) {
... ...
return () => {
if (slots.default)
return h(props.as || 'div', { ref: target }, slots.default())
}
},
})
로그인 후 복사로그인 후 복사🎜참고: Vue
에서 반응 상태를 변경하면 최종 DOM
업데이트가 동기적으로 적용되지 않고 Vue
에 의해 수행됩니다. > 다음 "tick"
이 함께 실행될 때까지 대기열에 캐시합니다. 이는 상태 변경 횟수에 관계없이 각 구성 요소가 하나의 업데이트만 수행하도록 하기 위한 것입니다. 🎜🎜nextTick()
은 상태 변경 직후 DOM
업데이트가 완료될 때까지 기다리는 데 사용할 수 있습니다. 🎜콜백 함수🎜를 매개변수로 전달하거나 🎜await가 반환한 Promise🎜를 전달할 수 있습니다. 🎜🎜🎜nextTick() 공식 웹사이트 예시🎜🎜function defineAsyncComponent(
source: AsyncComponentLoader | AsyncComponentOptions
): Component
type AsyncComponentLoader = () => Promise<Component>
interface AsyncComponentOptions {
loader: AsyncComponentLoader
loadingComponent?: Component
errorComponent?: Component
delay?: number
timeout?: number
suspensible?: boolean
onError?: (
error: Error,
retry: () => void,
fail: () => void,
attempts: number
) => any
}
로그인 후 복사로그인 후 복사🎜🎜nextTick() - ElementUI Plus 예시🎜🎜🎜🎜ElCascaderPanel 소스 코드🎜🎜<script setup>
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
resolve(/* 从服务器获取到的组件 */)
})
})
const AdminPage = defineAsyncComponent(() =>
import('./components/AdminPageComponent.vue')
)
</script>
<template>
<AsyncComp />
<AdminPage />
</template>
로그인 후 복사로그인 후 복사🎜🎜nextTick() - VueUse 예시🎜🎜🎜 🎜InfiniteScroll 소스 코드 사용🎜🎜export function useInfiniteScroll(
element: MaybeComputedRef<HTMLElement | SVGElement | Window | Document | null | undefined>
......
) {
const state = reactive(......)
watch(
() => state.arrivedState[direction],
async (v) => {
if (v) {
const elem = resolveUnref(element) as Element
......
if (options.preserveScrollPosition && elem) {
nextTick(() => {
elem.scrollTo({
top: elem.scrollHeight - previous.height,
left: elem.scrollWidth - previous.width,
})
})
}
}
}
)
}
로그인 후 복사로그인 후 복사使用场景:
当你需要在修改了某些数据后立即对 DOM
进行操作时,可以使用 nextTick
来确保 DOM
已经更新完毕。例如,在使用 $ref
获取元素时,需要确保元素已经被渲染才能够正确获取。
在一些复杂页面中,有些组件可能会因为条件渲染或动态数据而频繁地变化。使用 nextTick
可以避免频繁地进行 DOM
操作,从而提高应用程序的性能。
当需要在模板中访问某些计算属性或者监听器中的值时,也可以使用 nextTick
来确保这些值已经更新完毕。这样可以避免在视图中访问到旧值。
总之,nextTick
是一个非常有用的 API,可以确保在正确的时机对 DOM
进行操作,避免出现一些不必要的问题,并且可以提高应用程序的性能。
defineComponent()
在定义 Vue
组件时提供类型推导的辅助函数。
function defineComponent(
component: ComponentOptions | ComponentOptions['setup']
): ComponentConstructor
로그인 후 복사로그인 후 복사第一个参数是一个组件选项对象。返回值将是该选项对象本身,因为该函数实际上在运行时没有任何操作,仅用于提供类型推导。
注意返回值的类型有一点特别:它会是一个构造函数类型,它的实例类型是根据选项推断出的组件实例类型。这是为了能让该返回值在 TSX
中用作标签时提供类型推导支持。
const Foo = defineComponent(/* ... */)
// 提取出一个组件的实例类型 (与其选项中的 this 的类型等价)
type FooInstance = InstanceType<typeof Foo>
로그인 후 복사로그인 후 복사参考:Vue3 - defineComponent 解决了什么?
defineComponent() - ElementUI Plus 示例
import { defineComponent, renderSlot, watch } from 'vue'
import { provideGlobalConfig } from './hooks/use-global-config'
import { configProviderProps } from './config-provider-props'
......
const ConfigProvider = defineComponent({
name: 'ElConfigProvider',
props: configProviderProps,
setup(props, { slots }) {
......
},
})
export type ConfigProviderInstance = InstanceType<typeof ConfigProvider>
export default ConfigProvider
로그인 후 복사로그인 후 복사defineComponent() - Treeshaking
因为 defineComponent()
是一个函数调用,所以它可能被某些构建工具认为会产生副作用,如 webpack
。即使一个组件从未被使用,也有可能不被 tree-shake
。
为了告诉 webpack
这个函数调用可以被安全地 tree-shake
,我们可以在函数调用之前添加一个 /_#**PURE**_/
形式的注释:
export default /*#__PURE__*/ defineComponent(/* ... */)
로그인 후 복사로그인 후 복사请注意,如果你的项目中使用的是 Vite
,就不需要这么做,因为 Rollup
(Vite
底层使用的生产环境打包工具) 可以智能地确定 defineComponent()
实际上并没有副作用,所以无需手动注释。
defineComponent() - VueUse 示例
import { defineComponent, h, ref } from 'vue-demi'
import { onClickOutside } from '@vueuse/core'
import type { RenderableComponent } from '../types'
import type { OnClickOutsideOptions } from '.'
export interface OnClickOutsideProps extends RenderableComponent {
options?: OnClickOutsideOptions
}
export const OnClickOutside = /* #__PURE__ */ defineComponent<OnClickOutsideProps>({
name: 'OnClickOutside',
props: ['as', 'options'] as unknown as undefined,
emits: ['trigger'],
setup(props, { slots, emit }) {
... ...
return () => {
if (slots.default)
return h(props.as || 'div', { ref: target }, slots.default())
}
},
})
로그인 후 복사로그인 후 복사defineAsyncComponent()
定义一个异步组件,它在运行时是懒加载的。参数可以是一个异步加载函数,或是对加载行为进行更具体定制的一个选项对象。
function defineAsyncComponent(
source: AsyncComponentLoader | AsyncComponentOptions
): Component
type AsyncComponentLoader = () => Promise<Component>
interface AsyncComponentOptions {
loader: AsyncComponentLoader
loadingComponent?: Component
errorComponent?: Component
delay?: number
timeout?: number
suspensible?: boolean
onError?: (
error: Error,
retry: () => void,
fail: () => void,
attempts: number
) => any
}
로그인 후 복사로그인 후 복사defineAsyncComponent() - 官网示例
<script setup>
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
resolve(/* 从服务器获取到的组件 */)
})
})
const AdminPage = defineAsyncComponent(() =>
import('./components/AdminPageComponent.vue')
)
</script>
<template>
<AsyncComp />
<AdminPage />
</template>
로그인 후 복사로그인 후 복사ES
模块动态导入也会返回一个 Promise
,所以多数情况下我们会将它和 defineAsyncComponent
搭配使用。类似 Vite
和 Webpack
这样的构建工具也支持此语法 (并且会将它们作为打包时的代码分割点),因此我们也可以用它来导入 Vue
单文件组件。
defineAsyncComponent() - VitePress 示例
<script setup>
import { defineAsyncComponent } from 'vue'
import type { DefaultTheme } from 'vitepress/theme'
defineProps<{ carbonAds: DefaultTheme.CarbonAdsOptions }>()
const VPCarbonAds = __CARBON__
? defineAsyncComponent(() => import('./VPCarbonAds.vue'))
: () => null
</script>
<template>
<div>
<VPCarbonAds :carbon-ads="carbonAds" />
</div>
</template>
로그인 후 복사defineAsyncComponent()
使用场景:
当你需要异步加载某些组件时,可以使用 defineAsyncComponent
来进行组件懒加载,这样可以提高应用程序的性能。
在一些复杂页面中,有些组件可能只有在用户执行特定操作或进入特定页面时才会被使用到。使用 defineAsyncComponent
可以降低初始页面加载时的资源开销。
当你需要动态地加载某些组件时,也可以使用 defineAsyncComponent
。例如,在路由中根据不同的路径加载不同的组件。
除 Vue3
之外,许多基于 Vue 3
的库和框架也开始使用 defineAsyncComponent
来实现组件的异步加载。例如:
- VitePress:
Vite
的官方文档工具,使用 defineAsyncComponent
来实现文档页面的异步加载。 - Nuxt.js: 基于 Vue.js 的静态网站生成器,从版本 2.15 开始支持
defineAsyncComponent
。 - Quasar Framework: 基于
Vue.js
的 UI 框架,从版本 2.0 开始支持 defineAsyncComponent
。 - Element UI Plus: 基于
Vue 3
的 UI 库,使用 defineAsyncComponent
来实现组件的异步加载。
总之,随着 Vue 3 的普及,越来越多的库和框架都开始使用 defineAsyncComponent
来提高应用程序的性能。
defineCustomElement()
这个方法和 defineComponent
接受的参数相同,不同的是会返回一个原生自定义元素类的构造器。
function defineCustomElement(
component:
| (ComponentOptions & { styles?: string[] })
| ComponentOptions['setup']
): {
new (props?: object): HTMLElement
}
로그인 후 복사除了常规的组件选项,defineCustomElement()
还支持一个特别的选项 styles
,它应该是一个内联 CSS
字符串的数组,所提供的 CSS
会被注入到该元素的 shadow root
上。
返回值是一个可以通过 customElements.define()
注册的自定义元素构造器。
import { defineCustomElement } from 'vue'
const MyVueElement = defineCustomElement({
/* 组件选项 */
})
// 注册自定义元素
customElements.define('my-vue-element', MyVueElement)
로그인 후 복사使用 Vue 构建自定义元素
import { defineCustomElement } from 'vue'
const MyVueElement = defineCustomElement({
// 这里是同平常一样的 Vue 组件选项
props: {},
emits: {},
template: `...`,
// defineCustomElement 特有的:注入进 shadow root 的 CSS
styles: [`/* inlined css */`],
})
// 注册自定义元素
// 注册之后,所有此页面中的 `<my-vue-element>` 标签
// 都会被升级
customElements.define('my-vue-element', MyVueElement)
// 你也可以编程式地实例化元素:
// (必须在注册之后)
document.body.appendChild(
new MyVueElement({
// 初始化 props(可选)
})
)
// 组件使用
<my-vue-element></my-vue-element>
로그인 후 복사除了 Vue 3
之外,一些基于 Vue 3
的库和框架也开始使用 defineCustomElement
来将 Vue
组件打包成自定义元素供其他框架或纯 HTML 页面使用。例如:
-
Ionic Framework: 基于
Web Components
的移动端 UI 框架,从版本 6 开始支持使用 defineCustomElement
将 Ionic
组件打包成自定义元素。
-
LitElement: Google 推出的
Web Components
库,提供类似 Vue
的模板语法,并支持使用 defineCustomElement
将 LitElement
组件打包成自定义元素。
-
Stencil: 由
Ionic Team
开发的 Web Components
工具链,可以将任何框架的组件转换为自定义元素,并支持使用 defineCustomElement
直接将 Vue
组件打包成自定义元素。
总之,随着 Web Components
的不断流行和发展,越来越多的库和框架都开始使用 defineCustomElement
来实现跨框架、跨平台的组件共享。
小结
本次我们围绕着 Vue3
中的依赖注入与组件定义相关的几个 API,学习其基本使用方法,并且结合着目前流行的库和框架分析了使用场景,以此来加深我们对它们的认识。
内容收录于github 仓库
위 내용은 Vue3의 종속성 주입 및 구성 요소 정의에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!
export default /*#__PURE__*/ defineComponent(/* ... */)
import { defineComponent, h, ref } from 'vue-demi' import { onClickOutside } from '@vueuse/core' import type { RenderableComponent } from '../types' import type { OnClickOutsideOptions } from '.' export interface OnClickOutsideProps extends RenderableComponent { options?: OnClickOutsideOptions } export const OnClickOutside = /* #__PURE__ */ defineComponent<OnClickOutsideProps>({ name: 'OnClickOutside', props: ['as', 'options'] as unknown as undefined, emits: ['trigger'], setup(props, { slots, emit }) { ... ... return () => { if (slots.default) return h(props.as || 'div', { ref: target }, slots.default()) } }, })
function defineAsyncComponent( source: AsyncComponentLoader | AsyncComponentOptions ): Component type AsyncComponentLoader = () => Promise<Component> interface AsyncComponentOptions { loader: AsyncComponentLoader loadingComponent?: Component errorComponent?: Component delay?: number timeout?: number suspensible?: boolean onError?: ( error: Error, retry: () => void, fail: () => void, attempts: number ) => any }
<script setup> import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { resolve(/* 从服务器获取到的组件 */) }) }) const AdminPage = defineAsyncComponent(() => import('./components/AdminPageComponent.vue') ) </script> <template> <AsyncComp /> <AdminPage /> </template>
export function useInfiniteScroll( element: MaybeComputedRef<HTMLElement | SVGElement | Window | Document | null | undefined> ...... ) { const state = reactive(......) watch( () => state.arrivedState[direction], async (v) => { if (v) { const elem = resolveUnref(element) as Element ...... if (options.preserveScrollPosition && elem) { nextTick(() => { elem.scrollTo({ top: elem.scrollHeight - previous.height, left: elem.scrollWidth - previous.width, }) }) } } } ) }
当你需要在修改了某些数据后立即对 DOM
进行操作时,可以使用 nextTick
来确保 DOM
已经更新完毕。例如,在使用 $ref
获取元素时,需要确保元素已经被渲染才能够正确获取。
在一些复杂页面中,有些组件可能会因为条件渲染或动态数据而频繁地变化。使用 nextTick
可以避免频繁地进行 DOM
操作,从而提高应用程序的性能。
当需要在模板中访问某些计算属性或者监听器中的值时,也可以使用 nextTick
来确保这些值已经更新完毕。这样可以避免在视图中访问到旧值。
nextTick
是一个非常有用的 API,可以确保在正确的时机对 DOM
进行操作,避免出现一些不必要的问题,并且可以提高应用程序的性能。Vue
组件时提供类型推导的辅助函数。function defineComponent( component: ComponentOptions | ComponentOptions['setup'] ): ComponentConstructor
TSX
中用作标签时提供类型推导支持。const Foo = defineComponent(/* ... */) // 提取出一个组件的实例类型 (与其选项中的 this 的类型等价) type FooInstance = InstanceType<typeof Foo>
import { defineComponent, renderSlot, watch } from 'vue' import { provideGlobalConfig } from './hooks/use-global-config' import { configProviderProps } from './config-provider-props' ...... const ConfigProvider = defineComponent({ name: 'ElConfigProvider', props: configProviderProps, setup(props, { slots }) { ...... }, }) export type ConfigProviderInstance = InstanceType<typeof ConfigProvider> export default ConfigProvider
defineComponent()
是一个函数调用,所以它可能被某些构建工具认为会产生副作用,如 webpack
。即使一个组件从未被使用,也有可能不被 tree-shake
。webpack
这个函数调用可以被安全地 tree-shake
,我们可以在函数调用之前添加一个 /_#**PURE**_/
形式的注释:export default /*#__PURE__*/ defineComponent(/* ... */)
Vite
,就不需要这么做,因为 Rollup
(Vite
底层使用的生产环境打包工具) 可以智能地确定 defineComponent()
实际上并没有副作用,所以无需手动注释。import { defineComponent, h, ref } from 'vue-demi' import { onClickOutside } from '@vueuse/core' import type { RenderableComponent } from '../types' import type { OnClickOutsideOptions } from '.' export interface OnClickOutsideProps extends RenderableComponent { options?: OnClickOutsideOptions } export const OnClickOutside = /* #__PURE__ */ defineComponent<OnClickOutsideProps>({ name: 'OnClickOutside', props: ['as', 'options'] as unknown as undefined, emits: ['trigger'], setup(props, { slots, emit }) { ... ... return () => { if (slots.default) return h(props.as || 'div', { ref: target }, slots.default()) } }, })
function defineAsyncComponent( source: AsyncComponentLoader | AsyncComponentOptions ): Component type AsyncComponentLoader = () => Promise<Component> interface AsyncComponentOptions { loader: AsyncComponentLoader loadingComponent?: Component errorComponent?: Component delay?: number timeout?: number suspensible?: boolean onError?: ( error: Error, retry: () => void, fail: () => void, attempts: number ) => any }
<script setup> import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { resolve(/* 从服务器获取到的组件 */) }) }) const AdminPage = defineAsyncComponent(() => import('./components/AdminPageComponent.vue') ) </script> <template> <AsyncComp /> <AdminPage /> </template>
ES
模块动态导入也会返回一个 Promise
,所以多数情况下我们会将它和 defineAsyncComponent
搭配使用。类似 Vite
和 Webpack
这样的构建工具也支持此语法 (并且会将它们作为打包时的代码分割点),因此我们也可以用它来导入 Vue
单文件组件。<script setup> import { defineAsyncComponent } from 'vue' import type { DefaultTheme } from 'vitepress/theme' defineProps<{ carbonAds: DefaultTheme.CarbonAdsOptions }>() const VPCarbonAds = __CARBON__ ? defineAsyncComponent(() => import('./VPCarbonAds.vue')) : () => null </script> <template> <div> <VPCarbonAds :carbon-ads="carbonAds" /> </div> </template>
defineAsyncComponent()
使用场景:当你需要异步加载某些组件时,可以使用 defineAsyncComponent
来进行组件懒加载,这样可以提高应用程序的性能。
在一些复杂页面中,有些组件可能只有在用户执行特定操作或进入特定页面时才会被使用到。使用 defineAsyncComponent
可以降低初始页面加载时的资源开销。
当你需要动态地加载某些组件时,也可以使用 defineAsyncComponent
。例如,在路由中根据不同的路径加载不同的组件。
Vue3
之外,许多基于 Vue 3
的库和框架也开始使用 defineAsyncComponent
来实现组件的异步加载。例如:Vite
的官方文档工具,使用 defineAsyncComponent
来实现文档页面的异步加载。defineAsyncComponent
。Vue.js
的 UI 框架,从版本 2.0 开始支持 defineAsyncComponent
。Vue 3
的 UI 库,使用 defineAsyncComponent
来实现组件的异步加载。defineAsyncComponent
来提高应用程序的性能。defineComponent
接受的参数相同,不同的是会返回一个原生自定义元素类的构造器。function defineCustomElement( component: | (ComponentOptions & { styles?: string[] }) | ComponentOptions['setup'] ): { new (props?: object): HTMLElement }
defineCustomElement()
还支持一个特别的选项 styles
,它应该是一个内联 CSS
字符串的数组,所提供的 CSS
会被注入到该元素的 shadow root
上。
返回值是一个可以通过 customElements.define()
注册的自定义元素构造器。import { defineCustomElement } from 'vue' const MyVueElement = defineCustomElement({ /* 组件选项 */ }) // 注册自定义元素 customElements.define('my-vue-element', MyVueElement)
import { defineCustomElement } from 'vue' const MyVueElement = defineCustomElement({ // 这里是同平常一样的 Vue 组件选项 props: {}, emits: {}, template: `...`, // defineCustomElement 特有的:注入进 shadow root 的 CSS styles: [`/* inlined css */`], }) // 注册自定义元素 // 注册之后,所有此页面中的 `<my-vue-element>` 标签 // 都会被升级 customElements.define('my-vue-element', MyVueElement) // 你也可以编程式地实例化元素: // (必须在注册之后) document.body.appendChild( new MyVueElement({ // 初始化 props(可选) }) ) // 组件使用 <my-vue-element></my-vue-element>
Vue 3
之外,一些基于 Vue 3
的库和框架也开始使用 defineCustomElement
来将 Vue
组件打包成自定义元素供其他框架或纯 HTML 页面使用。例如:Web Components
的移动端 UI 框架,从版本 6 开始支持使用 defineCustomElement
将 Ionic
组件打包成自定义元素。Web Components
库,提供类似 Vue
的模板语法,并支持使用 defineCustomElement
将 LitElement
组件打包成自定义元素。Ionic Team
开发的 Web Components
工具链,可以将任何框架的组件转换为自定义元素,并支持使用 defineCustomElement
直接将 Vue
组件打包成自定义元素。Web Components
的不断流行和发展,越来越多的库和框架都开始使用 defineCustomElement
来实现跨框架、跨平台的组件共享。Vue3
中的依赖注入与组件定义相关的几个 API,学习其基本使用方法,并且结合着目前流行的库和框架分析了使用场景,以此来加深我们对它们的认识。
핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











vue.js에서 bootstrap 사용은 5 단계로 나뉩니다 : Bootstrap 설치. main.js.의 부트 스트랩 가져 오기 부트 스트랩 구성 요소를 템플릿에서 직접 사용하십시오. 선택 사항 : 사용자 정의 스타일. 선택 사항 : 플러그인을 사용하십시오.

HTML 템플릿의 버튼을 메소드에 바인딩하여 VUE 버튼에 함수를 추가 할 수 있습니다. 메소드를 정의하고 VUE 인스턴스에서 기능 로직을 작성하십시오.

vue.js의 시계 옵션을 사용하면 개발자가 특정 데이터의 변경 사항을들을 수 있습니다. 데이터가 변경되면 콜백 기능을 트리거하여 업데이트보기 또는 기타 작업을 수행합니다. 구성 옵션에는 즉시 콜백을 실행할지 여부와 DEEP를 지정하는 즉시 포함되며, 이는 객체 또는 어레이에 대한 변경 사항을 재귀 적으로 듣는 지 여부를 지정합니다.

VUE 멀티 페이지 개발은 vue.js 프레임 워크를 사용하여 응용 프로그램을 구축하는 방법입니다. 여기서 응용 프로그램은 별도의 페이지로 나뉩니다. 코드 유지 보수 : 응용 프로그램을 여러 페이지로 분할하면 코드를보다 쉽게 관리하고 유지 관리 할 수 있습니다. 모듈 식 : 각 페이지는 쉬운 재사용 및 교체를 위해 별도의 모듈로 사용할 수 있습니다. 간단한 라우팅 : 페이지 간의 탐색은 간단한 라우팅 구성을 통해 관리 할 수 있습니다. SEO 최적화 : 각 페이지에는 자체 URL이있어 SEO가 도움이됩니다.

vue.js에서 JS 파일을 참조하는 세 가지 방법이 있습니다. & lt; script & gt; 꼬리표;; mounted () 라이프 사이클 후크를 사용한 동적 가져 오기; Vuex State Management Library를 통해 수입.

vue.js는 이전 페이지로 돌아갈 수있는 네 가지 방법이 있습니다. $ router.go (-1) $ router.back () 사용 & lt; router-link to = & quot;/quot; Component Window.history.back () 및 메소드 선택은 장면에 따라 다릅니다.

vue.js가 트래버스 어레이 및 객체에 대한 세 가지 일반적인 방법이 있습니다. V- 결합 지시문은 V-FOR와 함께 사용하여 각 요소의 속성 값을 동적으로 설정할 수 있습니다. .MAP 메소드는 배열 요소를 새 배열로 변환 할 수 있습니다.

VUE에서 DIV 요소를 점프하는 두 가지 방법이 있습니다. VUE 라우터를 사용하고 라우터 링크 구성 요소를 추가하십시오. @Click 이벤트 리스너를 추가하고 이것을 호출하십시오. $ router.push () 메소드를 점프하십시오.
