Vue3 script setup 语法糖
简介
<script setup>语法糖并不是新增的功能模块,它只是简化了以往的组合API(compositionApi)的必须返回(return)的写法,并且有更好的运行时性能。- 在 setup 函数中:
setup选项是一个接收props和context的函数。此外,我们将setup返回的所有内容都暴露给组件的其余部分 (计算属性、方法、生命周期钩子等等) 以及组件的模板;所有 ES 模块导出都被认为是暴露给上下文的值,并包含在setup()返回对象中。相对于之前的写法,使用后,语法也变得更简单。 <script setup>语法糖组合式API的简化- 使用方式:在 script 标签加上 setup 关键字即可
1 <script setup> 2 ...... 3 </script>
注:因为setup语法糖是vue3.2正式确定下来的议案,所以vue3.2的版本是真正适合setup语法糖的版本。
属性和方法无需返回,直接使用
以前使用响应式数据是:
1 <template> 2 {{msg}} 3 </template> 4 5 <script> 6 import { ref } from 'vue' 7 export default { 8 setup () { 9 const msg = ref('hello vue3'); 10 return { 11 msg 12 } 13 } 14 } 15 </script>
现在使用 setup 语法糖,不需要return返回 和 setup函数,只需要全部定义在<script setup>内即可:
<template> {{msg}} </template> <script setup> import { ref } from 'vue' const msg = ref('hello vue3'); </script>
注意:在 setup语法糖 中你应该避免使用 this,因为它不会找到组件实例。setup 的调用发生在 data property、computed property 或 methods 被解析之前,所以它们无法>在 setup 中被获取。
reactive, computed,methods 也一样可以使用
1 <template> 2 <div>{{msg}}</div> 3 <div>{{obj.a}}</div> 4 <div>{{sum}}</div> 5 <div @click="increase"> a+1</div> 6 </template> 7 8 <script setup> 9 import { ref, reactive, computed } from 'vue' 10 11 const msg = ref('hello vue3'); 12 13 const obj = reactive({ //reactive只能是对象或数组 14 a: 1, 15 b: 2 16 }) 17 18 const sum = computed(() => { 19 return obj.a + 3; 20 }); 21 const increase = () => { 22 obj.a += 1 23 } 24 </script>
组件自动注册
在 script setup 中,引入的组件可以直接使用,无需再通过components进行注册,并且无法指定当前组件的名字,它会自动以文件名为主,也就是不用再写name属性了。
1 <template> 2 <Content/> 3 </template> 4 5 <script setup> 6 import Child from '@/components/Content.vue' 7 </script>
组件数据传递(props和emits)
通过defineProps指定当前 props 类型,获得上下文的props对象。
使用defineEmit定义当前组件含有的事件,并通过返回的上下文去执行 emit。
defineProps 用来接收父组件传来的 props ; defineEmits 用来声明触发的事件。
子组件 Child.vue
1 <template> 2 <div @click="toEmits">Child Components</div> 3 </template> 4 5 <script setup> 6 // defineEmits,defineProps无需导入,直接使用 7 const emits = defineEmits(['getChild']); 8 const props = defineProps({ 9 title: { 10 type: String, 11 defaule: 'defaule title' 12 } 13 }); 14 15 const toEmits = () => { 16 emits('getChild', 'child value') // 向父组件传递数据 17 } 18 19 // 获取父组件传递过来的数据 20 console.log(props.title); // parent value 21 </script>
父组件 Home.vue
1 <template> 2 <Child @getChild="getChild" :title="msg" /> 3 </template> 4 5 <script setup> 6 import { ref } from 'vue' 7 import Child from '@/components/Child.vue' 8 const msg = ref('parent value') 9 const getChild = (e) => { 10 // 接收父组件传递过来的数据 11 console.log(e); // child value 12 } 13 </script>
获取 slots 和 attrs
可以通过useContext从上下文中获取 slots 和 attrs。不过提案在正式通过后,废除了这个语法,被拆分成了useAttrs和useSlots。
useAttrs:用来获取 attrs 数据,但是这和 vue2 不同,里面包含了 class、属性、方法。
<template>
<component v-bind='attrs'></component>
</template>
<srcipt setup lang='ts'>
const attrs = useAttrs();
<script>
useSlots: 获取插槽数据。
1 // 旧 2 <script setup> 3 import { useContext } from 'vue' 4 5 const { slots, attrs } = useContext() 6 </script> 7 8 // 新 9 <script setup> 10 import { useAttrs, useSlots } from 'vue' 11 12 const slots = useSlots(); 13 const attrs = useAttrs(); 14 console.log(attrs.dataId); // 查看父组件传来的自定义属性 15 </script>
对外暴露属性(defineExpose)
传统的写法,我们可以在父组件中,通过 ref 实例的方式去访问子组件的内容,但在 script setup 中,该方法就不能用了,setup 相当于是一个闭包,除了内部的 template模板,谁都不能访问内部的数据和方法。
<script setup> 的组件默认不会对外部暴露任何内部声明的属性。
如果有部分属性要暴露出去,可以使用 defineExpose
子组件 Child.vue
1 <template> 2 {{msg}} 3 </template> 4 5 <script setup> 6 import { ref } from 'vue' 7 8 let msg = ref("Child Components"); 9 let num = ref(123); 10 11 // defineExpose无需导入,直接使用 12 defineExpose({ 13 msg, 14 num 15 }); 16 </script>
父组件 Home.vue
1 <template> 2 <Child ref="child" /> 3 </template> 4 5 <script setup> 6 import { ref, onMounted } from 'vue' 7 import Child from '@/components/Child.vue' 8 9 let child = ref(null); 10 11 onMounted(() => { 12 console.log(child.value.msg); // Child Components 13 console.log(child.value.num); // 123 14 }) 15 </script>
参考网站:https://www.cnblogs.com/bingcola/p/15507847.html

浙公网安备 33010602011771号