setup语法糖

329 阅读1分钟

setup与src

<script setup>不能与src属性一起使用

组件、变量、函数

<template>
  <div>{{ num }}</div>
  <MyComponent></MyComponent>
</template>

<script setup>
  import { ref }
  // `组件`引入就能使用
  import MyComponent from './components/MyComponent.vue'

  // `变量、函数`不需要return就能在html中直接使用
  const num = ref(1)
</script>

最外层await

<script setup>
  const post = await fetch(`/api/post/1`).then((r) => r.json())
</script>

单个文件中导入多个组件

<template>
  <Form.Input>
    <Form.Label>label</Form.Label>
  </Form.Input>
</template>

<script setup>
  // 单个文件中导入多个组件
  import * as Form from './form-components'
</script>

props、emit

基本使用

<script setup>
  // `props,emit`的使用
  const props = defineProps({
    msg: String
  })
  const emit = defineEmits(['change', 'delete'])
  emit('change', 参数一, 参数二,...)
</script>

ts中的props、emit声明

<script setup>
  const props = defineProps<{
    foo: string
    bar?: number
  }>()

  const emit = defineEmits<{
    (e: 'change', id: number): void
    (e: 'update', value: string): void
  }>()
</script>

<script setup>
  interface Props {
    msg?: string
    labels?: string[]
  }

  // 使用 withDefaults 设置props默认值
  const props = withDefaults(defineProps<Props>(), {
    msg: 'hello',
    labels: () => ['one', 'two']
  })
</script>

与普通的script(不加setup)一起使用

普通的<script>在有这些需要的情况下或许会被使用到:

  • 无法在<script setup>声明的选项,例如 inheritAttrs 或通过插件启用的自定义的选项
  • 声明命名导出
  • 运行副作用或者创建只需要执行一次的对象
<script>
 // 普通 <script>, 在模块范围下执行(只执行一次)
 runSideEffectOnce()

 // 声明额外的选项
 export default {
   inheritAttrs: false,
   customOptions: {}
 }
</script>

<script setup>
</script>

自定义指令

<template>
 <h1 v-my-directive>This is a Heading</h1>
</template>

<script setup>
 const vMyDirective = {
   beforeMount: (el) => {
     // do something with the element
   }
 }
</script>

defineExpose

<!-- 子组件 --> 
<script setup>
  import { ref } from 'vue'

  const a = 1
  const b = ref(2)

  // 在父组件中通过子组件的ref实例来访问子组件暴露出的数据和方法
  defineExpose({
    a,
    b
  })
</script>

<!-- 父组件 --> 
<template>
  <child ref="childRef" />
</template>

<script setup>
  import { ref } from 'vue'
  const childRef = ref()
  console.log(childRef.value.a) // 1
  console.log(childRef.value.b) // 2
</script>

useAttrs

<!-- 父组件 --> 
<child a="1" b="2" msg="hello" class="child" style="color:red" />

<!-- 子组件 -->
<script setup>
  import { useAttrs } from 'vue'

  const slots = useSlots()
  // {a: "1", b: "2"}: 父组件传递给子组件的属性(除了props、class以及style外的属性)
  const attrs = useAttrs()
</script>

useSlots

一般是用JSX才会用到

<!-- 父组件 -->
<child>
  <div>默认插槽</div>
  <template #left>
    <div>具名插槽</div>
  </template>
</child>

<!-- 子组件 -->
<script setup>
  import { useSlots } from 'vue'

  const slots = useSlots()

  // 渲染组件
  return () => (
    <div>
      // 默认插槽
      <div>{ slots.default ? slots.default() : '' }</div>
      // 具名插槽
      <div>{ slots.left ? slots.left() : '' }</div>
    </div>
  )
</script>

参考