Vue 3.x 的 script setup 语法糖用法详解

由于原来vue3中的setup Composition API 语法太过于冗长麻烦,官方又出了这么个语法糖,非常的好用了。
这里介绍一些常用的语法:

一、如何开始使用?

1、需要关闭vetur插件,安装Volar插件
2、tsconfig.json / jsconfig.json 文件 ,在compilerOptions里面加上 "strict": true,和 "moduleResolution": "node"
3、直接在script标签加入setup 或者 setup lang="ts"

<script setup>
</script>
或者使用TypeScript
<script setup lang="ts">
</script>

script setup里面的代码会被编译成组件setup()函数的内容。这意味着与普通的 script 只在组件被首次引入的时候执行一次不同,script setup 中的代码会在每次组件实例被创建的时候执行。
当使用 script setup 的时候,任何在script setup声明的顶层的绑定 (包括变量,函数声明,以及 import 引入的组件、方法等内容) 都能在模板中直接使用
import 导入的内容也会以同样的方式暴露。意味着可以在模板表达式中直接使用导入的函数,并不需要通过 methods
script-setup 无法指定当前组件的名字,所以使用的时候以文件名为主

<template>
  <div @click="test">{{ name}}</div>
  <div>{{dateFomat('2022-02-18')}}</div>
  <HomeComponent />
</template>

<script setup>
import { dateFomat} from './utils'
import HomeComponent from './MyComponent.vue'
import { ref , reactive } from 'vue'
// 简单变量
const name= ref('Lilei!')

//复杂变量
const user =reacrive({
  name:"韩梅梅",
  age:18
})
// 函数
const test =() => {
  console.log('hello')
}
</script>

二、prop父组件给子组件传值

在 <script setup> 中必须使用 defineProps API 来声明 props ,它们具备完整的类型推断并且在 <script setup> 中是直接可用的:

父组件中给子组件传值

<template>
  <myson info="子组件prop接收" ></myson>
</template>
<script setup lang="ts">
import myson from './myson.vue'
</script>

子组件获取prop

第一种方式:使用 JavaScript 原生构造函数进行类型规定。

<template>
  <p>{{ info }}</p>
</template>
<script setup lang="ts">
import { defineProps } from 'vue'

// 子组件使用defineProps接收父组件prop参数,类型是大写开头
defineProps({
  info: {
    type: String,
    required: false,
    default: '我是prop传值'
  }
})
<script>

第二种方式:使用 TypeScript 的类型注解。

defineProps 也是可以使用尖括号 <> 来包裹类型定义,紧跟在 API 后面,另外,由于 defineProps 返回的是一个对象(因为 props 本身是一个对象),所以尖括号里面的类型还要用大括号包裹,通过 key: value 的键值对形式表示

defineProps<{ name: string }>();//这里是类型string是小写的,而第一中方式是大写的,注意一下
如果有多个 prop ,就跟写 接口 interface 一样,注意类型都是小写开头

defineProps<{
  name: string;
  phoneNumber: number;
  userInfo: object;
  tags?: string[]; //?号表示这个是可选的
}>();
注意这里的userInfo 类型也可以写一个接口

interface UserInfo {
  id: number;
  age: number;
}

defineProps<{
  name: string;
  userInfo: UserInfo;
}>();

attrs 的接收父组件的传值

attrs 和 props 很相似,也是基于父子通信的数据,如果父组件绑定下来的数据没有被指定为 props ,那么就会被挂到 attrs 这边来。
setup script 中使用 useAttrs 来获取attrs

父组件中

<template>
  <myson msg="hello world" ></myson>
</template>
<script setup lang="ts">
import myson from './myson.vue'
</script>

子组件没有使用prop接收,就会到attr中

// 导入 useAttrs 组件
import { useAttrs } from 'vue'
// 获取 attrs
const attrs = useAttrs()
// attrs是个对象,和 props 一样,需要通过 key 来得到对应的单个 attr
console.log(attrs.msg);

三、子组件使用emits触发父组件的方法

setup script api中使用 defineEmits 来定义emit触发父组件事件,用法如下:

子组件中

<template>
  <button @click="triggerFatherAdd">点击触发父组件add</button>
</template>
<script setup lang="ts">
import { defineEmits } from 'vue'

// 子组件使用defineEmits向父组件抛出事件
const emits = defineEmits(['add', 'update'])//事件数组

// 触发调用子组件时的自定义事件add
const triggerFatherAdd = () => {
  emits('add', '新增数据')//后面是参数
}
</script>

父组件中使用子组件自定义事件@add=“父组件中的事件处理”

<template>
<myson @add="add" ></myson>
</template>

<script setup lang="ts">
import myson from './myson.vue'
const add = (msg:string) => {
  console.log('add', msg)
}
</script>

四、ref获取这个子组件对象

在之前的语法中,通过ref获取子组件的数据都是默认隐式暴露给父组件的,而script setup默认是不暴露子组件数据的,暴露数据需要 defineExpose api的支持
基本用法也很简单,它本身是一个函数,可以接受一个对象参数。
在子组件里,把需要暴露出去的数据通过 key: value 的形式作为入参

子组件中的写法:

<script setup lang="ts">
import { defineExpose } from 'vue'

// 定义一个想提供给父组件拿到的数据
const msg: string = 'Hello World!';

// 显示暴露的数据,才可以在父组件拿到
defineExpose({
  msg
});
</script>

父组件通过绑定ref拿到数据

<template>
 <myson ref="son" ></myson>
</template>
<script setup lang="ts">
import { ref , onMounted } from 'vue'
//1、定义一个变量,变量的名字需要和上面ref的一致
 const son=ref()
//2、通过 .value 获取数据,但是需要页面挂载后才能拿到ref数据,在此之前都是 undefined
 console.log(son.value) //undefined
 onMounted(() => {
  const getsonMsg = son.value.msg
  console.log(getsonMsg) //Hello World!
})
</script>

五、使用 provide 给子孙组件传值和 inject 接收父组件的值

父组件中使用provide

<script setup lang="ts">
  import { provide } from "vue";
  const curUserId = 168 //可以是简单类型,也可以是复杂类型
  provide('curUserId', curUserId)
</script>

子孙组件中获取

<script setup lang="ts">
  import { inject } from "vue";
  const curUserId= inject('curUserId')
</script>

六、style中使用v-bind

直接上代码:

<template>
  <span> 有开始循环了-开端 </span>  
</template>
<script setup>
  import { reactive } from 'vue'
  const state = reactive({
    color: 'red'
  })
</script>
<style scoped>
  span {
    /* 使用v-bind绑定state中的变量 */
    color: v-bind('state.color');
  }  
</style>

 

posted @ 2022-11-07 17:54  探索之路慢慢  阅读(2049)  评论(0编辑  收藏  举报