Browse Source

feat(sfc): css modules support

Evan You 6 years ago
parent
commit
d84cf3a538

+ 1 - 0
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
 }

+ 8 - 1
packages/runtime-core/src/componentProxy.ts

@@ -121,11 +121,18 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
 
     // 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) {

+ 23 - 0
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<string, string> {
+  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<string, string>
+}

+ 4 - 2
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

+ 3 - 0
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'