阅读 437

vue3.2 <script setup>语法糖以及编译效果

vue3.2已经发了一段时间了,也用了一段时间,特别setup语法用起来特顺手,有种回不去的感觉,下面就分享我这一段时间的感受以及体验的效果,总结学习,共同进步。

下来说下好处:此处偷个懒,直接复制官网的

  • 更少的样板内容,更简洁的代码。

  • 能够使用纯 Typescript 声明 props 和抛出事件。

  • 更好的运行时性能 (其模板会被编译成与其同一作用域的渲染函数,没有任何的中间代理)。

  • 更好的 IDE 类型推断性能 (减少语言服务器从代码中抽离类型的工作)。

我们首先看下setup语法:

1. props

先来看下3.2之前的声明props写法

<script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({   props: {     name: {       type: String,       default: '',     },   },   setup(props, context) {     console.log(props, context);   }, }); </script> 复制代码

3.2 <script setup>语法

defineProps 和 defineEmits 都是只在 <script setup> 中才能使用的编译器宏
他们不需要导入且会随着 <script setup> 处理过程一同被编译掉。
在 <script setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits

<script setup> const props = defineProps({   name: {     type: String,     default: '',   }, }); console.log(props); const testlick = () => {   console.log('test'); }; </script> 复制代码

这样写是不是简洁很多,使用也更加方便了。我们先看下编译后的文件

image.png

里面的代码会被编译成组件 setup() 函数的内容。这意味着与普通的 <script> 只在组件被首次引入的时候执行一次不同,<script setup> 中的代码会在每次组件实例被创建的时候执行

我们看到最后的编译结果和我们之前的Vue3.2之前语法是一样,他会把我们的声明变量,函数,以及 import 引入的内容都会暴露在最顶层,所以任何在 <script setup> 声明的顶层的绑定都能在模板中直接使用。

如果使用eslint报错的话,可以在eslint.js添加

// eslint.js module.exports = {   globals: {     defineEmits: true,     defineProps: true,   } } 复制代码

2. emit

在 <script setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits

我们在使用emit必须声明我们使用的事件名,例如:['change','update:modelValue'],可以多个声明,用都好隔开

我们使用最常用的双向绑定例子,来看下代码以及编译后的代码,看过后你就会更加清晰。

<script setup> import { computed } from 'vue'; const props = defineProps({   modelValue: {     type: String,     default: '',   }, }); const emit = defineEmits(['update:modelValue']); const inputValue = computed({   get: () => props.modelValue,   set: (value) => emit('update:modelValue', value), }); </script> 复制代码

image.png

3. 组件

<script setup> 中的组件可以直接使用引入标签名,不用在使用components声明

<template>   <Test /> </template> <script setup> import Test from './index.vue'; </script> <style lang="scss" scoped> </style> 复制代码

是不是很方便,不用担心组件没有声明报错了,我们来看下编译的代码

image.png

我们来看下createBlock方法,是创建是一个vnode节点,在组件打开的时候把这个vnode添加到父组件中,关闭的时候删除节点,这样就实现了直接可以使用引入的标签名使用组件。有兴趣的可以去研究下源码

image.png image.png

4.  useSlots 和 useAttrs

如果想要获取slots和attrs,可以使用这两个api,这个不是经常使用

<script setup> import { useSlots, useAttrs } from 'vue' const slots = useSlots() const attrs = useAttrs() </script> 复制代码

image.png

5. defineExpose

使用 <script setup> 的组件是默认关闭的,也即通过模板 ref 或者 $parent 链获取到的组件的公开实例,不会暴露任何在 <script setup> 中声明的绑定。

vue2我们可以用$ref.获取设置ref组件的方法以及属性,如果使用script setup是获取不到,我们先打印下数据看下效果.

通过getCurrentInstance()获取实例,首先看下没有使用defineExpose之前的打印效果

image.png

我们打印下ref,看下vue3的打印结果

image.png

看下使用defineExpose后的实例 image.png

ref获取的效果

image.png

可以看到如果没有导出, $ref方式是获取不到的其方法或者属性的。

image.png

6. 和普通的<script>一起使用

我们有时候要用的另外的scritp处理其他的逻辑
例如:

<script> export default {   name: 'Test',   inheritAttrs: false,   customOptions: {},   ... } </script> 复制代码

image.png

我们看到使用Object.assign合并的方式,这种方式优先取<scritpt setup>的方法和属性。

<script> const a = 123; const confirmHandler = ()=> {   console.log(6666) } </script> <script setup> import { ref } from 'vue'; const emit = defineEmits(['change', 'confirm']); const confirmHandler = () => {   emit('confirm', multipleSelection.value); }; const search = ref(''); const changeHandle = () => {   const list = { page: currentPage.value };   if (search.value) list.search = search.value;   emit('change', list); }; defineExpose({   changeHandle,   confirmHandler }) </script> 复制代码

image.png


作者:童心虫鸣
链接:https://juejin.cn/post/7045166035799900174

玩站网免费分享SEO网站优化 技术及文章 伪原创工具 https://www.237it.com/ 


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐