这是我参与「第四届青训营 」笔记创作活动的第2天
后续会不断完善,欢迎指正
一、问题
Vue3.0中setup需要将声明的变量、函数以及 import 引入的内容通过return向外暴露,才能在<template/>使用
然而,在<script setup>中,我们无需return 声明的变量、函数以及import引入的内容
,这中间的操作由<script setup>这个语法糖来帮我们完成,不再需要写export default{}
二、script setup的使用方式
1、组件注册:
不需要在引入组件后,通过 components:{}注册组件,可直接使用
2、组件通信:
在<script setup>中必须使用 defineProps defineEmits API 来替代 props 和 emits
。这两个API直接可用,不需要import,子组件使用时如下:
defineProps
<script setup>
//import {defineProps} from 'vue' 不需要引入
//语法糖必须使用defineProps替代props`
const props = defineProps({
title: {
type: String
}
});
//script-setup 需要通过props.xx获取父组件传递过来的props
console.log(props.title) //父的值
</script>
and defineEmits
<script setup>
import {ref} from 'vue'
const name = ref('我是子组件')
//1、暴露内部数据
const emits = defineEmits(['childFn']);
const toEmits = () => {
//2、触发父组件中暴露的childFn方法并携带数据
emits('childFn',name)
}
</script>
补:defineEmits子组件向父组件传递值时,对于父组件,使用如下:
<Child @childFn='fatherMethod'/>childFn是子组件中emit的名字,fatherMethod是父组件在自己的组件内定义的 用于接收的方法名
3、<slot/>和attrs:
如果需要在script-setup中使用 slots 和 attrs 需要用useSlots 和 useAttrs替代
需要引入:import { useSlots ,useAttrs } form 'vue'
在<template/>中通过 $slots 和 $attrs 来访问更方便
attrs用来获取父组件中非props(子组件如果在props里面声明了父组件传来的参数a,那么子组件就无法通过attrs来得到a)的传递到子组件的参数/方法, slots可以获取父组件中插槽传递的虚拟dom对象,在SFC模式应该用处不大,在JSX /TSX使用比较多
父组件
<template>
<Child msg="非porps传值子组件用attrs接收">
<!-- 匿名插槽 -->
<span >默认插槽</span>
<!-- 具名插槽 -->
<template #title>
<h1>具名插槽</h1>
</template>
<!-- 作用域插槽 -->
<template #footer="{ scope }">
<footer>作用域插槽——姓名:{{ scope.name }},年龄{{ scope.age }}</footer>
</template>
</Child>
</template>
<script setup>
// 引入子组件
import Child from ``'./child.vue'
</script>
子组件
<template>
<!-- 匿名插槽 -->
<slot />
<!-- 具名插槽 -->
<slot name= "title" />
<!-- 作用域插槽 -->
<slot name="footer":scope="state"/>
<!-- $attrs 用来获取父组件中非props的传递到子组件的参数 -->
<p>{{ attrs.msg == $attrs.msg }}</p>
<!--true 没想到有啥作用... -->
<p>{{ slots == $slots }}</p>
</template>
<script setup>
import { useSlots, useAttrs, reactive, toRef } from 'vue'
const state = reactive({
name: '张三',
age: '18'
})
const slots = useSlots()
console.log(slots.default ()); //获取到默认插槽的虚拟dom对象
console.log(slots.title()); //获取到具名title插槽的虚拟dom对象
// console.log(slots.footer()); //报错 不知道为啥有插槽作用域的无法获取
//useAttrs() 用来获取父组件传递的过来的属性数据的(也就是非 props 的属性值)。
const attrs = useAttrs()
</script>
4、在setup访问路由
setup 里不能访问 this,不能再直接访问 this.$router 或 this.$route。
(getCurrentInstance可以替代this)
推荐:使用useRoute 函数和useRouter函数替代this.$route 和 this.$router
<script setup>
import { useRouter, useRoute } from 'vue-router'
const route = useRoute()
const router = useRouter()
function pushWithQuery(query) {
router.push({
name: 'search',
query: {
...route.query,
},
})
}
<script/>
over
推荐原文