script setup 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖;当同时使用单文件组件与组合式 API 时该语法是默认推荐;

基本特性

  1. 自动暴露顶层绑定:在 script setup 中声明的所有顶级绑定 (变量、函数、import 导入) 都会自动暴露给模板;

    <script setup>
    const message = 'Hello Vue 3!'
    const count = ref(0)
    
    function increment() {
      count.value++
    }
    </script>
    
    <template>
      <p>{{ message }}</p>
      <button @click="increment">Count is: {{ count }}</button>
    </template>
    
  2. 自动组件注册:导入的组件无需显式注册即可直接在模板中使用;

    <script setup>
    import MyComponent from './MyComponent.vue'
    import { Icon } from 'vant'
    </script>
    
    <template>
      <MyComponent />
      <Icon name="success" />
    </template>
    

使用组件

动态组件

  1. 由于组件是通过变量引用而不是基于字符串组件名注册的,在 script setup 中要使用动态组件的时候,应该使用动态的 :is 来绑定;

  2. 示例代码

    <script setup>
    import Foo from './Foo.vue'
    import Bar from './Bar.vue'
    </script>
    
    <template>
      <component :is="Foo" />
      <component :is="someCondition ? Foo : Bar" />
    </template>
    

递归组件

  1. 一个单文件组件可以通过它的文件名被其自己所引用;例如:名为 FooBar.vue 的组件可以在其模板中用 <FooBar/> 引用它自己;

  2. 请注意这种方式相比于导入的组件优先级更低;如果有具名的导入和组件自身推导的名字冲突了,可以为导入的组件添加别名;

    import { FooBar as FooBarChild } from './components'
    

命名空间组件

  1. 可以使用带 . 的组件标签,例如 <Foo.Bar> 来引用嵌套在对象属性中的组件;

  2. 这在需要从单个文件中导入多个组件的时候非常有用:

    <script setup>
    import * as Form from './form-components'
    </script>
    
    <template>
      <Form.Input>
        <Form.Label>label</Form.Label>
      </Form.Input>
    </template>
    

使用自定义指令

  1. 全局注册的自定义指令将正常工作;本地的自定义指令在 script setup 中不需要显式注册,但他们必须遵循 vNameOfDirective 这样的命名规范:

    <script setup>
    const vMyDirective = {
      beforeMount: (el) => {
        // 在元素上做些操作
      }
    }
    </script>
    <template>
      <h1 v-my-directive>This is a Heading</h1>
    </template>
    
  2. 如果指令是从别处导入的,可以通过重命名来使其符合命名规范:

    <script setup>
    import { myDirective as vMyDirective } from './MyDirective.js'
    </script>
    

核心 API

defineProps 和 defineEmits

  1. 为了在声明 propsemits 选项时获得完整的类型推导支持,可以使用 definePropsdefineEmits,它们将自动地在 script setup 中可用:

    <script setup>
    const props = defineProps({
      foo: String
    })
    
    const emit = defineEmits(['change', 'delete'])
    // setup 代码
    </script>
    
  2. defineProps 接收与 props 选项相同的值,defineEmits 接收与 emits 选项相同的值;

defineExpose

  1. 使用 script setup 的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在 script setup 中声明的绑定;

  2. 可以通过 defineExpose 编译器宏来显式指定在script setup 组件中要暴露出去的属性:

    <script setup>
    import { ref } from 'vue'
    
    const a = 1
    const b = ref(2)
    
    defineExpose({
      a,
      b
    })
    </script>
    

defineModel (v3.4)

  1. defineModel()Vue 3.4 中引入的一个新的 Composition API,用于简化组件的双向绑定 (v-model) 实现;它是对 v-model 用法的现代化改进,特别适合在组合式 API 中使用;

  2. defineModel() 返回一个 ref,你可以像普通 ref 一样操作它,但它会自动与父组件的 v-model 绑定;它解决了以前需要手动处理 modelValue propupdate:modelValue 事件的繁琐问题;

基本用法示例

  1. 子组件

    <script setup>
    // 定义一个 model,名称为 'modelValue'(默认名称)
    const model = defineModel()
    
    function updateValue() {
      model.value = 'New Value'
    }
    </script>
    
    <template>
      <div>
        <input v-model="model">
        <button @click="updateValue">Update Value</button>
      </div>
    </template>
    
  2. 父组件

    <script setup>
    import { ref } from 'vue'
    import ChildComponent from './ChildComponent.vue'
    
    const parentValue = ref('Initial Value')
    </script>
    
    <template>
      <ChildComponent v-model="parentValue" />
      <p>Parent value: {{ parentValue }}</p>
    </template>
    

带参数的 v-model

  1. 子组件

    <script setup>
    const firstName = defineModel('firstName')
    const lastName = defineModel('lastName')
    </script>
    
    <template>
      <input v-model="firstName" placeholder="First Name">
      <input v-model="lastName" placeholder="Last Name">
    </template>
    
  2. 父组件

    <script setup>
    import { ref } from 'vue'
    import MultipleModels from './MultipleModels.vue'
    
    const first = ref('John')
    const last = ref('Doe')
    </script>
    
    <template>
      <MultipleModels 
        v-model:firstName="first"
        v-model:lastName="last"
      />
      <p>Full Name: {{ first }} {{ last }}</p>
    </template>
    

带修饰符的 v-model

  1. 子组件

    <script setup>
    const model = defineModel({
      // 默认值
      default: '',
      // 当父组件使用修饰符时,这里会接收到
      set(value) {
        // 如果使用了 .trim 修饰符
        if (model.modifiers.trim) {
          return value.trim()
        }
        return value
      }
    })
    </script>
    
    <template>
      <input v-model="model">
    </template>
    
  2. 父组件

    <script setup>
    import { ref } from 'vue'
    import ModifiersExample from './ModifiersExample.vue'
    
    const text = ref('')
    </script>
    
    <template>
      <ModifiersExample v-model.trim="text" />
      <p>Value: "{{ text }}"</p>
    </template>
    
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

你好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 基本特性
  2. 2. 使用组件
    1. 2.1. 动态组件
    2. 2.2. 递归组件
    3. 2.3. 命名空间组件
  3. 3. 使用自定义指令
  4. 4. 核心 API
    1. 4.1. defineProps 和 defineEmits
    2. 4.2. defineExpose
    3. 4.3. defineModel (v3.4)
      1. 4.3.1. 基本用法示例
      2. 4.3.2. 带参数的 v-model
      3. 4.3.3. 带修饰符的 v-model