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> 复制代码
这样写是不是简洁很多,使用也更加方便了。我们先看下编译后的文件
里面的代码会被编译成组件
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> 复制代码
3. 组件
<script setup>
中的组件可以直接使用引入标签名,不用在使用components
声明
<template> <Test /> </template> <script setup> import Test from './index.vue'; </script> <style lang="scss" scoped> </style> 复制代码
是不是很方便,不用担心组件没有声明报错了,我们来看下编译的代码
我们来看下createBlock方法,是创建是一个vnode节点,在组件打开的时候把这个vnode添加到父组件中,关闭的时候删除节点,这样就实现了直接可以使用引入的标签名使用组件。有兴趣的可以去研究下源码
4. useSlots
和 useAttrs
如果想要获取slots和attrs,可以使用这两个api,这个不是经常使用
<script setup> import { useSlots, useAttrs } from 'vue' const slots = useSlots() const attrs = useAttrs() </script> 复制代码
5. defineExpose
使用
<script setup>
的组件是默认关闭的,也即通过模板 ref 或者$parent
链获取到的组件的公开实例,不会暴露任何在<script setup>
中声明的绑定。
vue2我们可以用$ref.
获取设置ref组件的方法以及属性,如果使用script setup
是获取不到,我们先打印下数据看下效果.
通过getCurrentInstance()
获取实例,首先看下没有使用defineExpose
之前的打印效果
我们打印下ref,看下vue3的打印结果
看下使用defineExpose
后的实例
ref获取的效果
可以看到如果没有导出, $ref
方式是获取不到的其方法或者属性的。
6. 和普通的<script>
一起使用
我们有时候要用的另外的scritp处理其他的逻辑
例如:
<script> export default { name: 'Test', inheritAttrs: false, customOptions: {}, ... } </script> 复制代码
我们看到使用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> 复制代码
作者:童心虫鸣
链接:https://juejin.cn/post/7045166035799900174
玩站网免费分享SEO网站优化 技术及文章 伪原创工具 https://www.237it.com/