diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index e2658142..36412420 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -34,6 +34,7 @@ export type Data = { [key: string]: unknown } export interface SFCInternalOptions { __scopeId?: string + __cssModules?: Data __hmrId?: string __hmrUpdated?: boolean } diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index f9c2c8ee..cfcc2726 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -121,11 +121,18 @@ export const PublicInstanceProxyHandlers: ProxyHandler = { // public $xxx properties & user-attached properties (sink) const publicGetter = publicPropertiesMap[key] - if (publicGetter !== undefined) { + let cssModule + if (publicGetter != null) { if (__DEV__ && key === '$attrs') { markAttrsAccessed() } return publicGetter(target) + } else if ( + __BUNDLER__ && + (cssModule = type.__cssModules) != null && + (cssModule = cssModule[key]) + ) { + return cssModule } else if (hasOwn(sink, key)) { return sink[key] } else if (__DEV__ && currentRenderingInstance != null) { diff --git a/packages/runtime-core/src/helpers/useCssModule.ts b/packages/runtime-core/src/helpers/useCssModule.ts new file mode 100644 index 00000000..b838835f --- /dev/null +++ b/packages/runtime-core/src/helpers/useCssModule.ts @@ -0,0 +1,23 @@ +import { getCurrentInstance } from '../component' +import { EMPTY_OBJ } from '@vue/shared' +import { warn } from '../warning' + +export function useCSSModule(name = '$style'): Record { + const instance = getCurrentInstance()! + if (!instance) { + __DEV__ && warn(`useCSSModule must be called inside setup()`) + return EMPTY_OBJ + } + const modules = instance.type.__cssModules + if (!modules) { + __DEV__ && warn(`Current instance does not have CSS modules injected.`) + return EMPTY_OBJ + } + const mod = modules[name] + if (!mod) { + __DEV__ && + warn(`Current instance does not have CSS module named "${name}".`) + return EMPTY_OBJ + } + return mod as Record +} diff --git a/packages/runtime-core/src/hmr.ts b/packages/runtime-core/src/hmr.ts index 940f01d0..84433067 100644 --- a/packages/runtime-core/src/hmr.ts +++ b/packages/runtime-core/src/hmr.ts @@ -59,9 +59,11 @@ function createRecord(id: string, comp: ComponentOptions): boolean { return true } -function rerender(id: string, newRender: RenderFunction) { +function rerender(id: string, newRender?: RenderFunction) { map.get(id)!.instances.forEach(instance => { - instance.render = newRender + if (newRender) { + instance.render = newRender + } instance.renderCache = [] // this flag forces child components with slot content to update instance.renderUpdated = true diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index dbf89cba..782f93f2 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -51,6 +51,9 @@ export const PatchFlags = PublicPatchFlags as { BAIL: number } +// SFC CSS Modules +export { useCSSModule } from './helpers/useCssModule' + // For custom renderers export { createRenderer, RootRenderFunction } from './renderer' export { warn } from './warning'