Skip to content

@vue/compiler-sfc是给什么用的, 用调用链表示谁调用了它

js
`@vue/compiler-sfc` 的主要用途是解析和编译 Vue.js 的单文件组件(Single File Components,SFCs)。这个库通常不会被直接调用,而是在 Vue 开发和构建工具中被使用,作为处理 .vue 文件的核心工具。

### `@vue/compiler-sfc` 的调用链

要显示 `@vue/compiler-sfc` 的调用链,我们可以考虑它在一个典型的 Vue 项目中的使用场景。以下是一种常见的调用链表示:

1. **开发工具(如 Vue CLI、Vite 等)**
   - 开发者配置和运行构建工具,这些工具设置项目的构建过程,包括解析和编译源代码。

2. **构建工具的 SFC 解析器插件**
   - Vue CLI 或 Vite 使用内部或第三方插件来处理 .vue 文件。这些插件利用 `@vue/compiler-sfc` 来解析和编译 `.vue` 文件。

3. **`@vue/compiler-sfc`**
   - 被插件调用来处理单文件组件。它会解析组件的各个部分(模板、脚本、样式),并将模板编译成 JavaScript 渲染函数。

4. **生成的代码**
   - `@vue/compiler-sfc` 返回经过处理的组件代码,此代码可用于进一步的打包和优化,最终生成可以在浏览器中运行的 JavaScript。

5. **应用在浏览器中运行**
   - 打包过的代码通过浏览器执行,实现最终的应用效果。

### 实际代码中怎么体现

在实际项目中,`@vue/compiler-sfc` 的使用通常被抽象掉了,开发者不需要直接与它交互。例如:


// 假设在一个 Vite 项目中使用 Vue
import { createApp } from 'vue';
import App from './App.vue';

// 这里的 .vue 文件会自动被处理,
// 通过 Vite 或构建工具背后的调用链使用 `@vue/compiler-sfc`
const app = createApp(App);
app.mount('#app');


在上面的例子中,对 `App.vue` 的引用将自动触发 Vite 中的相应插件来使用 `@vue/compiler-sfc` 解析和编译这个组件文件。

因此,`@vue/compiler-sfc` 的调用链是从开发工具到插件系统,最终在内部完成对 .vue 文件的解析和编译。

编译器宏(compiler macros)

markdown
1. **`defineProps`**
   - 作用:用于声明组件的 props。
   - 示例:
     <script setup>
     const props = defineProps({
       title: String,
       count: Number
     })
     </script>

2. **`defineEmits`**
   - 作用:用于声明组件可以发出的事件。
   - 示例:
     <script setup>
     const emit = defineEmits(['update', 'delete'])

     function updateItem() {
       emit('update')
     }
     </script>

3. **`defineExpose`**
   - 作用:用于显式暴露给父组件的属性或方法。
   - 示例:
     <script setup>
     function someMethod() { /* ... */ }

     defineExpose({
       someMethod
     })
     </script>

4. **`withDefaults`**
   - 作用:为 props 提供默认值。
   - 示例:
     <script setup>
     const props = withDefaults(defineProps({
       message: String
     }), {
       message: 'Hello World'
     })
     </script>

5. **`useSlots`**
   - 作用:用于获取插槽对象。
   - 示例:
     <script setup>
     const slots = useSlots()

     if (slots.default) {
       // 使用默认插槽内容
     }
     </script>

6. **`useAttrs`**
   - 作用:用于获取透传的 attribute。
   - 示例:
     <script setup>
     const attrs = useAttrs()

     // 可以将 attrs 传递给子组件
     </script>

7. **`defineModel`**
	- defineModel编译器宏 3.3版本引入 | 2023年4月8日pull请求
	- 作用:用于声明模型属性,实现双向绑定。
	- 示例:
     <script setup>
     defineModel({
       props: 'modelValue',
       emit: 'update:modelValue'
     })
     </script>

8. **`defineOptions`**
   - 作用:用于在 `<script setup>` 中声明组件选项。
   - 示例:
     <script setup>
     defineOptions({
       name: 'MyComponent'
     })
     </script>

9. **`ref` (setup function specific)**
   - 作用:用于声明响应式引用。
   - 示例:
     <script setup>
     import { ref } from 'vue'

     const count = ref(0)
     </script>

10. **`computed` (setup function specific)**
   - 作用:用于声明计算属性。
   - 示例:
     <script setup>
     import { computed } from 'vue'

     const count = ref(0)
     const doubleCount = computed(() => count.value * 2)
     </script>

类型检查

vue
<script lang="ts">  
import { defineComponent, ref } from 'vue';  

// 接口定义  
interface User {  
  id: number;  
  name: string;  
  email?: string; // 可选属性  
}  

// 字面量类型  
type Status = 'success' | 'error' | 'pending';  

// 组件定义  
export default defineComponent({  
  name: 'ExampleComponent',  

  setup() {  
    // 使用基本类型  
    const count = ref<number>(0);  

    // 使用联合类型  
    const identifier: string | number = "user_123";  

    // 使用泛型  
    function identity<T>(arg: T): T {  
      return arg;  
    }  
    const numberIdentity = identity<number>(123);  

    // 使用交叉类型  
    const user: User & { status: Status } = {  
      id: 1,  
      name: 'John Doe',  
      email: 'john@example.com',  
      status: 'success'  
    };  

    // 类型断言  
    const someElement = document.querySelector('.my-element') as HTMLDivElement;  
    
    // 可选链和空值合并  
    const email = user.email ?? 'No email provided';  

    // 使用类定义和成员可见性  
    class Service {  
      public status: Status = 'pending';  
      private data: string[] = [];  

      public addData(item: string): void {  
        this.data.push(item);  
      }  

      protected getData(): string[] {  
        return this.data;  
      }  
    }  

    const service = new Service();  
    service.addData('Hello');  

    return {  
      count,  
      identifier,  
      user,  
      someElement,  
      email,  
      service,  
      numberIdentity,  
    };  
  },  
});  
</script>  

<template>  
  <div>  
    <p>Count: {{ count }}</p>  
    <p>Identifier: {{ identifier }}</p>  
    <p>User: {{ user.name }} - Status: {{ user.status }}</p>  
    <p>Email: {{ email }}</p>  
    <p>Service Status: {{ service.status }}</p>  
    <p>Number Identity: {{ numberIdentity }}</p>  
  </div>  
</template>
本站总访问量 次 本站访客数 人次

1111111111111111111