第九章、Vue3中<script setup>语法糖

2023-05-16

摘要:<script setup>语法糖: https://cn.vuejs.org/api/sfc-script-setup.html

一、<script setup>语法糖用法

1.1 基本语法:

要使用这个语法,在script 中添加setup属性即可。

<script setup></script>

里面的代码最终会编译成setup()函数中的内容: 所以每次在组件实例被创建时,都会执行;

1.2 顶层绑定自动暴露给模板

当使用<script setup>时候,任何在其中声明的顶层绑定(包括变量,方法,import导入的东西)都可以在template中直接使用,不在需要return,节省代码。

<template>
  <div id="app">
    {{count}} <button @click="add"></button>
  </div>
</template>


<script setup>
import { ref } from "vue";
const count = ref(0)
const add = count.value ++

</script>

1.3 setup 在components中的使用

1.3.1 组件名自动推断

在<script setup>中,不书写组件名,vue会自动把文件名作为组件名,如果想自定义,可以添加普通的script中name配置。

//Foo.vue
<script setup></script>
 
<script>
export default {
  name: 'FooIndex'
}
</script>
1.3.2 动态组件: import导入的组件会被当成变量名,而非字符串,注意;
<template>
  <div id="setup">
    <component :is="condition ? Foo : Bar" />
  </div>
</template>


<script setup>
import { ref } from "vue";
import Foo from './Foo.vue'
import Bar from './Bar.vue'

const condition = ref(true)

setTimeout(() =>{
  condition.value = false;
},2000)

</script>
1.3.3 递归组件

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

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

import { FooBar as FooBarChild } from './components'
1.3.4 命名空间组件

在单文件中导入过多组件时候,之前需要写很多import,命名空间组件可以简化代码。template中可通过对象点语法使用组件.

index.vue

<template>
  <div id="setup">
    <All.Foo />
    <All.Bar />
  </div>
</template>

<script setup>
import { ref } from "vue";
// import Foo from './components/Foo.vue'
// import Bar from './components/Bar.vue'
import * as All from './components'

</script

在components中index.ts,可导入当前所有的子组件

import Foo from './Foo.vue'
import Bar from './Bar.vue'

export {
   Foo,
   Bar
}

1.4 defineProps 与defineEmits 运行时声明和类型声明写法

1.4.1 运行时声明和类型声明

运行时声明即代码运行后会给出相应的提示,比如子组件在props显式声明title为String类型,编码时传递number类型,Vue会给出相应的提示:类型声明(ts类型检查)即代码过程中,在运行之前,集=结合IDE,ts,就会给出提示,比如标红,下划线等

运行时声明写法

<script setup>
const props = defineProps({
  foo: String
})

const emit = defineEmits(['change', 'delete'])
// setup 代码
</script>

类型声明写法

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

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

1.5 defineExpose:暴露当前组件方法和数据,供父组件调用(结合ref)

//child.vue
<script setup>
import { ref } from 'vue'

const count = ref(0)
const add = () => count.value ++

defineExpose({
  count,add
})
</script>


//index.vue
<Child ref="childRef"/>
const childRef = ref(null)
onMounted(() =>{
  console.log(childRef.value.count)
})

1.6 useSlots和useAttrs: 主要用与获取当前组件的插槽和attrs信息

<script setup>
import { useSlots, useAttrs } from 'vue'

const slots = useSlots()
const attrs = useAttrs()
</script>

1.7 与普通script块一起用,下面这几种情况可以一起用,其他情况,反对混用

  • 声明无法在 <script setup> 中声明的选项,例如 inheritAttrs 或插件的自定义选项。

  • 声明模块的具名导出 (named exports)。

  • 运行只需要在模块作用域执行一次的副作用,或是创建单例对象。

<script>
// 普通 <script>, 在模块作用域下执行 (仅一次)
runSideEffectOnce()

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

<script setup>
// 在 setup() 作用域中执行 (对每个实例皆如此)
</script>

1.8 顶层await: 顶层不在需要写async, 最终会编译成async setup()

<script setup>
import { ref } from "vue";
const ret = await ( await fetch('https://api.uomg.com/api/rand.qinghua?format=json')).json()
if(ret.code === 1) console.log(ret.content)


// const randWords = ref('')
// const generateWords = async () =>{
//   const res = await ( await fetch('https://api.uomg.com/api/rand.qinghua?format=json')).json()
//   if(res.code === 1)  randWords.value = res.content
// }
</script>

注意: async setup必须和Suspense(实验阶段)结合使用,目前不推荐使用

1.9 限制src引入:禁止<script steup>与src导入的.js,ts一起使用。

<template src="./template.html"></template>
<script src="./script.js"></script>
<style src="./style.css"></template>
//禁止这样混用
<script setup></script>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第九章、Vue3中<script setup>语法糖 的相关文章

随机推荐