1.初始setup的使用方式
<script>
import {ref} from "vue"
import HelloWorld from "./HelloWorld.vue"
export default{
name:"app",
components:{
HelloWorld
},
props:["name"]
setup(props,ctx){
const state=ref("");
state.value=props.name;
const add=()=>{
//分发自定义事件的函数,
ctx.emit("add",50)
}
return {state,add}
}
}
</script>
2.setup语法糖
什么是setup语法糖?
在script标签中添加过setup,组件只需引入不用注册,属性和方法也不用返回,也不用写setup函数,也不用写export default
<template>
<div>{{data}}</div>
<div>{{state.name}}</div>
</template>
//当前组件名称会自动以文件名为主,不用再需要name属性了
<script setup>
//组件自动注册,
import HelloWorld from "./HelloWorld.vue"
import {ref,reactive} from "vue"
const data=ref("");
const state=reactive({name:"张三"})
</script>
问题:没有setup函数,应该怎么获取props,emit,attrs呢
setup 语法糖提供了三个新的API来供我们使用:defineProps、defineEmits和useContext
- defineProps 用来接收父组件传来的值
props
。
//子组件接收
<script setup>
import {defineProps} from 'vue'
const props=defineProps(["name"])
</script>
//父组件传值
<template>
<div>我是父组件</div>
<div :name="state.name"></div>
</template>
<script setup>
import {ref,reactive} from "vue"
const data=ref("");
const state=reactive({name:"张三"})
</script>
- defineEmits 用来声明触发的事件表。
//子组件
<script setup>
import {defineEmits,ref} from 'vue'
const name=ref("张三")
//自定义函数,父组件可以触发
const emit=defineEmits(['update'])
const show=()=>{
emit("update",name.value)
}
</script>
<template>
<div>我是父组件</div>
<div @update="update"></div>
</template>
<script setup>
import {ref,reactive} from "vue"
const update=(data)=>{
console.log(data)//张三
}
</script>
- 获取 slots 和 attrs
<script setup>
import { useSlots, useAttrs } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
</script>
- defineExpose对外暴露属性
<script setup>
的组件默认不会对外部暴露任何内部声明的属性。 如果有部分属性要暴露出去,可以使用 defineExpose
使用场景:通过ref获取子组件的内容,子组件没有向外暴露是获取不到的
//子组件
<script setup>
import {ref} from 'vue'
const name=ref("张三")
const age=ref(12)
defineExpose({
name
})
</script>
//父组件
<template>
<div>我是父组件</div>
<HelloWorld ref="hello"></HelloWorld>
</template>
<script setup>
import HelloWorld from "./HelloWorld.vue"
import {ref,reactive} from "vue"
const hello=ref(null)
OnMounted(()=>{
console.log(hello.name)//张三
console.log(hello.age)//获取不到值
})
</script>
注意: defineProps、defineEmits、defineExpose API 不需要引入可以直接使用
总结:
<script setup>
语法糖的优势
- 更少的样板内容,更简洁的代码。
- 能够使用纯Typescript声明 props 和抛出事件。
- 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。
- 更好的 IDE 类型推断性能 (减少语言服务器从代码中抽离类型的工作)。