Vue3.x的scriptsetup语法糖⽤法详解
由于原来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'
// 简单变量define的基本用法
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('lor');
}
</style>
更新中。。。