Vue3中的依赖注入与组件定义怎么实现
本篇内容主要讲解“Vue3中的依赖注入与组件定义怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue3中的依赖注入与组件定义怎么实现”吧!
专注于为中小企业提供成都网站设计、成都网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业高碑店免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了成百上千企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
provide() & inject()
provide()
提供一个值,可以被后代组件注入。
function provide
接收两个参数:
要注入的
key
,字符串或者Symbol
;
export interface InjectionKey
对应注入的值
与注册生命周期钩子的 API
类似,provide()
必须在组件的 setup()
阶段同步调用。
inject()
注入一个由祖先组件或整个应用 (通过 app.provide()
) 提供的值。
// 没有默认值
function inject
第一个参数是注入的
key
。Vue
会遍历父组件链,通过匹配key
来确定所提供的值。如果父组件链上多个组件对同一个key
提供了值,那么离得更近的组件将会“覆盖”链上更远的组件所提供的值。如果没有能通过key
匹配到值,inject()
将返回undefined
,除非提供了一个默认值。第二个参数是可选的,即在没有匹配到
key
时使用的默认值。它也可以是一个工厂函数,用来返回某些创建起来比较复杂的值。如果默认值本身就是一个函数,那么你必须将false
作为第三个参数传入,表明这个函数就是默认值,而不是一个工厂函数。
provide() & inject() - 官方示例
// provide
// inject
provide() & inject() - ElementUI Plus 示例Breadcrumb 组件
provide() & inject() - VueUse 示例
createInjectionState 源码 / createInjectionState 使用
package/core/computedInject 源码
import { type InjectionKey, inject, provide } from 'vue-demi'
/**
* 创建可以注入到组件中的全局状态
*/
export function createInjectionState
nextTick()
等待下一次 DOM 更新刷新的工具方法。
function nextTick(callback?: () => void): Promise
说明:当你在 Vue
中更改响应式状态时,最终的 DOM
更新并不是同步生效的,而是由 Vue
将它们缓存在一个队列中,直到下一个“tick”
才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。
nextTick()
可以在状态改变后立即使用,以等待 DOM
更新完成。你可以传递一个回调函数作为参数,或者 await 返回的 Promise。
nextTick() 官网示例
nextTick() - ElementUI Plus 示例
ElCascaderPanel 源码
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)
}
})
}
......
})
nextTick() - VueUse 示例
useInfiniteScroll 源码
export function useInfiniteScroll(
element: MaybeComputedRef
使用场景:
当你需要在修改了某些数据后立即对
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
参考:Vue3 - defineComponent 解决了什么?
defineComponent() - ElementUI Plus 示例
ConfigProvider 源码
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
defineComponent() - Treeshaking
因为 defineComponent()
是一个函数调用,所以它可能被某些构建工具认为会产生副作用,如 webpack
。即使一个组件从未被使用,也有可能不被 tree-shake
。
为了告诉 webpack
这个函数调用可以被安全地 tree-shake
,我们可以在函数调用之前添加一个 /_#**PURE**_/
形式的注释:
export default /*#__PURE__*/ defineComponent(/* ... */)
请注意,如果你的项目中使用的是 Vite
,就不需要这么做,因为 Rollup
(Vite
底层使用的生产环境打包工具) 可以智能地确定 defineComponent()
实际上并没有副作用,所以无需手动注释。
defineComponent() - VueUse 示例
OnClickOutside 源码
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
defineAsyncComponent()
定义一个异步组件,它在运行时是懒加载的。参数可以是一个异步加载函数,或是对加载行为进行更具体定制的一个选项对象。
function defineAsyncComponent(
source: AsyncComponentLoader | AsyncComponentOptions
): Component
type AsyncComponentLoader = () => Promise
defineAsyncComponent() - 官网示例
ES
模块动态导入也会返回一个 Promise
,所以多数情况下我们会将它和 defineAsyncComponent
搭配使用。类似 Vite
和 Webpack
这样的构建工具也支持此语法 (并且会将它们作为打包时的代码分割点),因此我们也可以用它来导入 Vue
单文件组件。
defineAsyncComponent() -VitePress 示例
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 */`],
})
// 注册自定义元素
// 注册之后,所有此页面中的 `
除了 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
组件打包成自定义元素。
到此,相信大家对“Vue3中的依赖注入与组件定义怎么实现”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
分享标题:Vue3中的依赖注入与组件定义怎么实现
转载来源:http://myzitong.com/article/jihpip.html